. 设计要求 以AT89C51单片机为核心,制作一个LCD显示的智能电子钟 求程序

. 设计要求 以AT89C51单片机为核心,制作一个LCD显示的智能电子钟 求程序,第1张

[5]单片机多功能万年历电子表系统 节日提醒温湿度显示

功能描述:

1、 按键调时间, 设置闹钟

2、 带备用电池(断电继续走时)

3、 阳历、 农历节日提醒; 可显示上午、 中午、 晚上、 午夜、 深夜等时间段

4、 温湿度实时显示(可替换其他传感器数据显示)

5、 功能扩展: 语音播报万年历、 温湿度等。(此项功能为扩展功能)

☆已作出的实物优酷视频演示地址:

http://v.youku.com/v_show/id_XMTU0MjI4OTExNg==.html

[1]GPS 自动授时系统 语音报时/播报温湿度

实现功能:

1.可设置授时模式为自动授时和手动更新

2.可脱离 GPS 数据利用本地时钟芯片准确走时

3.可设置静音模式、 整点报时和自动语音播报温湿度及其混合模式等四种语音工作模式

4.可以切换显示本地时间和温湿度数据和 GPS 卫星时间数据和定位数据

5.经过分析 GPS 数据, 利用算法缩短了解析时间在秒级时间内就能获取到 GPS 时间数据(正常情况下, 完成定位需要几分钟以上)

6.(亮点) 利用算法自动计算星期参数和农历参数, 程序内部算法输入任何阳历日期数据即可得到准确的

星期数据和农历数据

7.利用 12864 串口工作模式, 节省了 8 个 IO

8.可进行功能定制

☆已作出的实物优酷视频演示地址:

http://v.youku.com/v_show/id_XMjY4OTkyNjk4NA==.html

步骤如下:

lcd电子钟如何调时间

1、修改时间和日期

按下设置移动按钮,钟面年份开始闪烁,再按设置移动按钮,月份开始闪烁;再按设置移动按钮,日期开始闪烁;再按设置移动按钮,小时开始闪烁,按下修改按钮,可向上增加时间;再按设置移动按钮,分钟数字开始闪烁,按下修改按钮,可向上增加分钟。

2、完成调整后,按下退出按钮,就进入正常显示

各种电子钟设置方法基本相似,有五个按钮的,修改有上调、下调两个按钮。万年历显示信息分上下两部分,屏幕上半部分固定显示时间,下半部分轮流显示日期、星期、温度、农历日期以及24节气。信息轮流显示的时间间隔固定为5秒,不可调整。万年历配备两组闹钟。系统有备用电池,在断电的情况下依然可以保证正确计时,保持时间视电池电量而定,通常短时间断电不会出现时间丢失的情况。

3、电子钟日历调整

如果是万年历那种,侧面有四个按键,从上到下叫ABCD,先按住A一会儿,表盘年月日星期等开始闪动。哪个闪动,按B就是往上加数字,按C就是往下减,以此类推都可以调整了,调整完不动它,过一会恢复正常走时了!

4、电子钟时间调整

先按一下“调整”按钮,数字开始闪动。想调哪一个数就多按几次,按到的这个数就会闪动。再用“上调”、或者“下调”来调整。在正常的显示下,按一下“闹钟”按钮,会在“开”和“关”之间转换。按一下“喇叭”按钮,会在“开”和“关”的功能切换。最后按复位。

5、先按一下“设置”键

进入时间设置状态,同时年份“闪烁”,可按“上调”或“流水(下调)”键修改年份,修改好后按“设置”键将闪烁位移到公历“月”,按“上调”或“流水(下调)”键修改月份;用同样的方法可对日、时、分、秒进行设置;星期、农历月、日将自动跟随公历的变化而变化。

6、再按“设置”或“退出”

退出时间设置,回到正常时间状态。

7、查看说明书

众所周知,说明书是每个物品必有的一个最全面的教科书,如果还有不理解的可以参考说明书上的内容。

#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit dq=P3^7 //////18b20

sbit lcden=P2^7////lcd

sbit rs=P2^6

sbit wr=P2^5

sbit sck=P3^6 ////1302

sbit sda=P3^4

sbit rst=P3^5

sbit a=P1^0

sbit b=P1^1

sbit c=P1^2

sbit d=P1^3

sbit kj=P1^4

sbit beep=P1^5

