1 #include<reg52.h>//单片机头文件
2 #define uchar unsigned char//宏定义,用uchar表示unsigned char,叫无符号字符型数据类型,取值范围为:0到255。
3 #define uint unsigned int//宏定义,用uint表示unsigned int,叫无符号整数型数据类型,取值范围为:0到65535。
4 sbit RS=P0^7;//位定义LCD1602字符型液晶显示器的数据/命令选择引脚
5 sbit RW=P0^6;//位定义LCD1602字符型液晶显示器的读写引脚
6 sbit EN=P0^5; //位定义LCD1602字符型液晶显示器的使能引脚
7 sbit S1=P3^5;//移位按键S1
8 sbit S2=P3^4;//增加按键S2
9 sbit S3=P3^3;//减少按键S3
10 sbit S4=P3^2;//启停按键S4
11 uchar count,S1num,S4num;//count为定时器0中断次数变量,S1num为移位按键S1按键按下次数变量,S4num为启停按键S4按下次数变量。
12 uchar shi,fen,miao;//未做时间修改的计时时钟、分钟、秒钟变量
13 uchar secondge,secondshi; //秒钟个位、十位的变量
14 uchar minutange,minutanshi;//分钟个位、十位的变量
15 uchar hourge,hourshi;//时钟个位、十位的变量
16 uchar table0[]="2019-11-11";//LCD1602第一行初始显示
17 uchar table1[]="00:00:00";//LCD1602第二行初始显示
18 void Delay(uint z)//延时程序
19 {
20 uint x,y;
21 for(x=z;x>0;x--)
22 for(y=110;y>0;y--);
23 }
24 void WriteCommand(uchar command)//LCD1602字符型液晶显示器写指令函数
25 {
26 RS=0;//LCD1602字符型液晶显示器指令寄存器低电平
27 RW=0;//LCD1602字符型液晶显示器写指令操作低电平
28 P2=command;//LCD1602字符型液晶显示器写指令函数写指令到单片机P2组端口,再输送到LCD1602字符型液晶显示器指令寄存器中执行。
29 Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
30 EN=1;//LCD1602字符型液晶显示器使能端高电平
31 Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
32 EN=0;//LCD1602字符型液晶显示器使能端低电平
33 }
34 void WriteData(uchar information)//LCD1602字符型液晶显示器写数据函数
35 {
36 RS=1;//LCD1602字符型液晶显示器数据寄存器高电平
37 RW=0;//LCD1602字符型液晶显示器写数据操作低电平
38 P2=information;//LCD1602字符型液晶显示器写数据函数写数据到单片机P2组端口,再输送到LCD1602字符型液晶显示器上显示。
39 Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
40 EN=1;//LCD1602字符型液晶显示器使能端高电平
41 Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
42 EN=0;//LCD1602字符型液晶显示器使能端低电平
43 }
44 void LCD1602Init()//LCD1602初始化函数
45 {
46 WriteCommand(0x38);//设置LCD1602字符型液晶显示器16x2显示,5*7或5*8点阵,8位数据并口,简称显模。
47 WriteCommand(0x08);//设置LCD1602字符型液晶显示器显示开,简称亮屏。
48 WriteCommand(0x01);//设置清除LCD1602字符型液晶显示器屏上所有内容,并让光标复位到LCD1602字符型液晶显示器屏左上角,简称清屏。
49 WriteCommand(0x06);//设置开光标(或字符)地址指针自增1,光标右移动一个字符位,整屏显示不移动。
50 WriteCommand(0x0c);//设置开LCD1602字符型液晶显示器显示,关光标,关光标(字符)闪烁。
51 }
52 void Timer0Init()//定时器0初始化函数
53 {
54 TMOD=0x01;//设定定时器0工作模式为模式1
55 TH0=(65536-50000)/256;//TH0装初值
56 TL0=(65536-50000)%256;//TL0装初值
57 EA=1;//开启定时器总中断
58 ET0=1;//开启定时器0中断开关
59 TR0=1;//启动定时器0
60 }
61 void LCD1602Display()//LCD1602字符型液晶显示器显示函数
62 {
63 uchar j;//j表示数组元素个数变量
64 WriteCommand(0x80+0x00);//LCD1602字符型液晶显示器第一行第一个位置显示
65 for(j=0;j<10;j++)//有10个字符,要循环10次。
66 {
67 WriteData(table0[j]);//显示字符串
68 Delay(5);
69 }
70 WriteCommand(0x80+0x40);//LCD1602字符型液晶显示器第二行第一个位置显示
71 for(j=0;j<8;j++)//有8个字符,要循环8次。
72 {
73 WriteData(table1[j]);//显示字符串
74 Delay(5);
75 }
76 }
77 void LCD1602DisplayTime(uchar address,uchar num)//LCD1602显示时间两位数分解函数
78 {
79 uchar shi,ge;//十位、个位的变量
80 shi=num/10;//十位数
81 ge=num%10;//个位数
82 WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
83 WriteData(0x30+shi);//0x30表示字符库的数字0,整个代码表示十位可显示0到9的数字。
84 WriteData(0x30+ge);//0x30表示字符库的数字0,整个代码表示个位可显示0到9的数字。
85 }
86 void LCD1602DisplayGeDigitResolve(uchar address,uchar num)//LCD1602字符型液晶显示器显示修改时间个位数分解函数
87 {
88 uchar ge;//个位的变量
89 ge=num%10;//个位数
90 WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
91 WriteData(0x30+ge);//0x30表示字符库的数字0,整个代码表示个位可显示0到9的数字。
92 }
93 void LCD1602DisplayShiDigitResolve(uchar address,uchar num)//LCD1602字符型液晶显示器修改时间十位数分解函数
94 {
95 uchar shi;//十位变量
96 shi=num%10;//十位数
97 WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
98 WriteData(0x30+shi);//0x30表示字符库的数字0,整个代码表示十位可显示0到9的数字。
99 }
100 void KeyScan()//按键扫描函数
101 {
102 if(S1==0)//判断移位按键S1是否按下
103 {
104 Delay(5);
105 if(S1==0)//再次判断移位按键S1是否按下
106 {
107 S1num++;//移位按键S1按键次数变量先赋值再自加
108 while(!S1);//等待移位按键S1弹起
109 switch(S1num)
110 {
111 case 1:
112 TR0=0;//关定时器0
113 S4num=0;//启停按键S4按下次数清零
114 secondge=miao%10;//关掉定时器0定时后,把秒钟计时时间数值取余赋给秒钟个位显示位。
115 secondshi=miao/10;//关掉定时器0定时后,把秒钟计时时间数值取除赋给秒钟十位显示位。
116 WriteCommand(0x80+0x40+0x07);//LCD1602字符型液晶显示器第二行第8个位置的显示位
117 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
118 break;
119 case 2:
120 secondshi=secondshi;//关掉定时器0定时后,把秒钟计时时间数值取除后得到的值再赋给秒钟十位显示位。
121 WriteCommand(0x80+0x40+0x06);//LCD1602字符型液晶显示器第二行第7个位置的显示位
122 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
123 break;
124 case 3:
125 minutange=fen%10;//关掉定时器0定时后,把分钟计时时间数值取余赋给分钟个位显示位。
126 minutanshi=fen/10;//关掉定时器0定时后,把分钟计时时间数值取除赋给分钟十位显示位。
127 WriteCommand(0x80+0x40+0x04);//LCD1602字符型液晶显示器第二行第5个位置的显示位
128 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
129 break;
130 case 4:
131 minutanshi=minutanshi;//关掉定时器0定时后,把分钟计时时间数值取除后得到的值再赋给分钟十位显示位。
132 WriteCommand(0x80+0x40+0x03);//LCD1602字符型液晶显示器第二行第4个位置的显示位
133 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
134 break;
135 case 5:
136 hourge=shi%10;//关掉定时器0定时后,把时钟计时时间数值取余赋给时钟个位显示位。
137 hourshi=shi/10;//关掉定时器0定时后,把时钟计时时间数值取除赋给时钟十位显示位。
138 WriteCommand(0x80+0x40+0x01);//LCD1602字符型液晶显示器第二行第2个位置的显示位
139 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
140 break;
141 case 6:
142 hourshi=hourshi;//关掉定时器0定时后,把时钟计时时间数值取除后得到的值再赋给时钟十位显示位。
143 WriteCommand(0x80+0x40+0x00);//LCD1602字符型液晶显示器第二行第1个位置的显示位
144 WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
145 break;
146 case 7:
147 WriteCommand(0x80+0x40+0x07);//LCD1602字符型液晶显示器第二行第8个位置的显示位
148 WriteCommand(0x0c);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
149 TR0=1;//打开定时器0
150 S1num=0;//移位按键S1按键按下次数清零
151 break;
152 default:
153 S1num=0;//移位按键S1按键按下次数清零
154 break;
155 }
156 }
157 }
158 if(S1num!=0)//判断移位按键S1按键按下次数变量是否为0
159 {
160 if(S2==0)//判断增加按键S2是否按下
161 {
162 if(S2==0)//判断增加按键S2是否按下
163 {
164 Delay(5);
165 if(S2==0)//再次判断增加按键S2是否按下
166 {
167 while(!S2);//等待增加按键S2弹起
168 switch(S1num)//移位按键S1按键按下次数变量选择位
169 {
170 case 1://移位按键S1按键第一次按下
171 secondge++;//秒钟个位数先赋值再加加
172 if(secondge==10)//判断秒钟个位数设定值是否达到10
173 secondge=0;//秒钟个位数归零
174 LCD1602DisplayGeDigitResolve(0x07,secondge);//LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位的显示数
175 WriteCommand(0x80+0x40+0x07);//写入LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位
176 miao=secondshi*10+secondge;//移位修改秒钟个位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
177 break;
178 case 2://移位按键S1按键第二次按下
179 secondshi++;//秒钟十位数先赋值再加加
180 if(secondshi==6)//判断秒钟十位数设定值是否达到6
181 secondshi=0;//秒钟十位数归零
182 LCD1602DisplayShiDigitResolve(0x06,secondshi);//LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位的显示数
183 WriteCommand(0x80+0x40+0x06);//写入LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位
184 miao=secondshi*10+secondge;//移位修改秒钟十位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
185 break;
186 case 3://移位按键S1按键第三次按下
187 minutange++;//分钟个位数先赋值再加加
188 if(minutange==10)//判断分钟个位数设定值是否达到10
189 minutange=0;//分钟个位数归零
190 LCD1602DisplayGeDigitResolve(0x04,minutange);//LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位的显示数
191 WriteCommand(0x80+0x40+0x04);//写入LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位
192 fen=minutanshi*10+minutange;//移位修改分钟个位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
193 break;
194 case 4://移位按键S1按键第四次按下
195 minutanshi++;//分钟十位数先赋值再加加
196 if(minutanshi==6)//判断分钟十位数设定值是否达到6
197 minutanshi=0;//分钟十位数归零
198 LCD1602DisplayShiDigitResolve(0x03,minutanshi);//LCD1602字符型液晶显示器第二行第4个位置的分钟十位显示位的显示数
199 WriteCommand(0x80+0x40+0x03);//写入LCD1602字符型液晶显示器第二行第7个位置的分钟十位显示位
200 fen=minutanshi*10+minutange;//移位修改分钟十位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
201 break;
202 case 5://移位按键S1按键第五次按下
203 hourge++;//时钟个位数先赋值再加加
204 if(hourge==4)//判断时钟个位数设定值是否达到4
205 hourge=0;//时钟个位数归零
206 LCD1602DisplayGeDigitResolve(0x01,hourge);//LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位的显示数
207 WriteCommand(0x80+0x40+0x01);//写入LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位
208 shi=hourshi*10+hourge;//移位修改时钟个位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
209 break;
210 case 6://移位按键S1按键第六次按下
211 hourshi++;//时钟十位数先赋值再加加
212 if(hourshi==3)//判断时钟十位数设定值是否达到3
213 hourshi=0;//时钟十位数归零
214 LCD1602DisplayShiDigitResolve(0x00,hourshi);//LCD1602字符型液晶显示器第二行第1个位置的时钟十位显示位的显示数
215 WriteCommand(0x80+0x40+0x00);//写入LCD1602第二行第1个位置的时钟十位显示位
216 shi=hourshi*10+hourge;//移位修改时钟十位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
217 break;
218 default:
219 S1num=0;//移位按键S1按键按下次数清零
220 break;
221 }
222 }
223 }
224 if(S3==0)//判断减少按键S3是否按下
225 {
226 Delay(5);
227 if(S3==0)//再次判断减少按键S3是否按下
228 {
229 while(!S3);//等待减少按键S3弹起
230 switch(S1num)//移位按键S1按键按下次数变量选择位
231 {
232 case 1://移位按键S1按键第一次按下
233 secondge--;//秒钟个位数先赋值再减减
234 if(secondge==-1)//判断秒钟个位数设定值是否达到-1
235 secondge=9;//秒钟个位数归9
236 LCD1602DisplayGeDigitResolve(0x07,secondge);//LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位的显示数
237 WriteCommand(0x80+0x40+0x07);//写入LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位
238 miao=secondshi*10+secondge;//移位修改秒钟个位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
239 break;
240 case 2://移位按键S1按键第二次按下
241 secondshi--;//秒钟十位数先赋值再减减
242 if(secondshi==-1)//判断秒钟十位数设定值是否达到-1
243 secondshi=5;//秒钟十位数归5
244 LCD1602DisplayShiDigitResolve(0x06,secondshi);//LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位的显示数
245 WriteCommand(0x80+0x40+0x06);//写入LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位
246 miao=secondshi*10+secondge;//移位修改秒钟十位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
247 break;
248 case 3://移位按键S1按键第三次按下
249 minutange--;//分钟个位数先赋值再减减
250 if(minutange==-1)//判断分钟个位数设定值是否达到-1
251 minutange=9;//分钟个位数归9
252 LCD1602DisplayGeDigitResolve(0x04,minutange);//LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位的显示数
253 WriteCommand(0x80+0x40+0x04);//写入LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位
254 fen=minutanshi*10+minutange;//移位修改分钟个位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
255 break;
256 case 4://移位按键S1按键第四次按下
257 minutanshi--;//分钟十位数先赋值再减减
258 if(minutanshi==-1)//判断分钟十位数设定值是否达到6
259 minutanshi=5;//分钟十位数归5
260 LCD1602DisplayShiDigitResolve(0x03,minutanshi);//LCD1602字符型液晶显示器第二行第4个位置的分钟十位显示位的显示数
261 WriteCommand(0x80+0x40+0x03);//写入LCD1602字符型液晶显示器第二行第7个位置的分钟十位显示位
262 fen=minutanshi*10+minutange;//移位修改分钟十位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
263 break;
264 case 5://移位按键S1按键第五次按下
265 hourge--;//时钟个位数先赋值再减减
266 if(hourge==-1)//判断时钟个位数设定值是否达到-1
267 hourge=3;//时钟个位数归3
268 LCD1602DisplayGeDigitResolve(0x01,hourge);//LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位的显示数
269 WriteCommand(0x80+0x40+0x01);//写入LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位
270 shi=hourshi*10+hourge;//移位修改时钟个位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
271 break;
272 case 6://移位按键S1按键第六次按下
273 hourshi--;//时钟十位数先赋值再减减
274 if(hourshi==-1)//判断时钟十位数设定值是否达到-1
275 hourshi=2;//时钟十位数归2
276 LCD1602DisplayShiDigitResolve(0x00,hourshi);//LCD1602字符型液晶显示器第二行第1个位置的时钟十位显示位的显示数
277 WriteCommand(0x80+0x40+0x00);//写入LCD1602字符型液晶显示器第二行第1个位置的时钟十位显示位
278 shi=hourshi*10+hourge;//移位修改时钟十位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
279 break;
280 default:
281 S1num=0;//移位按键S1按键按下次数清零
282 break;
283 }
284 }
285 }
286 }
287 if(S4==0)//判断启停按键S4是否按下
288 {
289 Delay(5);
290 if(S4==0)//再次判断启停按键S4是否按下
291 {
292 S4num++;//启停按键S4按下次数先赋值再加加
293 while(!S4);//等待启停按键S4弹起
294 if(S4num==1)//判断启停按键S4是否第一次按下过。实现直接停止。
295 {
296 TR0=0;//关定时器0
297 }
298 if(S1num>=1&&S4num==1)//判断移位按键S1按键和启停按键S4是否按下过。实现移位停止后,可移位修改时间数值或不修改时间数值,然后再启动。
299 {
300 TR0=1;//开定时器0
301 WriteCommand(0x0c);//开LCD1602显示,关光标,关光标(或字符)闪烁。
302 S4num=0;//启停按键S4按下次数变量清零
303 S1num=0;//移位按键S1按键按下次数变量清零
304 }
305 if(S4num==2)//判断移位按键S4按键是否第二次按下过
306 {
307 TR0=1;//开定时器0
308 S4num=0;//启停按键S4按下次数变量清零
309 }
310 }
311 }
312 }
313 void Timer0() interrupt 1//定时器0中断函数
314 {
315 TH0=(65536-50000)/256;//TH0重新装值
316 TL0=(65536-50000)%256;//TL0重新装值
317 count++;//定时器0中断次数先赋值再加
318 if(count==18)//判断定时器0中断次数是否为18次
319 {
320 count=0;//定时器0中断次数归零
321 miao++;//秒钟先赋值再加
322 if(miao==60)//判断秒钟是否达到60秒
323 {
324 miao=0;//秒钟归零
325 fen++;//分钟先赋值再加
326 if(fen==60)//判断分钟是否达到60分
327 {
328 fen=0;//分钟归零
329 shi++;//时钟先赋值再加
330 if(shi==24)//判断时钟是否达到24时
331 {
332 shi=0;//时钟归零
333 }
334 LCD1602DisplayTime(0x00,shi);//时钟显示两位数分解函数
335 }
336 LCD1602DisplayTime(0x03,fen);//分钟显示两位数分解函数
337 }
338 LCD1602DisplayTime(0x06,miao);//秒钟显示两位数分解函数
339 }
340 }
341 void main()//主函数
342 {
343 LCD1602Init();//LCD1602字符型液晶显示器初始化函数
344 Timer0Init();//定时器0初始化函数
345 LCD1602Display();//LCD1602字符型液晶显示器显示函数
346 while(1)
347 {
348 KeyScan();//按键扫描函数
349 }
350 }
![](https://img2020.cnblogs.com/blog/1680900/202004/1680900-20200425093641124-2145614626.png)