郑州市惠济区城乡建设局网站,友点cms,我要建网站,做网站的广告词在写代码前#xff0c;记得把上一节的跳线帽给插回去#xff0c;不然LCD无法显示
一.DS1302时钟
1.编写DS1302.c文件
#xff08;1#xff09;重新对端口定义名字
sbit DS1302_SCLKP3^6;
sbit DS1302_IOP3^4;
sbit DS1302_CEP3^5;#xff08;2#xff09;初始化
因为…在写代码前记得把上一节的跳线帽给插回去不然LCD无法显示
一.DS1302时钟
1.编写DS1302.c文件
1重新对端口定义名字
sbit DS1302_SCLKP3^6;
sbit DS1302_IOP3^4;
sbit DS1302_CEP3^5;2初始化
因为单片机上电默认是1所以要初始化为0
void DS1302_Init(void)
{DS1302_CE0;DS1302_SCLK0;
}
3写入函数
在给SCLK赋值的时候 DS1302_SCLK1; DS1302_SCLK0;
在这中间置1后马上置0需要有一个最小的延时但实际操作后发现不用加延时可以运行因为我们的单片机运行没有这么快
这里相当于我们已经写入了第0位
//Command是命令字
void DS1302_WriteByte(unsigned char Command,Data)
{DS1302_CE1;DS1302_IOCommand0x01; //取第0位DS1302_SCLK1; DS1302_SCLK0;}
同理第1位即 DS1302_IOCommand0x02; 第2位即 DS1302_IOCommand0x04; .......
所以我们可以用一个for循环来实现取8位
//Command是命令字
void DS1302_WriteByte(unsigned char Command,Data)
{unsigned char iDS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK1; DS1302_SCLK0;}}此时我们已经完成写入操作的一半又发现后面的写入数据和前面的写入指令是一样的所以我们可以复制for循环的代码思路
//Command是命令字
void DS1302_WriteByte(unsigned char Command,Data)
{unsigned char iDS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK1; DS1302_SCLK0;}for(i0;i8;i){DS1302_IOData(0x01i); DS1302_SCLK1; DS1302_SCLK0;}DS1302_CE0;
}
记得在最后把CE置0
到这我们就完成时序的写入函数我们就可以对任何的寄存器进行写入操作
4读取函数
虽然该部分的时序跟上面的写入类似但不能直接照搬因为在SCLK这条线上只有15个脉冲写入是16个因为在最中间的脉冲同时进行上升沿和下降沿的操作
所以我们把SCLK赋值的顺序颠倒一下先给0再给1这样当for循环8次后刚好全是上升沿 这里根据代码理解在图上比划一下就很好理解第一个for循环里先给0再给1在循环结束后SCLK依旧是1但是在第二个for循环里还是要先给1再给0目的就是为了跳过一个周期适配15个脉冲
unsigned char DS1302_ReadByte(unsigned char Command)
{unsigned char i,Data0x00;DS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK0; DS1302_SCLK1;}for(i0;i8;i){DS1302_SCLK1; DS1302_SCLK0;if(DS1302_IO){Data | (0X01i);} }DS1302_CE0;return Data;
}一般来说与操作是为了清零或操作是为了置1
最后不用忘了return 返回值因为这是有返回值的函数
5测试
写完上面3个函数我们就已经对时序模拟出来了、
接下来进行测试
先写好声明文件
//DS1302.h#ifndef __DS1302_H_
#define __DS1302_H_void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command,Data);
unsigned char DS1302_ReadByte(unsigned char Command);#endif
这里提醒一下DS1302初始化有写保护只能读不能写在DS1302初始化之后加一句DS1302_WriteByte(0x8e,0x000x8E为写保护寄存器需要先关闭写保护
//main文件#include REGX52.H
#include LCD1602.h
#include DS1302.hunsigned char Second;void main()
{DS1302_Init();DS1302_WriteByte(0x8E,0x00);LCD_Init();LCD_ShowString(1,1,RTC);DS1302_WriteByte(0x80,0x03);SecondDS1302_ReadByte(0x81);LCD_ShowNum(2,1,Second,3);while(1){}}
现象 6扩展知识点
BCD码Binary Coded Decimal用4位二进制数来表示1位十进制
内部的寄存器不是以二进制来存储的而是以BCD码来存储
例0001 0011表示131000 0101表示850001 1010不合法
在十六进制中的体现0x13表示130x85表示85,0x1A不合法
BCD码转十进制DECBCD/16*10BCD%16;2位BCD
十进制转BCD码BCDDEC/10*16DEC%16;2位BCD
#include REGX52.H
#include LCD1602.h
#include DS1302.h
#include Delay.hunsigned char Second;void main()
{DS1302_Init();DS1302_WriteByte(0x8E,0x00);LCD_Init();LCD_ShowString(1,1,RTC);DS1302_WriteByte(0x80,0x03);while(1){SecondDS1302_ReadByte(0x81);LCD_ShowHexNum(2,1,Second,3);}}
所以我们在这里想让Second自加显示在LCD上就得使用下面这个函数而不是ShowNum否则他会从9突变到16这是因为ShowNum是以十进制来显示而时钟寄存器的自加是上面所说的BCD码而下面这个函数是以十六进制显示的 LCD_ShowHexNum(2,1,Second,3); 十六进制和BCD码有部分兼容
下面解释寄存器里的BCD码
CH是时钟静止给1静止给0运行高3位显示10秒低4位显示秒分、时、日、月、年都是同理
小时的最高位是选择12/24制第6位选择AM还是PM 根据前面BCD码转十进制我们就可以写出
LCD_ShowNum(2,1,Second/16*10Second%16,3);
这样就可以在LCD上正常显示了
7定义数组函数存储读写年月日等
先定义地址
因为写入和读取的地址前7位都是一样的只有最低位是01之分这里我们只定义写入的地址只需要在读的函数里给Command即命令字的最低位置1这样就不用再重新定义读取的地址了
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_WP 0x8Eunsigned char DS1302_ReadByte(unsigned char Command)
{Command |0x01;下面是完整代码
记得要在.h文件里说明
这里再说一电声明外部变量时前面必须加extern数组和函数可以不加因为前面会自带
#include REGX52.H//重新对端口定义名字
sbit DS1302_SCLKP3^6;
sbit DS1302_IOP3^4;
sbit DS1302_CEP3^5;#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_WP 0x8Eunsigned char DS1320_Time[]{25,03,04,12,59,55,2}void DS1302_Init(void)
{DS1302_CE0;DS1302_SCLK0;
}//Command是命令字
void DS1302_WriteByte(unsigned char Command,Data)
{unsigned char i;DS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK1; DS1302_SCLK0;}for(i0;i8;i){DS1302_IOData(0x01i); DS1302_SCLK1; DS1302_SCLK0;}DS1302_CE0;
}unsigned char DS1302_ReadByte(unsigned char Command)
{unsigned char i,Data0x00;Command |0x01;DS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK0; DS1302_SCLK1;}for(i0;i8;i){DS1302_SCLK1; DS1302_SCLK0;if(DS1302_IO){Data | (0X01i);} }DS1302_CE0;DS1302_IO0;return Data;
}//写入时间是十进制转BCD码
void DS1302_SetTime(void)
{DS1302_WriteByte(DS1302_WP,0x00);DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16DS1302_Time[0]%10);DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16DS1302_Time[1]%10);DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16DS1302_Time[2]%10);DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16DS1302_Time[3]%10);DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16DS1302_Time[4]%10);DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16DS1302_Time[5]%10);DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16DS1302_Time[6]%10);DS1302_WriteByte(DS1302_WP,0x80);
}
//读取时间是BCD码转十进制
void DS1302_ReadTime(void)
{unsigned char Temp;TempDS1302_ReadByte(DS1302_YEAR);DS1302_Time[0]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_MONTH);DS1302_Time[1]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_DATE);DS1302_Time[2]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_HOUR);DS1302_Time[3]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_MINUTE);DS1302_Time[4]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_SECOND);DS1302_Time[5]Temp/16*10Temp%16TempDS1302_ReadByte(DS1302_DAY);DS1302_Time[6]Temp/16*10Temp%16}
有了这些代码我们就不用在main函数里定义时分秒了我们只需要调用函数即可
8主函数
到这里我们就做好第一个功能了
#include REGX52.H
#include LCD1602.h
#include DS1302.h
#include Delay.hvoid main()
{DS1302_Init();LCD_Init();LCD_ShowString(1,1, - - );LCD_ShowString(2,1, : : );DS1302_SetTime();while(1){DS1302_ReadTime();LCD_ShowNum(1,1,DS1302_Time[0],2);LCD_ShowNum(1,4,DS1302_Time[1],2);LCD_ShowNum(1,7,DS1302_Time[2],2);LCD_ShowNum(2,1,DS1302_Time[3],2);LCD_ShowNum(2,4,DS1302_Time[4],2);LCD_ShowNum(2,7,DS1302_Time[5],2);}}
下面再对模块化参数进行注释
#include REGX52.H//引脚定义
sbit DS1302_SCLKP3^6;
sbit DS1302_IOP3^4;
sbit DS1302_CEP3^5;//寄存器写入地址/指令定义
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_WP 0x8Eunsigned char DS1302_Time[]{25,03,04,12,59,55,2};/*** brief DS1302初始化* param 无* retval 无*/void DS1302_Init(void)
{DS1302_CE0;DS1302_SCLK0;
}/*** brief DS1302写一个字节* param Command命令字/地址* param Data要写入的数据* retval 无*/
void DS1302_WriteByte(unsigned char Command,Data)
{unsigned char i;DS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK1; DS1302_SCLK0;}for(i0;i8;i){DS1302_IOData(0x01i); DS1302_SCLK1; DS1302_SCLK0;}DS1302_CE0;
}/*** brief DS1302读一个字节* param Command命令字/地址* retval 读出的数据*/unsigned char DS1302_ReadByte(unsigned char Command)
{unsigned char i,Data0x00;Command |0x01;DS1302_CE1;for(i0;i8;i){DS1302_IOCommand(0x01i); DS1302_SCLK0; DS1302_SCLK1;}for(i0;i8;i){DS1302_SCLK1; DS1302_SCLK0;if(DS1302_IO){Data | (0X01i);} }DS1302_CE0;DS1302_IO0;return Data;
}/*** brief DS1302设置时间调用之后DS1302_Time数组的数字会被设置到DS1302中* param 无* retval 无*/
void DS1302_SetTime(void)
{DS1302_WriteByte(DS1302_WP,0x00);DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16DS1302_Time[0]%10);//鍗佽繘鍒惰浆BCD鐮佸悗鍐欏叆DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16DS1302_Time[1]%10);DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16DS1302_Time[2]%10);DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16DS1302_Time[3]%10);DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16DS1302_Time[4]%10);DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16DS1302_Time[5]%10);DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16DS1302_Time[6]%10);DS1302_WriteByte(DS1302_WP,0x80);
}/*** brief DS1302读取时间调用之后DS1302中的数据会被读取到DS1302_Time数组中* param 无* retval 无*/
void DS1302_ReadTime(void)
{unsigned char Temp;TempDS1302_ReadByte(DS1302_YEAR);DS1302_Time[0]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_MONTH);DS1302_Time[1]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_DATE);DS1302_Time[2]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_HOUR);DS1302_Time[3]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_MINUTE);DS1302_Time[4]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_SECOND);DS1302_Time[5]Temp/16*10Temp%16;TempDS1302_ReadByte(DS1302_DAY);DS1302_Time[6]Temp/16*10Temp%16;}
二.DS1302可调时钟
这个部分是上一个代码的升级版这一块会比较难
下面为了节约空间我没有把定义的变量标出来都是unsigned char类型
1.按键1切换
定义按键1切换我们的模式模式0是时间显示模式1是时间设置
void main()
{DS1302_Init();LCD_Init();LCD_ShowString(1,1, - - );LCD_ShowString(2,1, : : );DS1302_SetTime();while(1){KeyNumKey();if(KeyNum1){if(MODE0){MODE1;}else if(MODE1){MODE0;}}switch(MODE){case 0:TimeShow();break;case 1:TimeSet();break;}}}
2.时间显示函数
void TimeShow(void)
{DS1302_ReadTime();LCD_ShowNum(1,1,DS1302_Time[0],2);LCD_ShowNum(1,4,DS1302_Time[1],2);LCD_ShowNum(1,7,DS1302_Time[2],2);LCD_ShowNum(2,1,DS1302_Time[3],2);LCD_ShowNum(2,4,DS1302_Time[4],2);LCD_ShowNum(2,7,DS1302_Time[5],2);
}3.时间设置函数
按键2让时间设置选择并且取值范围在0~5
void TimeSet(void)
{if(KeyNum2){TimeSetSelect;TimeSetSelect%6; //大于5越界取余0的进阶写法}if(KeyNum3){DS1302_Time[TimeSetSelect];}if(KeyNum4){DS1302_Time[TimeSetSelect]--;}LCD_ShowNum(1,1,DS1302_Time[0],2);LCD_ShowNum(1,4,DS1302_Time[1],2);LCD_ShowNum(1,7,DS1302_Time[2],2);LCD_ShowNum(2,1,DS1302_Time[3],2);LCD_ShowNum(2,4,DS1302_Time[4],2);LCD_ShowNum(2,7,DS1302_Time[5],2);LCD_ShowNum(2,10,TimeSetSelect,2);
}这样就已经实现对时钟的六个位进行选择和加减但是我们并没有设置越界判断也就是说月份会一直加到13,14月所以下面我们对这个函数进行越界判断的优化
这段最麻烦是对日的判断因为有30和31的区分而2月又有28和29的区分所以非常麻烦
void TimeSet(void)
{if(KeyNum2){TimeSetSelect;TimeSetSelect%6; //大于5越界取余0的进阶写法}
if(KeyNum3){DS1302_Time[TimeSetSelect];if(DS1302_Time[0]99){DS1302_Time[0]0;}if(DS1302_Time[1]12){DS1302_Time[1]1;}if( DS1302_Time[1]1 || DS1302_Time[1]3 || DS1302_Time[1]5 || DS1302_Time[1]7 || DS1302_Time[1]8 || DS1302_Time[1]10 || DS1302_Time[1]12){if(DS1302_Time[2]31){DS1302_Time[2]1;}}else if(DS1302_Time[1]4 || DS1302_Time[1]6 || DS1302_Time[1]9 || DS1302_Time[1]11){if(DS1302_Time[2]30){DS1302_Time[2]1;}}else if(DS1302_Time[1]2){if(DS1302_Time[0]%40){if(DS1302_Time[2]29){DS1302_Time[2]1;}}else{if(DS1302_Time[2]28){DS1302_Time[2]1;}}}if(DS1302_Time[3]23){DS1302_Time[3]0;}if(DS1302_Time[4]59){DS1302_Time[4]0;}if(DS1302_Time[5]59){DS1302_Time[5]0;}}if(KeyNum4){DS1302_Time[TimeSetSelect]--;if(DS1302_Time[0]0){DS1302_Time[0]99;}if(DS1302_Time[1]1){DS1302_Time[1]12;}if( DS1302_Time[1]1 || DS1302_Time[1]3 || DS1302_Time[1]5 || DS1302_Time[1]7 || DS1302_Time[1]8 || DS1302_Time[1]10 || DS1302_Time[1]12){if(DS1302_Time[2]1){DS1302_Time[2]31;}if(DS1302_Time[2]31){DS1302_Time[2]1;}}else if(DS1302_Time[1]4 || DS1302_Time[1]6 || DS1302_Time[1]9 || DS1302_Time[1]11){if(DS1302_Time[2]1){DS1302_Time[2]30;}if(DS1302_Time[2]30){DS1302_Time[2]1;}}else if(DS1302_Time[1]2){if(DS1302_Time[0]%40){if(DS1302_Time[2]1){DS1302_Time[2]29;}if(DS1302_Time[2]29){DS1302_Time[2]1;}}else{if(DS1302_Time[2]1){DS1302_Time[2]28;}if(DS1302_Time[2]28){DS1302_Time[2]1;}}}if(DS1302_Time[3]0){DS1302_Time[3]23;}if(DS1302_Time[4]0){DS1302_Time[4]59;}if(DS1302_Time[5]0){DS1302_Time[5]59;}}LCD_ShowNum(1,1,DS1302_Time[0],2);LCD_ShowNum(1,4,DS1302_Time[1],2);LCD_ShowNum(1,7,DS1302_Time[2],2);LCD_ShowNum(2,1,DS1302_Time[3],2);LCD_ShowNum(2,4,DS1302_Time[4],2);LCD_ShowNum(2,7,DS1302_Time[5],2);LCD_ShowNum(2,10,TimeSetSelect,2);
}4.选择对应位闪烁
感叹号是逻辑取反波浪号是按位取反
比如0逻辑取反1,1逻辑取反00按位取反0xFE1按位取反0xFF
我们设置一个变量让他10101010的变化然后当选择某个位时让这个位为1时亮为0时灭在这里我们只需要一个标识位所以用逻辑取反就好
这里要用到之前的定时器中断的函数 if(TimeSetSelect0TimeSetFlashFlag1){LCD_ShowString(1,1, );}else {LCD_ShowNum(1,1,DS1302_Time[0],2);}if(TimeSetSelect1TimeSetFlashFlag1){LCD_ShowString(1,4, );}else {LCD_ShowNum(1,4,DS1302_Time[1],2);}if(TimeSetSelect2TimeSetFlashFlag1){LCD_ShowString(1,7, );}else {LCD_ShowNum(1,7,DS1302_Time[2],2);}if(TimeSetSelect3TimeSetFlashFlag1){LCD_ShowString(2,1, );}else {LCD_ShowNum(2,1,DS1302_Time[3],2);}if(TimeSetSelect4TimeSetFlashFlag1){LCD_ShowString(2,4, );}else {LCD_ShowNum(2,4,DS1302_Time[4],2);}if(TimeSetSelect5TimeSetFlashFlag1){LCD_ShowString(2,7, );}else {LCD_ShowNum(2,7,DS1302_Time[5],2);}void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值T0Count;if(T0Count500){T0Count0;TimeSetFlashFlag!TimeSetFlashFlag;}}
#include REGX52.H
#include LCD1602.h
#include DS1302.h
#include Delay.h
#include Key.h
#include Timer0.hunsigned char KeyNum,MODE,TimeSetSelect,TimeSetFlashFlag;void TimeShow(void)
{DS1302_ReadTime();LCD_ShowNum(1,1,DS1302_Time[0],2);LCD_ShowNum(1,4,DS1302_Time[1],2);LCD_ShowNum(1,7,DS1302_Time[2],2);LCD_ShowNum(2,1,DS1302_Time[3],2);LCD_ShowNum(2,4,DS1302_Time[4],2);LCD_ShowNum(2,7,DS1302_Time[5],2);
}void TimeSet(void)
{if(KeyNum2){TimeSetSelect;TimeSetSelect%6; //大于5越界取余0的进阶写法}
if(KeyNum3){DS1302_Time[TimeSetSelect];if(DS1302_Time[0]99){DS1302_Time[0]0;}if(DS1302_Time[1]12){DS1302_Time[1]1;}if( DS1302_Time[1]1 || DS1302_Time[1]3 || DS1302_Time[1]5 || DS1302_Time[1]7 || DS1302_Time[1]8 || DS1302_Time[1]10 || DS1302_Time[1]12){if(DS1302_Time[2]31){DS1302_Time[2]1;}}else if(DS1302_Time[1]4 || DS1302_Time[1]6 || DS1302_Time[1]9 || DS1302_Time[1]11){if(DS1302_Time[2]30){DS1302_Time[2]1;}}else if(DS1302_Time[1]2){if(DS1302_Time[0]%40){if(DS1302_Time[2]29){DS1302_Time[2]1;}}else{if(DS1302_Time[2]28){DS1302_Time[2]1;}}}if(DS1302_Time[3]23){DS1302_Time[3]0;}if(DS1302_Time[4]59){DS1302_Time[4]0;}if(DS1302_Time[5]59){DS1302_Time[5]0;}}if(KeyNum4){DS1302_Time[TimeSetSelect]--;if(DS1302_Time[0]0){DS1302_Time[0]99;}if(DS1302_Time[1]1){DS1302_Time[1]12;}if( DS1302_Time[1]1 || DS1302_Time[1]3 || DS1302_Time[1]5 || DS1302_Time[1]7 || DS1302_Time[1]8 || DS1302_Time[1]10 || DS1302_Time[1]12){if(DS1302_Time[2]1){DS1302_Time[2]31;}if(DS1302_Time[2]31){DS1302_Time[2]1;}}else if(DS1302_Time[1]4 || DS1302_Time[1]6 || DS1302_Time[1]9 || DS1302_Time[1]11){if(DS1302_Time[2]1){DS1302_Time[2]30;}if(DS1302_Time[2]30){DS1302_Time[2]1;}}else if(DS1302_Time[1]2){if(DS1302_Time[0]%40){if(DS1302_Time[2]1){DS1302_Time[2]29;}if(DS1302_Time[2]29){DS1302_Time[2]1;}}else{if(DS1302_Time[2]1){DS1302_Time[2]28;}if(DS1302_Time[2]28){DS1302_Time[2]1;}}}if(DS1302_Time[3]0){DS1302_Time[3]23;}if(DS1302_Time[4]0){DS1302_Time[4]59;}if(DS1302_Time[5]0){DS1302_Time[5]59;}}if(TimeSetSelect0TimeSetFlashFlag1){LCD_ShowString(1,1, );}else {LCD_ShowNum(1,1,DS1302_Time[0],2);}if(TimeSetSelect1TimeSetFlashFlag1){LCD_ShowString(1,4, );}else {LCD_ShowNum(1,4,DS1302_Time[1],2);}if(TimeSetSelect2TimeSetFlashFlag1){LCD_ShowString(1,7, );}else {LCD_ShowNum(1,7,DS1302_Time[2],2);}if(TimeSetSelect3TimeSetFlashFlag1){LCD_ShowString(2,1, );}else {LCD_ShowNum(2,1,DS1302_Time[3],2);}if(TimeSetSelect4TimeSetFlashFlag1){LCD_ShowString(2,4, );}else {LCD_ShowNum(2,4,DS1302_Time[4],2);}if(TimeSetSelect5TimeSetFlashFlag1){LCD_ShowString(2,7, );}else {LCD_ShowNum(2,7,DS1302_Time[5],2);}}void main()
{DS1302_Init();LCD_Init();Timer0Init();LCD_ShowString(1,1, - - );LCD_ShowString(2,1, : : );DS1302_SetTime();while(1){KeyNumKey();if(KeyNum1){if(MODE0){MODE1;TimeSetSelect0;}else if(MODE1){MODE0;DS1302_SetTime();}}switch(MODE){case 0:TimeShow();break;case 1:TimeSet();break;}}}void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值T0Count;if(T0Count500){T0Count0;TimeSetFlashFlag!TimeSetFlashFlag;}}
这代码还有一个缺陷就是按下按键的时候会停止时间
就是我们在写Key函数时用到了while死循环但是为了简单应用只能这样
unsigned int Key()
{unsigned char KeyNumber0;if(P3_10){Delay(20);while(P3_10);Delay(20);KeyNumber1;}if(P3_00){Delay(20);while(P3_00);Delay(20);KeyNumber2;}if(P3_20){Delay(20);while(P3_20);Delay(20);KeyNumber3;}if(P3_30){Delay(20);while(P3_30);Delay(20);KeyNumber4;}return KeyNumber;
}