uchar ritime

uchar startflag

uchar ridate[33]

uchar bitnum

uchar rireceok

uchar ricode[4]

uchar riprosok

uchar dis[8]

void dis_key(void)

void riwork(void)

void ripros(void)

void keyscan(void)

void bep(void)

void timer0init(void)

void init0init(void)

uchar key0,key1,key2,key0num,passwordok

uchar key,p,m,pnum,sha

uchar password[9]

uchar password1[9]={6,7,4,6,8,8,6,4,6}

void password_scan()

void post_key()

void dj1()

void dj2()

//////////////////////函数声明1302

void wr1302_byte(uchar byte)

void wr1302 (uchar add,uchar dat)

uchar read1302(uchar add)

uchar time_date[7]={10,3,12,8,21,37,20}////年周月日时分秒

uchar time_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80}////写入地址

uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}////读出地址

uchar disp[13] ////将读出时间装入

void set_rtc()

void read_rtc()

void timepost() ////处理时间为10进制

void display()

void password_display()

void timeplay()

void runnian1()///闰年

void runnian2() ///闰年减

void keypost() //按键处理

///////////////////////////// 函数声明 lcd ////////////////////

uchar code lcd_tab[]="0123456789- ():c"

uchar code lcd_tab1[]="Plese Password:"

uchar code table1[]="key=00-00-00-00"

uchar code table[]=" QQ:674688646"

uchar code numtab[]="0123456789ABCDEF"

uchar code numtab1[]=" 1234567890"

void delay(uint z)

void init_lcd()

void write_com(uchar com)

void write_date(uchar x)

///////////////////////////18b20////////////

void init18b20(void)

void wr1820_byte(uchar dat)

uchar read18b20_byte(void)

uchar read1820(void)

void delay1(uint t)

//////////////////////////////////////////

void timer0init(void) //开定时器2

{

TMOD=0X02

TH0=0X00

TL0=0X00

ET0=1

EA=1

TR0=1

}

void init0init(void) //外部中断

{

IT0=1

EX0=1

EA=1

}

void riwork(void)

{

dis[0]=ricode[0]/16

dis[1]=ricode[0]%16

dis[2]=ricode[1]/16

dis[3]=ricode[1]%16

dis[4]=ricode[2]/16

dis[5]=ricode[2]%16

dis[6]=ricode[3]/16

dis[7]=ricode[3]%16

}

void ripros(void)

{ uchar j,k,i,value

k=1

for(j=0j<4j++)

{

for(i=0i<8i++)

{

value=value>>1

if(ridate[k]>6)

{

value=value|0x80

}

k++

}

ricode[j]=value

}

riprosok=1

}

void timer0 () interrupt 1

{

ritime++

}

void int0() interrupt 0

{

if(startflag==1)

{

if(ritime>32)//检测引导码

{

bitnum=0

}

ridate[bitnum]=ritime

ritime=0

bitnum++

if(bitnum==33)

{

bitnum=0

rireceok=1

}

}

else

{

startflag=1

ritime=0

}

}

void keyscan(void)

{ if(rireceok==1)

{bep() //按键发声 但影响蜂鸣器 *** 作

ripros()

rireceok=0

}

if(riprosok==1)

{ riwork()

riprosok=0

switch(ricode[2])

{ case 0x46:p=1pnum++break

case 0x0c:key=1break

case 0x18:key=2break

case 0x5e:key=3break

case 0x08:key=4break

case 0x1c:key=5break

case 0x5a:key=6break

case 0x42:key=7break

case 0x52:key=8break

case 0x4a:key=9break

case 0x16:key=10break

case 0x09:key0=1key0num++break

case 0x15:key1=1break

case 0x07:sha=1key2=1break

if(key0==1){if(key0num==1)read_rtc()}

}

}

////按下设定键后读一次1302保证time_date内数据正常

}

void bep(void)

{

beep=0delay(100)beep=1

}

///////////////////////////////////////////////////////////

void write_com(uchar com) /////写命令

{

rs=0

P0=com

lcden=1

delay(5)

lcden=0

}

void write_date(uchar x)/////写数据

{

rs=1

P0=x

delay(5)

lcden=1

delay(5)

lcden=0

}

void init_lcd()// ///lcd初始化

{

wr=0

lcden=0

write_com(0x38)

write_com(0x0c)

write_com(0x06)

write_com(0x01)

}

