版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、* 描述 : 该程序实现了用单片机来控制时钟芯片 DS1302 进行万年历的显示。 这个代码相对来说很复杂,注释比较多,大家可以仔细分析。 程序运行,首先设置时间。按 S21 ,进行某一位的设置,会看到某一位上面会闪烁。按 S20 ,数值减 1.按 S22 ,数值加 1. 设置完后,时间会进行运行。 另外 ,1602 上也会有时间显示的。 开发板上有一个 J28 跳线,用跳线帽短接,时间掉电后不会丢失。 因为费电,所以建议 J28 不要一直短接。* 创建人 : 东流, 2018 年 2 月 7 日* 版本号 : 1.0*杜邦线接法:P3.5接J18的1端;J3.6接J18的2端;J3.7接J1
2、8的3端。1602 接到 J17 的排座上。P2.3连接到J31的4端。P1.0 接 J8 的 2 端。P1.1 接 J8 的 3 端。P1.2 接 J8 的 4 端。 */ #include<reg51.h>#include"DS18B20_3.H"#define uint unsigned int#define uchar unsigned charuchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp 。/flag 用于读取头文件中的温度值,和显示温度值#define yh 0x80 /LCD 第一行 的
3、初 始位置 ,因为 LCD1602 字符 地址首 位 D7 恒定 为 1<100000000=80 )#define er 0x80+0x40 /LCD 第二行初始位置 <因为第二行第一个字符位置地址是0x40)液晶屏的与C51之间的引脚连接定义 <显示数据线接 C51的P0 口)sbit rs=P2A4。sbit rw=P2A5。 /如果硬件上rw接地,就不用写这句和后面的rw=0 了sbit en=P2A6。/DS1302 时钟芯片与 C51 之间的引脚连接定义sbit SCLK=P3A5 。sbit IO=P3A6 。sbit RST=P3A7。sbit ACC0=AC
4、CA0 。sbit ACC7=ACCA7 。/*ACC 累加器 =AACC.0=E0HACC.0 就是 ACC 的第 0位。 Acc 可以位寻址。累加器 ACC 是一个 8 位的存储单元,是用来放数据的。但是,这个存储单元有其特殊的地位, 是单片机中一个非常关键的单元,很多运算都要通过ACC 来进行。以后在学习指令时,常用 A 来表示累加器。但有一些地方例外,比如在PUSH 指令中,就必须用 ACC 这样的名字。一般的说法, A 代表了累加器中的内容、而 ACC 代表的是累加器的地址。 */校时按键与 C51 的引脚连接定义sbit key仁P1X。/设置键sbit key2=P1A2。/加键
5、sbit key3=P1A0。/减键 /*/ uchar code tab1="20 - - " 。 /年显示的固定字符 uchar code tab2=" : : " 。 /时间显示的固定字符/延时函数,后面经常调用void delay(uint xms>/ 延时函数,有参函数uint x,y 。for(x=xms 。 x>0 。 x-> for(y=110 。 y>0。 y-> 。/* 液晶写入指令函数与写入数据函数,以后可调用 */*在这个程序中,液晶写入有关函数会在 DS1302的函数中调用,所以液晶程序要放在前面*
6、/void write_1602com(uchar com>/* 液晶写入指令函数 *rs=0。 /数据 /指令选择置为指令rw=0 。 /读写选择置为写P0=com。 /送入数据 delay(1> 。en=1。 /拉高使能端,为制造有效的下降沿做准备 delay(1> 。en=0。 /en 由高变低,产生下降沿,液晶执行命令void write_1602dat(uchar dat>/* 液晶写入数据函数 *rs=1。 /数据 /指令选择置为数据rw=0 。 /读写选择置为写P0=dat。 /送入数据delay(1> 。en=1 。 /en 置高电平,为制造下降沿
7、做准备 delay(1> 。en=0。 /en 由高变低,产生下降沿,液晶执行命令void lcd_init(>/* 液晶初始化函数 *write_1602com(0x38> 。 /设置液晶工作模式,意思: 16*2 行显示, 5*7 点阵, 8 位 数据write_1602com(0x0c> 。 /开显示不显示光标 write_1602com(0x06> 。 /整屏不移动,光标自动右移 write_1602com(0x01> 。 /清显示write_1602com(yh+1> 。 /日历显示固定符号从第一行第 1 个位置之后开始显示 for(a=0
8、。 a<14。 a+>write_1602dat(tab1a> 。 /向液晶屏写日历显示的固定符号部分 /delay(3> 。write_1602com(er+2> 。 /时间显示固定符号写入位置,从第2 个位置后开始显示for(a=0 。 a<8。 a+>write_1602dat(tab2a> 。 /写显示时间固定符号,两个冒号 /delay(3> 。*over*/*DS1302有关子函数 */ void write_byte(uchar dat>/ 写一个字节ACC=dat 。RST=1。for(a=8 。 a>0。 a-
9、>IO=ACC0 。SCLK=0 。SCLK=1 。ACC=ACC>>1 。uchar read_byte(>/ 读一个字节RST=1。for(a=8 。 a>0。 a->ACC7=IO 。SCLK=1 。SCLK=0 。ACC=ACC>>1 。 return (ACC> 。/void write_1302(uchar add,uchar dat>/ 向 1302 芯片写函数,指定写入地址,数据 RST=0。SCLK=0 。RST=1。 write_byte(add> 。 write_byte(dat> 。SCLK=1 。
10、RST=0。uchar read_1302(uchar add>/ 从 1302 读数据函数,指定读取数据来源地址uchar temp。RST=0。SCLK=0 。RST=1。write_byte(add> 。 temp=read_byte(> 。SCLK=1 。RST=0。 return(temp> 。uchar BCD_Decimal(uchar bcd>/BCD 码转十进制函数,输入 BCD ,返回十进制 uchar Decimal 。Decimal=bcd>>4 。 return(Decimal=Decimal*10+(bcd&=0x0
11、F>> 。/void ds1302_init(> /1302 芯片初始化子函数 (2018-01-07,12:00:00,week4>RST=0。SCLK=0 。write_1302(0x8e,0x00> 。 / 允许写,禁止写保护/write_1302(0x80,0x00> 。 /向 DS1302 内写秒寄存器 80H 写入初始秒数据 00 /write_1302(0x82,0x00> 。 /向 DS1302 内写分寄存器 82H 写入初始分数据 00 /write_1302(0x84,0x12> 。 /向 DS1302 内写小时寄存器 84H
12、 写入初始小时数据 12 /write_1302(0x8a,0x04> 。/向 DS1302 内写周寄存器 8aH 写入初始周数据 4 /write_1302(0x86,0x07> 。 /向 DS1302 内写日期寄存器 86H 写入初始日期数据 07 /write_1302(0x88,0x01> 。 /向 DS1302 内写月份寄存器 88H 写入初始月份数据 01 /write_1302(0x8c,0x10> 。 /向 DS1302 内写年份寄存器 8cH 写入初始年份数据 10 write_1302(0x8e,0x80> 。 / 打开写保护/温度显示子函数v
13、oid write_temp(uchar add,uchar dat>/ 向 LCD 写温度数据 ,并指定显示位置uchar gw,sw。gw=dat%10 。 /取得个位数字sw=dat/10 。 /取得十位数字write_1602com(er+add> 。 /er 是头文件规定的值 0x80+0x40 write_1602dat(0x30+sw> 。/数字 +30得到该数字的 LCD1602 显示码 write_1602dat(0x30+gw> 。/数字+30得到该数字的 LCD1602 显示码 write_1602dat(0xdf> 。/ 显示温度的小圆圈符
14、号, 0xdf 是液晶屏字符库的该符号地址码write_1602dat(0x43> 。 /显示 "C" 符号, 0x43 是液晶屏字符库里大写 C 的地址码/时分秒显示子函数void write_sfm(uchar add,uchar dat>/ 向 LCD 写时分秒 ,有显示位置加、现示数据,两个参数uchar gw,sw。gw=dat%10 。 /取得个位数字sw=dat/10 。 /取得十位数字write_1602com(er+add> 。 /er 是头文件规定的值 0x80+0x40 write_1602dat(0x30+sw> 。/数字 +
15、30得到该数字的 LCD1602 显示码 write_1602dat(0x30+gw> 。/数字+30得到该数字的 LCD1602 显示码/年月日显示子函数void write_nyr(uchar add,uchar dat>/ 向 LCD 写年月日,有显示位置加数、显示数据,两个 参数uchar gw,sw。gw=dat%10 。 /取得个位数字sw=dat/10 。 /取得十位数字write_1602com(yh+add> 。 /设定显示位置为第一个位置 +add write_1602dat(0x30+sw> 。/数字 +30得到该数字的 LCD1602 显示码 w
16、rite_1602dat(0x30+gw> 。/数字+30得到该数字的 LCD1602 显示码/void write_week(uchar week>/ 写星期函数write_1602com(yh+0x0c> 。 /星期字符的显示位置switch(week>case 1:write_1602dat('M'> 。 /星期数为 1 write_1602dat('O'> 。 write_1602dat('N'> 。break。case 2:write_1602dat('T'> 。 /星期数
17、据为write_1602dat('U'> 。write_1602dat('E'> 。break。case 3:write_1602dat('W'> 。 /星期数据为 write_1602dat('E'> 。 write_1602dat('D'> 。break。case 4:write_1602dat('T'> 。 /星期数据为write_1602dat('H'> 。write_1602dat('U'> 。break。ca
18、se 5:write_1602dat('F'> 。 /星期数据为 write_1602dat('R'> 。 write_1602dat('I'> 。break。case 6:write_1602dat('S'> 。 /星期数据为write_1602dat('T'> 。write_1602dat('A'> 。break。case 7:write_1602dat('S'> 。 /星期数据为write_1602dat('U'>
19、 。write_1602dat('N'> 。break。时,显示2 时显示3 时显示4 是显示5 时显示6 时显示7 时显示/*键盘扫描有关函数 * void keyscan(>key1 为功能键 < 设置键)if(key1=0>/delay(9>。 /延时,用于消抖动 if(key1=0>/ 延时后再次确认按键按下 while(!key1> 。 key1n+ 。 if(key1n=9>8 个功keyl n=1。/设置按键共有秒、分、时、星期、日、月、年、返回,能循环switch(key1n>case 1: TR0=0。 /
20、关闭定时器/TR1=0 。write_1602com(er+0x09> 。 /设置按键按动一次,秒位置显示光标 write_1602com(0x0f> 。 /设置光标为闪烁 temp=(miao>/10*16+(miao>%10 。 /秒数据写入 DS1302 write_1302(0x8e,0x00> 。write_1302(0x80,0x80|temp> 。 /miaowrite_1302(0x8e,0x80> 。break。case 2: write_1602com(er+6> 。/按 2次 fen 位置显示光标/write_1602com
21、(0x0f> 。break。case 3: write_1602com(er+3> 。/按动 3次, shi/write_1602com(0x0f> 。break。case 4: write_1602com(yh+0x0e> 。/按动 4次, week/write_1602com(0x0f> 。break。case 5: write_1602com(yh+0x0a> 。/按动 5次, ri/write_1602com(0x0f> 。break。case 6: write_1602com(yh+0x07> 。/按动 6次, yue/write_16
22、02com(0x0f> 。break。case 7: write_1602com(yh+0x04> 。/按动 7次, nian/write_1602com(0x0f> 。break。case 8:write_1602com(0x0c> 。 /按动到第 8 次,设置光标不闪烁TR0=1。/打开定时器temp=(miao>/10*16+(miao>%10 。write_1302(0x8e,0x00> 。write_1302(0x80,0x00|temp> 。 /miao 数据写入 DS1302 write_1302(0x8e,0x80> 。br
23、eak 。/ 加键 key2if(key1n!=0>/ 当 key1 按下以下。再按以下键才有效<按键次数不等于零)if(key2=0> / 上调键 delay(10> 。 if(key2=0> while(!key2> 。 switch(key1n>case 1:miao+。 /设置键按动 1 次,调秒 if(miao=60>miao=0 。/秒超过 59,再加 1,就归零 write_sfm(0x08,miao> 。 /令 LCD 在正确位置显示 "加 "设定好的秒数 temp=(miao>/10*16+(mi
24、ao>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 / 允许写,禁止写保护 write_1302(0x80,temp> 。 /向 DS1302 内写秒寄存器 80H 写入调整 后的秒数据 BCD 码write_1302(0x8e,0x80> 。 / 打开写保护 write_1602com(er+0x09> 。 /因为设置液晶的模式是写入数据后,光 标自动右移,所以要指定返回/write_1602com(0x0b> 。 break。case 2:fen+。 if(fen=60>fen=0。 w
25、rite_sfm(0x05,fen> 。/令 LCD 在正确位置显示 " 加" 设定好的分数 据temp=(fen>/10*16+(fen>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x82,temp> 。/向 DS1302 内写分寄存器 82H 写入调整后 的分数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(er+6> 。 /因为设置液晶的模式是写入数据后,指针 自
26、动加一,在这里是写回原来的位置break。case 3:shi+。if(shi=24>shi=0 。 write_sfm(2,shi> 。/令 LCD 在正确的位置显示 "加" 设定好的小时数 据temp=(shi>/10*16+(shi>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x84,temp> 。 /向 DS1302 内写小时寄存器 84H 写入调整后的小时数据 BCD 码write_1302(0x8e,0x80>
27、。 /打开写保护 write_1602com(er+3> 。 /因为设置液晶的模式是写入数据后,指针 自动加一,所以需要光标回位break。case 4:week+。if(week=8> week=1 。write_1602com(yh+0x0C> 。/指定 '加 '后的周数据显示位置 write_week(week> 。/ 指定周数据显示内容 temp=(week>/10*16+(week>%10 。 / 十进制转换成 DS1302 要求的 DCB 码 write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_
28、1302(0x8a,temp> 。 /向 DS1302 内写周寄存器 8aH 写入调整后 的周数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(yh+0x0e> 。 /因为设置液晶的模式是写入数据后, 指针自动加一,所以需要光标回位break。case 5:ri+。if(ri=32> ri=1。write_nyr(9,ri> 。/令 LCD 在正确的位置显示 " 加"设定好的日期数据 temp=(ri>/10*16+(ri>%10。/十进制转换成 DS1302 要求的 DCB
29、码 write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x86,temp>。 /向DS1302内写日期寄存器 86H写入调整 后的日期数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护write_1602com(yh+10> 。 /因为设置液晶的模式是写入数据后,指 针自动加一,所以需要光标回位break。case 6:yue+。if(yue=13> yue=1 。write_nyr(6,yue> 。 /令 LCD 在正确的位置显示 "加"设定好的月份数 据temp=(y
30、ue>/10*16+(yue>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x88,temp> 。 /向 DS1302 内写月份寄存器 88H 写入调整 后的月份数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护write_1602com(yh+7> 。 /因为设置液晶的模式是写入数据后,指针 自动加一,所以需要光标回位break。case 7:nian+ 。if(nian=100> nian=0。 write_nyr(
31、3,nian> 。 /令 LCD 在正确的位置显示 "加 "设定好的年份数 据temp=(nian>/10*16+(nian>%10 。 /十进制转换成 DS1302 要求的 DCB 码 write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x8c,temp> 。 /向 DS1302 内写年份寄存器 8cH 写入调整 后的年份数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(yh+4> 。 /因为设置液晶的模式是写入数据后,指针 自动加一
32、,所以需要光标回位break。/ 减键 key3 ,各句功能参照 '加键'注释 if(key3=0>delay(10> 。/调延时,消抖动 if(key3=0> while(!key3> 。 switch(key1n> case 1:miao-。 if(miao=-1>miao=59。/秒数据减到-1时自动变成59 write_sfm(0x08,miao> 。 /在 LCD 的正确位置显示改变后新的秒数 temp=(miao>/10*16+(miao>%10 。 /十进制转换成 DS1 302要求的 DCB 码 write_
33、1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x80,temp> 。/向 DS1302 内写秒寄存器 80H 写入调整后的秒数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(er+0x09> 。 /因为设置液晶的模式是写入数据后,指 针自动加一,在这里是写回原来的位置/write_1602com(0x0b> 。 break。case 2:fen-。 if(fen=-1>fen=59。write_sfm(5,fen> 。 temp=(fen>/10*16+(
34、fen>%10 。 /十进制转换成 DS1302 要求的 DCBwrite_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x82,temp> 。/向 DS1302 内写分寄存器 82H 写入调整后 的分数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(er+6> 。 /因为设置液晶的模式是写入数据后,指针 自动加一,在这里是写回原来的位置break。case 3:shi-。if(shi=-1>shi=23。write_sfm(2,shi> 。 temp=(shi
35、>/10*16+(shi>%10 。 /十进制转换成DS1302 要求的 DCB码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x84,temp> 。 /向 DS1302 内写小时寄存器 84H 写入调整 后的小时数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(er+3> 。 /因为设置液晶的模式是写入数据后,指针 自动加一,所以需要光标回位break。case 4:week-。if(week=0>week=7 。write_1602com(yh+
36、0x0C> 。/指定 '加 '后的周数据显示位置 write_week(week> 。/ 指定周数据显示内容 temp=(week>/10*16+(week>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x8a,temp> 。 /向 DS1302 内写周寄存器 8aH 写入调整后 的周数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(yh+0x0e> 。 /因为设置液晶
37、的模式是写入数据后, 指针自动加一,所以需要光标回位break。case 5:ri- 。if(ri=0>ri=31 。write_nyr(9,ri> 。temp=(ri>/10*16+(ri>%10。/十进制转换成 DS1302 要求的 DCB 码 write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x86,temp>。 /向DS1302内写日期寄存器 86H写入调整 后的日期数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护write_1602com(yh+10> 。 /因为设
38、置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break。 case 6:yue-。if(yue=0> yue=12。 write_nyr(6,yue> 。 temp=(yue>/10*16+(yue>%10 。 /十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x88,temp> 。 /向 DS1302 内写月份寄存器 88H 写入调整 后的月份数据 BCD 码write_1302(0x8e,0x80> 。 /打开写保护 write_1602com(yh+7> 。 /因为设置液晶的模式是写入数据后,指针 自动加一,所以需要光标回位break。case 7:nian-。if(nian=-1> nian=99。 write_nyr(3,nian> 。temp=(nian>/10*16+(nian>%10 。/ 十进制转换成 DS1302 要求的 DCB 码 write_1302(0x8e,0x00> 。 /允许写,禁止写保护 write_1302(0x8c,temp> 。 /向 DS1302 内写年份寄存器 8cH 写入调整 后的年份数据
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中专老师新学期工作计划
- 学生工作计划合集六篇
- 专科毕业实习报告15篇
- 江苏省南京师范大学附属中学树人学校2024-2025学年上学期12月月考九年级数学测试卷(含部分答案)
- 高二语文上学期期末考点大串讲(统编版选择性必修上册+中册)专题03 文言文阅读(知识清单)
- 典型固体废物资源化技术
- 《IABP使用常见问题》课件
- 2024届河南省息县高三下学期三校联考高考一模地理试卷
- 供热企业安全培训
- 《自动控制原理及其应用》全套教学课件
- 导游工作中的常见案例分析
- 2023年鳌江镇活动策划项目招标文件
- 大学体验英语综合教程课后答案Unit1-2
- 安全与合规管理
- 山东省潍坊市2022-2023学年七年级上学期期末数学试题(含答案)
- 油烟净化器安全操作规程范本
- 护理门诊开科方案课件
- 苏教版六年级上数学全册教学反思(全册)
- 占用人行道开挖施工方案
- 食品召回记录表
- 农村小学基于国家中小学智慧教育平台下的双师课堂研究
评论
0/150
提交评论