void display()

{timepost()

write_com(0x80+2)

write_date(lcd_tab[2])

write_date(lcd_tab[0])

write_date(lcd_tab[disp[0]])

write_date(lcd_tab[disp[1]])

write_date(lcd_tab[10])

write_date(lcd_tab[disp[3]])

write_date(lcd_tab[disp[4]])

write_date(lcd_tab[10])

write_date(lcd_tab[disp[5]])

write_date(lcd_tab[disp[6]])

write_date(lcd_tab[11])

write_date(lcd_tab[12])

write_date(lcd_tab[disp[2]])

write_date(lcd_tab[13])

write_com(0x80+0x40+4)/////////第二行

write_date(lcd_tab[disp[7]])

write_date(lcd_tab[disp[8]])

write_date(lcd_tab[14])

write_date(lcd_tab[disp[9]])

write_date(lcd_tab[disp[10]])

write_date(lcd_tab[14])

write_date(lcd_tab[disp[11]])

write_date(lcd_tab[disp[12]])

write_date(lcd_tab[11])

write_date(lcd_tab[read1820()/10])/////显示温度

write_date(lcd_tab[read1820()%10])

write_date(lcd_tab[15])

}

//////////////// 1302 //////////////////////////////

void wr1302_byte(uchar byte) /////写入一个字节

{ uchar i

for(i=0i<8i++)

{ sck=0

sda=byte&0x01

byte>>=1

sck=1

}

}

void wr1302 (uchar add,uchar dat)/////写进1302 时间和地址

{ rst=0

_nop_()

sck=0

_nop_()

rst=1

_nop_()

wr1302_byte(add)

wr1302_byte(dat)

rst=0

//_nop_()

//sda=1

//sck=1

}

uchar read1302(uchar add)

{ uchar i,temp

rst=0

_nop_()

sck=0

_nop_()

rst=1

_nop_()

wr1302_byte(add)////////////////////写入要读的地址

for(i=0i<8i++)

{

if(sda)temp=temp|0x80

sck=0

temp>>=1

_nop_()

sck=1

}

rst=0 //////// 延时很重要

_nop_()

sck=0

_nop_()

sck=1

_nop_()

sda=0

_nop_()

sda=1

_nop_()

return temp

}

void set_rtc()

{

uchar i,j

for(i=0i<7i++)

{

j=time_date[i]/10 ///////将10进制变成16进制

time_date[i]=time_date[i]%10

time_date[i]=time_date[i]+j*16

}

wr1302(0x8e,0x00)//////去除写保护

for(i=0i<7i++)

{

wr1302(time_add[i],time_date[i])

}

wr1302(0x8e,0x80)//////加写保护

}

void read_rtc()

{uchar i,j

for(i=0i<7i++)

{

time_date[i]=read1302(read_add[i])

////将读到的bcd码转化成10进制码

j=time_date[i]&0x0f

time_date[i]>>=4

time_date[i]&=0x0f

time_date[i]*=10

time_date[i]=time_date[i]+j

}

}

void timepost()

{ disp[0]=time_date[0]/10/////年

disp[1]=time_date[0]%10

disp[2]=time_date[1]%10/////周

disp[3]=time_date[2]/10/////月

disp[4]=time_date[2]%10/////

disp[5]=time_date[3]/10/////日

disp[6]=time_date[3]%10////

disp[7]=time_date[4]/10////时

disp[8]=time_date[4]%10////

disp[9]=time_date[5]/10////分

disp[10]=time_date[5]%10////

disp[11]=time_date[6]/10////秒

disp[12]=time_date[6]%10////

}

void delay(uint z)

{

uint x,y

for(x=0x<20x++)

for(y=zy>0y--)

}

/////////////////////////18b20////////

void delay1(uint t)

{

while (t--)

}

void init18b20(void)

{

uchar n

dq=1

delay1(8)

dq=0

delay1(80)

dq=1

delay1(8)

n=dq

delay1(4)

}

void wr18b20_byte(uchar dat)

{

uchar i

for(i=0i<8i++)

{

dq=0

dq=dat&0x01

delay1(4)

dq=1

dat>>=1

}

delay1(4)

}

uchar read18b20_byte(void)

{

uchar i,value

for(i=0i<8i++)

{ dq=0

value>>=1

dq=1

if(dq)

value|=0x80

delay1(4)

}

return value

}

uchar read1820(void)

{ uchar a,b

init18b20()

wr18b20_byte(0xcc)

wr18b20_byte(0x44)

delay1(50)

init18b20()

wr18b20_byte(0xcc)

wr18b20_byte(0xbe)

a=read18b20_byte()

b=read18b20_byte()

b<<=4

b+=(a&0xf0)>>4

return b

}

///////////////////////////////////////////////////////

void keypost()

{ uchar n

if(key0==1)

{

if(key0num==1)

{write_com(0x80+0x40+10)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[6]++

if(time_date[6]==60)time_date[6]=0

display()

}

if(key2==1)

{

key2=0n=1

time_date[6]--

if(time_date[6]==-1)time_date[6]=59

display()

}

}

if(key0num==2)

{write_com(0x80+0x40+8)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[5]++

if(time_date[5]==60)time_date[5]=0

display()

}

if(key2==1)

{

key2=0n=1

time_date[5]--

if(time_date[5]==-1)time_date[5]=59

display()

}

}

if(key0num==3)

{write_com(0x80+0x40+5)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[4]++

if(time_date[4]==24)time_date[4]=0

display()

}

if(key2==1)

{

key2=0n=1

time_date[4]--

if(time_date[4]==-1)time_date[4]=23

display()

}

}

if(key0num==4)

{write_com(0x80+14)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[1]++

if(time_date[1]==8)time_date[1]=1

display()

}

if(key2==1)

{

key2=0n=1

time_date[1]--

if(time_date[1]==0)time_date[1]=7

display()

}

}

if(key0num==5)

{write_com(0x80+10)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[3]++

runnian1()

display()

}

if(key2==1)

{

key2=0n=1

time_date[3]--

if(time_date[3]<1)time_date[3]=31

runnian2()

display()

}

}

if(key0num==6)

{write_com(0x80+7)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[2]++

if(time_date[2]>12)time_date[2]=1

runnian2()

display()

}

if(key2==1)

{

key2=0n=1

time_date[2]--

if(time_date[2]==0)time_date[2]=12

runnian2()

display()

}

}

if(key0num==7)

{write_com(0x80+4)

write_com(0x0f)delay(1000)

if(key1==1)

{ key1=0n=1

time_date[0]++

if(time_date[0]==100)time_date[0]=0

runnian2()

display()

}

if(key2==1)

{

key2=0n=1

time_date[0]--

if(time_date[0]==-1)time_date[0]=99

runnian2()

display()

}

}

if(key0num==8)

{ key0num=0key0=0

write_com(0x0c)

if(n){n=0set_rtc()}

}

}

else

{

read_rtc()

timepost()

display()

if(time_date[5]==0)///整点报时

{if(time_date[6]==0)beep=0

else beep=1

}

}

}

void runnian1()////闰年加

{

if(time_date[2]==2) /////判断2月

{ if((time_date[0]+4)%4==0)

{ if(time_date[3]>29)time_date[3]=1}//判断闰年

else

{if(time_date[3]>28)time_date[3]=1}

}

else

{ if(time_date[2]<8)///判断月小于8

{

if((time_date[2]+1)%2==0)

{if(time_date[3]>31)time_date[3]=1}

else

{if(time_date[3]>30)time_date[3]=1}

}

if(time_date[2]>7)

{

if((time_date[2])%2==0)

{if(time_date[3]>31)time_date[3]=1}

else

{if(time_date[3]>30)time_date[3]=1}

}

}

}

void runnian2()//闰年减

{

if(time_date[2]==2) /////判断2月

{ if((time_date[0]+4)%4==0)

{ if(time_date[3]>29)time_date[3]=29}//判断闰年

else

{if(time_date[3]>28)time_date[3]=28}

}

else

{

if(time_date[2]<8)///判断月小于8

{

if((time_date[2]+1)%2==0)

{if(time_date[3]>31)time_date[3]=31}

else

{if(time_date[3]>30)time_date[3]=30}

}

if(time_date[2]>7)

{

if((time_date[2])%2==0)

{if(time_date[3]>31)time_date[3]=31}

else

{if(time_date[3]>30)time_date[3]=30}

}

}

}

void password_scan() ////////输入密码界面

{uchar l,i,j

write_com(0x80)

for(l=0l<15l++)

{write_date(lcd_tab1[l])}

write_com(0x80+0x40+4+i)

write_com(0x0f)delay(1000)

if(key!=0)

{

password[i]=key

write_com(0x80+0x40+4+i)

write_date(numtab1[key])

write_com(0x14)

i++key=0

}

if(i>0)

{if(sha==1)

{sha=0i--

write_com(0x80+0x40+4+i)

write_date(numtab1[0])

write_com(0x10)

}

}

if(i==9)

{ i=0

for(j=0j<9j++)

{

if(password1[j]==password[j])m++

else {init_lcd()m=0break}

}

if(m==9)

{

m=0passwordok=1

p=0pnum=0key=0

init_lcd()

for(i=0i<15i++)

{write_date(table[i])}

write_com(0x80+0x40)

for(i=0i<15i++)

{write_date(table1[i])}

}

}

}

void dis_key(void) //显示键值

{

write_com(0x80+0x40+4)

write_date(numtab[dis[0]])

write_date(numtab[dis[1]])

write_com(0x80+0x40+7)

write_date(numtab[dis[2]])

write_date(numtab[dis[3]])

write_com(0x80+0x40+10)

write_date(numtab[dis[4]])

write_date(numtab[dis[5]])

write_com(0x80+0x40+13)

write_date(numtab[dis[6]])

write_date(numtab[dis[7]])

}

void timeplay()

{

if(p==1)

{ uchar vkey0num=0key0=0

if(v==0){v=1init_lcd()key=0}

if(pnum==1)

{

password_scan()

}

if(pnum==2)

{ p=0pnum=0m=0v=0

init_lcd()

}

}

else keypost()

}

//////////////////////////主函数////////////////////////

void main()

{

init_lcd() /////初始化lcd

timer0init()///// 开定时器中断

init0init()///// 开外部器中断

key=0

while(1)

{

keyscan()

if(passwordok)

{ dis_key()

post_key()

if(p==1)

{ if(pnum==1)

{if(ricode[2]!=0x46)pnum=0}

if(pnum==2)

{pnum=0m=0

passwordok=0p=0

break

}

}

}

else timeplay()

}

}

void post_key()

{

if(key==1){key=0kj=0}

if(key==2){key=0kj=1}

if(key==3){key=0dj1()}

if(key==4){key=0dj2()}

}

void dj1()

{

uint i

for(i=0i<512i++)

{if(rireceok==1)break

a=0b=0delay(20)

a=1b=0delay(20)

b=0c=0delay(20)

b=1c=0delay(20)

c=0d=0delay(20)

c=1d=0delay(20)

d=0a=0delay(20)

d=1delay(20)

}

}

void dj2()

{ uint i

for(i=0i<512i++)

{if(rireceok==1)break

d=0a=0delay(20)

a=1d=0delay(20)

c=0d=0delay(20)

c=0d=1delay(20)

b=0c=0delay(20)

c=1b=0delay(20)

a=0b=0delay(20)

a=0b=1delay(20)

}

}

使用方法 本程序用于HC6800 V2.6 实验箱,需要装上1602液晶屏,18b20 温度传感器,红外接收头,和步进电机,同时保证遥控器好用(要用配套的小遥控器并且要按键值和我的一样才能准确的 *** 作本程序)

我的遥控器按键值如下

ch-0x45 ch 0x46 ch+0x47

<<0x44 >>0x40 >= 0x43

- 0x07 + 0x15 EQ 0x09

0 0x16 100+ 0x19200+ 0x0d

1 0x0c 2 0x18 3 0x5e

4 0x08 5 0x1c 6 0x5a

7 0x42 8 0x52 9 0x4a

主要 *** 作键为 ch EQ + - 123456789 等键,

程序下进去后 1602会显示日期 时间 温度

用EQ键可对日期 时间进行设定

用+ - 键对日期时间进行调节

调节日期时会自动识别大小月,及闰年并对日期进行相应调整

按下ch键后 会进入输入密码界面 依次输入674688646 会进入按键读值界面 ,输入错误可用 - 键退回

在按键读值界面 连续按两次ch 键后,程序 会退出到时间显示界面

在按键读值界面 按1 打开继电器 按2 关闭继电器 按3 步进电机正转一周,按 4 步进电机反转一周 ,步进电机转的过程中按其他键,步进电机停止


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7960234.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存