• DS1302和LCD1602整合长短按键电子钟


    以下代码来自学习江科大自化协和手把手教你学51单片机后的整合

     

     

     

     

    1. //LCD1602.h
    2. #ifndef __LCD1602_H__
    3. #define __LCD1602_H__
    4. //用户调用函数:
    5. void LCD_Init();
    6. void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
    7. void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
    8. void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
    9. void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
    10. void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
    11. void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
    12. #endif
    13. //LCD1602.c
    14. #include
    15. //引脚配置:
    16. sbit LCD_RS=P2^6;
    17. sbit LCD_RW=P2^5;
    18. sbit LCD_EN=P2^7;
    19. #define LCD_DataPort P0
    20. //函数定义:
    21. /**
    22. * @brief LCD1602延时函数,12MHz调用可延时1ms
    23. * @param 无
    24. * @retval 无
    25. */
    26. void LCD_Delay()
    27. {
    28. unsigned char i, j;
    29. i = 2;
    30. j = 239;
    31. do
    32. {
    33. while (--j);
    34. } while (--i);
    35. }
    36. /**
    37. * @brief LCD1602写命令
    38. * @param Command 要写入的命令
    39. * @retval 无
    40. */
    41. void LCD_WriteCommand(unsigned char Command)
    42. {
    43. LCD_RS=0;
    44. LCD_RW=0;
    45. LCD_DataPort=Command;
    46. LCD_EN=1;
    47. LCD_Delay();
    48. LCD_EN=0;
    49. LCD_Delay();
    50. }
    51. /**
    52. * @brief LCD1602写数据
    53. * @param Data 要写入的数据
    54. * @retval 无
    55. */
    56. void LCD_WriteData(unsigned char Data)
    57. {
    58. LCD_RS=1;
    59. LCD_RW=0;
    60. LCD_DataPort=Data;
    61. LCD_EN=1;
    62. LCD_Delay();
    63. LCD_EN=0;
    64. LCD_Delay();
    65. }
    66. /**
    67. * @brief LCD1602设置光标位置
    68. * @param Line 行位置,范围:1~2
    69. * @param Column 列位置,范围:1~16
    70. * @retval 无
    71. */
    72. void LCD_SetCursor(unsigned char Line,unsigned char Column)
    73. {
    74. if(Line==1)
    75. {
    76. LCD_WriteCommand(0x80|(Column-1));
    77. }
    78. else if(Line==2)
    79. {
    80. LCD_WriteCommand(0x80|(Column-1+0x40));
    81. }
    82. }
    83. /**
    84. * @brief LCD1602初始化函数
    85. * @param 无
    86. * @retval 无
    87. */
    88. void LCD_Init()
    89. {
    90. LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
    91. LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
    92. LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
    93. LCD_WriteCommand(0x01);//光标复位,清屏
    94. }
    95. /**
    96. * @brief 在LCD1602指定位置上显示一个字符
    97. * @param Line 行位置,范围:1~2
    98. * @param Column 列位置,范围:1~16
    99. * @param Char 要显示的字符
    100. * @retval 无
    101. */
    102. void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
    103. {
    104. LCD_SetCursor(Line,Column);
    105. LCD_WriteData(Char);
    106. }
    107. /**
    108. * @brief 在LCD1602指定位置开始显示所给字符串
    109. * @param Line 起始行位置,范围:1~2
    110. * @param Column 起始列位置,范围:1~16
    111. * @param String 要显示的字符串
    112. * @retval 无
    113. */
    114. void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
    115. {
    116. unsigned char i;
    117. LCD_SetCursor(Line,Column);
    118. for(i=0;String[i]!='\0';i++)
    119. {
    120. LCD_WriteData(String[i]);
    121. }
    122. }
    123. /**
    124. * @brief 返回值=X的Y次方
    125. */
    126. int LCD_Pow(int X,int Y)
    127. {
    128. unsigned char i;
    129. int Result=1;
    130. for(i=0;i
    131. {
    132. Result*=X;
    133. }
    134. return Result;
    135. }
    136. /**
    137. * @brief 在LCD1602指定位置开始显示所给数字
    138. * @param Line 起始行位置,范围:1~2
    139. * @param Column 起始列位置,范围:1~16
    140. * @param Number 要显示的数字,范围:0~65535
    141. * @param Length 要显示数字的长度,范围:1~5
    142. * @retval 无
    143. */
    144. void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
    145. {
    146. unsigned char i;
    147. LCD_SetCursor(Line,Column);
    148. for(i=Length;i>0;i--)
    149. {
    150. LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
    151. }
    152. }
    153. /**
    154. * @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
    155. * @param Line 起始行位置,范围:1~2
    156. * @param Column 起始列位置,范围:1~16
    157. * @param Number 要显示的数字,范围:-32768~32767
    158. * @param Length 要显示数字的长度,范围:1~5
    159. * @retval 无
    160. */
    161. void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
    162. {
    163. unsigned char i;
    164. unsigned int Number1;
    165. LCD_SetCursor(Line,Column);
    166. if(Number>=0)
    167. {
    168. LCD_WriteData('+');
    169. Number1=Number;
    170. }
    171. else
    172. {
    173. LCD_WriteData('-');
    174. Number1=-Number;
    175. }
    176. for(i=Length;i>0;i--)
    177. {
    178. LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
    179. }
    180. }
    181. /**
    182. * @brief 在LCD1602指定位置开始以十六进制显示所给数字
    183. * @param Line 起始行位置,范围:1~2
    184. * @param Column 起始列位置,范围:1~16
    185. * @param Number 要显示的数字,范围:0~0xFFFF
    186. * @param Length 要显示数字的长度,范围:1~4
    187. * @retval 无
    188. */
    189. void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
    190. {
    191. unsigned char i,SingleNumber;
    192. LCD_SetCursor(Line,Column);
    193. for(i=Length;i>0;i--)
    194. {
    195. SingleNumber=Number/LCD_Pow(16,i-1)%16;
    196. if(SingleNumber<10)
    197. {
    198. LCD_WriteData(SingleNumber+'0');
    199. }
    200. else
    201. {
    202. LCD_WriteData(SingleNumber-10+'A');
    203. }
    204. }
    205. }
    206. /**
    207. * @brief 在LCD1602指定位置开始以二进制显示所给数字
    208. * @param Line 起始行位置,范围:1~2
    209. * @param Column 起始列位置,范围:1~16
    210. * @param Number 要显示的数字,范围:0~1111 1111 1111 1111
    211. * @param Length 要显示数字的长度,范围:1~16
    212. * @retval 无
    213. */
    214. void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
    215. {
    216. unsigned char i;
    217. LCD_SetCursor(Line,Column);
    218. for(i=Length;i>0;i--)
    219. {
    220. LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
    221. }
    222. }
    223. //***********************************************************************************//********************
    224. //DS1302.h
    225. #ifndef __DS1302_H__
    226. #define __DS1302_H__
    227. char DS1302_data[];
    228. extern unsigned char TimeSetFlashFlag;
    229. void Time_Show();
    230. void LCD_Show();
    231. void LCD_Show_Button();
    232. void DS1302_Init();
    233. void DS1302_WriteByte(unsigned char command,unsigned char Data);
    234. unsigned char DS1302_ReadByte(unsigned char command);
    235. void DS1302_SetTime();
    236. void DS1302_ReadTime();
    237. #endif
    238. //DS1302.c
    239. #include
    240. #include "LCD1602.h"
    241. #include "Key.h"
    242. sbit DS1302_SCLK = P3^6;
    243. sbit DS1302_IO = P3^4;
    244. sbit DS1302_CE = P3^5;
    245. char DS1302_data[] = {21,12,31,23,59,56,2}; //定义年,月,日,时,分,秒,星期
    246. unsigned char TimeSetFlashFlag; //时间设置闪烁标志位。
    247. #define DS1302_sec 0x80 //写地址最后一位为零,如果是读就让它|0x01,在DS1302_ReadByte()中已经置1了,所以不用再定义0x81
    248. #define DS1302_min 0x82
    249. #define DS1302_hour 0x84
    250. #define DS1302_date 0x86 //日期
    251. #define DS1302_mon 0x88
    252. #define DS1302_day 0x8A //星期
    253. #define DS1302_year 0x8C
    254. #define DS1302_wp 0x8E //写保护
    255. /************BCD码转换******************/
    256. //DEC=BCD/16*10+BCD%16
    257. //BCD=DEC/10*16+DEC%10
    258. void DS1302_Init()
    259. {
    260. DS1302_CE = 0;
    261. DS1302_SCLK = 0;
    262. }
    263. void DS1302_WriteByte(unsigned char command,unsigned char Data)
    264. {
    265. // DS1302_CE = 1;
    266. //
    267. // DS1302_IO = command&0x01;
    268. // DS1302_SCLK = 1; //一个上升延写入,
    269. // DS1302_SCLK = 0; //随后又下降,为下一个上升延准备.
    270. //
    271. // DS1302_IO = command&0x02;
    272. // DS1302_SCLK = 1; //一个上升延写入,
    273. // DS1302_SCLK = 0; //随后又下降,为下一个上升延准备.
    274. // . 查DS1302数据手册得知上升下降最小为50ns,结合单片机
    275. // . 执行一条语句的时间为微秒级,所以中间不用延迟.
    276. // .优化如下:
    277. unsigned char i;
    278. DS1302_CE = 1;
    279. for(i=0;i<8;i++)
    280. {
    281. DS1302_IO = command&(0x01<
    282. DS1302_SCLK = 1; //一个上升延写入,
    283. DS1302_SCLK = 0; //随后又下降,为下一个上升延准备.
    284. }
    285. //以上是时序图的前半段,以下是后半段
    286. for(i=0;i<8;i++)
    287. {
    288. DS1302_IO = Data&(0x01<
    289. DS1302_SCLK = 1; //一个上升延写入,
    290. DS1302_SCLK = 0; //随后又下降,为下一个上升延准备.
    291. }
    292. DS1302_CE = 0;
    293. }
    294. unsigned char DS1302_ReadByte(unsigned char command)
    295. {
    296. unsigned char i;
    297. unsigned char Data = 0x00;
    298. command |= 0x01; //读的最低位肯定为1
    299. DS1302_CE = 1;
    300. for(i=0;i<8;i++)
    301. {
    302. DS1302_IO = command&(0x01<
    303. DS1302_SCLK = 0; //先一个下降延,与初始一样,目的是最后一次循环后能落到读数据之前.
    304. DS1302_SCLK = 1; //来一个上升延写入命令.
    305. }
    306. //以上是时序图的前半段,以下是后半段
    307. for(i=0;i<8;i++)
    308. {
    309. DS1302_SCLK = 1; //接着上面重复置1就可以和时序一样.加起来等于15个上升延.
    310. DS1302_SCLK = 0; //下降延读出数据.
    311. if(DS1302_IO)
    312. {
    313. Data |= (0x01<
    314. }
    315. }
    316. DS1302_CE = 0;
    317. DS1302_IO = 0;
    318. return Data;
    319. }
    320. void DS1302_SetTime()
    321. {
    322. DS1302_WriteByte(DS1302_wp,0x00); //关闭写保护
    323. DS1302_WriteByte(DS1302_year,DS1302_data[0]/10*16+DS1302_data[0]%10);
    324. DS1302_WriteByte(DS1302_mon,DS1302_data[1]/10*16+DS1302_data[1]%10);
    325. DS1302_WriteByte(DS1302_date,DS1302_data[2]/10*16+DS1302_data[2]%10);
    326. DS1302_WriteByte(DS1302_hour,DS1302_data[3]/10*16+DS1302_data[3]%10);
    327. DS1302_WriteByte(DS1302_min,DS1302_data[4]/10*16+DS1302_data[4]%10);
    328. DS1302_WriteByte(DS1302_sec,DS1302_data[5]/10*16+DS1302_data[5]%10);
    329. DS1302_WriteByte(DS1302_day,DS1302_data[6]/10*16+DS1302_data[6]%10);
    330. DS1302_WriteByte(DS1302_wp,0x80); //打开写保护
    331. }
    332. void DS1302_ReadTime()
    333. {
    334. unsigned char tmp;
    335. tmp = DS1302_ReadByte(DS1302_year);
    336. DS1302_data[0] = tmp/16*10+tmp%16;
    337. tmp = DS1302_ReadByte(DS1302_mon);
    338. DS1302_data[1] = tmp/16*10+tmp%16;
    339. tmp = DS1302_ReadByte(DS1302_date);
    340. DS1302_data[2] = tmp/16*10+tmp%16;
    341. tmp = DS1302_ReadByte(DS1302_hour);
    342. DS1302_data[3] = tmp/16*10+tmp%16;
    343. tmp = DS1302_ReadByte(DS1302_min);
    344. DS1302_data[4] = tmp/16*10+tmp%16;
    345. tmp = DS1302_ReadByte(DS1302_sec);
    346. DS1302_data[5] = tmp/16*10+tmp%16;
    347. tmp = DS1302_ReadByte(DS1302_day);
    348. DS1302_data[6] = tmp/16*10+tmp%16;
    349. }
    350. void LCD_Show_Button() //设置时数字闪烁
    351. {
    352. if(index==0 && TimeSetFlashFlag==1)
    353. {
    354. LCD_ShowString(1,1," ");
    355. }
    356. else
    357. {
    358. LCD_ShowNum(1,1,DS1302_data[0],2);
    359. }
    360. if(index==1 && TimeSetFlashFlag==1)
    361. {
    362. LCD_ShowString(1,4," ");
    363. }
    364. else
    365. {
    366. LCD_ShowNum(1,4,DS1302_data[1],2);
    367. }
    368. if(index==2 && TimeSetFlashFlag==1)
    369. {
    370. LCD_ShowString(1,7," ");
    371. }
    372. else
    373. {
    374. LCD_ShowNum(1,7,DS1302_data[2],2);
    375. }
    376. if(index==3 && TimeSetFlashFlag==1)
    377. {
    378. LCD_ShowString(2,1," ");
    379. }
    380. else
    381. {
    382. LCD_ShowNum(2,1,DS1302_data[3],2);
    383. }
    384. if(index==4 && TimeSetFlashFlag==1)
    385. {
    386. LCD_ShowString(2,4," ");
    387. }
    388. else
    389. {
    390. LCD_ShowNum(2,4,DS1302_data[4],2);
    391. }
    392. if(index==5 && TimeSetFlashFlag==1)
    393. {
    394. LCD_ShowString(2,7," ");
    395. }
    396. else
    397. {
    398. LCD_ShowNum(2,7,DS1302_data[5],2);
    399. }
    400. }
    401. void LCD_Show()
    402. {
    403. LCD_ShowNum(1,1,DS1302_data[0],2);
    404. LCD_ShowNum(1,4,DS1302_data[1],2);
    405. LCD_ShowNum(1,7,DS1302_data[2],2);
    406. LCD_ShowNum(2,1,DS1302_data[3],2);
    407. LCD_ShowNum(2,4,DS1302_data[4],2);
    408. LCD_ShowNum(2,7,DS1302_data[5],2);
    409. }
    410. void Time_Show()
    411. {
    412. DS1302_ReadTime(); //读取时间.
    413. LCD_Show();
    414. }
    415. //***********************************************************************************//********************************
    416. //key.h
    417. #ifndef __KEY_H_
    418. #define __KEY_H_
    419. extern unsigned char MODE;
    420. extern unsigned char KeySta[4][4];
    421. extern unsigned long pdata KeyDownTime[4][4];
    422. extern unsigned char index;
    423. void KeyAction(unsigned char keycode);
    424. void KeyDriver();
    425. void KeyScan();
    426. #endif
    427. key.c
    428. #include "LCD1602.H"
    429. #include
    430. #include "DS1302.H"
    431. unsigned char MODE = 0;
    432. unsigned char index = 0;
    433. unsigned char KeySta[4][4] = {{1,1,1,1},
    434. {1,1,1,1},
    435. {1,1,1,1},
    436. {1,1,1,1}
    437. };
    438. unsigned char code KeyCodeMap[4][4]={
    439. {0x31,0x32,0x33,0x26}, //数字键1,数字键2,数字键3,向上键
    440. {0x34,0x35,0x36,0x25}, //数字键4,数字键5,数字键6,向左键
    441. {0x37,0x38,0x39,0x28}, //数字键7,数字键8,数字键9,向下键
    442. {0x30,0x1B,0x0D,0x27} //数字键0,Esc键,回车键,向右键
    443. };
    444. unsigned long pdata KeyDownTime[4][4] = {
    445. {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}
    446. };
    447. void KeyAction(unsigned char keycode)
    448. {
    449. if((keycode>=0x30)&&(keycode<=0x39)) //如果是数字0~9
    450. {
    451. }
    452. else if(keycode==0x25) //向左 ,设为切换模式
    453. {
    454. MODE = !MODE;
    455. }
    456. else if(keycode==0x26) //如果是向上键 ,加
    457. {
    458. DS1302_data[index]++;
    459. if(DS1302_data[0]>99){DS1302_data[0]=0;}//年越界判断
    460. if(DS1302_data[1]>12){DS1302_data[1]=1;}//月越界判断
    461. if( DS1302_data[1]==1 || DS1302_data[1]==3 || DS1302_data[1]==5 || DS1302_data[1]==7 ||
    462. DS1302_data[1]==8 || DS1302_data[1]==10 || DS1302_data[1]==12)//日越界判断
    463. {
    464. if(DS1302_data[2]>31){DS1302_data[2]=1;}//大月
    465. }
    466. else if(DS1302_data[1]==4 || DS1302_data[1]==6 || DS1302_data[1]==9 || DS1302_data[1]==11)
    467. {
    468. if(DS1302_data[2]>30){DS1302_data[2]=1;}//小月
    469. }
    470. else if(DS1302_data[1]==2)
    471. {
    472. if(DS1302_data[0]%4==0)
    473. {
    474. if(DS1302_data[2]>29){DS1302_data[2]=1;}//闰年2月
    475. }
    476. else
    477. {
    478. if(DS1302_data[2]>28){DS1302_data[2]=1;}//平年2月
    479. }
    480. }
    481. if(DS1302_data[3]>23){DS1302_data[3]=0;}//时越界判断
    482. if(DS1302_data[4]>59){DS1302_data[4]=0;}//分越界判断
    483. if(DS1302_data[5]>59){DS1302_data[5]=0;}//秒越界判断
    484. }
    485. else if(keycode==0x27) //如果是向右键 ,切换时间数组索引
    486. {
    487. index++;
    488. index %= 6;
    489. }
    490. else if(keycode==0x28)//如果是向下键,减
    491. {
    492. DS1302_data[index]--;
    493. if(DS1302_data[0]<0){DS1302_data[0]=99;}//年越界判断
    494. if(DS1302_data[1]<1){DS1302_data[1]=12;}//月越界判断
    495. if( DS1302_data[1]==1 || DS1302_data[1]==3 || DS1302_data[1]==5 || DS1302_data[1]==7 ||
    496. DS1302_data[1]==8 || DS1302_data[1]==10 || DS1302_data[1]==12)//日越界判断
    497. {
    498. if(DS1302_data[2]<1){DS1302_data[2]=31;}//大月
    499. if(DS1302_data[2]>31){DS1302_data[2]=1;}
    500. }
    501. else if(DS1302_data[1]==4 || DS1302_data[1]==6 || DS1302_data[1]==9 || DS1302_data[1]==11)
    502. {
    503. if(DS1302_data[2]<1){DS1302_data[2]=30;}//小月
    504. if(DS1302_data[2]>30){DS1302_data[2]=1;}
    505. }
    506. else if(DS1302_data[1]==2)
    507. {
    508. if(DS1302_data[0]%4==0)
    509. {
    510. if(DS1302_data[2]<1){DS1302_data[2]=29;}//闰年2月
    511. if(DS1302_data[2]>29){DS1302_data[2]=1;}
    512. }
    513. else
    514. {
    515. if(DS1302_data[2]<1){DS1302_data[2]=28;}//平年2月
    516. if(DS1302_data[2]>28){DS1302_data[2]=1;}
    517. }
    518. }
    519. if(DS1302_data[3]<0){DS1302_data[3]=23;}//时越界判断
    520. if(DS1302_data[4]<0){DS1302_data[4]=59;}//分越界判断
    521. if(DS1302_data[5]<0){DS1302_data[5]=59;}//秒越界判断
    522. }
    523. else if(keycode==0x1B) //如果是回车键
    524. {
    525. }
    526. }
    527. void KeyDriver()
    528. {
    529. static unsigned char backup[4][4] = { {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
    530. unsigned char i,j;
    531. static unsigned long pdata TimeAdd[4][4] = {
    532. {1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000}
    533. };
    534. for(i=0;i<4;i++)
    535. {
    536. for(j=0;j<4;j++)
    537. {
    538. if(backup[i][j] != KeySta[i][j])
    539. {
    540. if(backup[i][j] == 0)
    541. {
    542. KeyAction(KeyCodeMap[i][j]);
    543. }
    544. backup[i][j] = KeySta[i][j];
    545. }
    546. if(KeyDownTime[i][j] > 0)
    547. { //LCD_ShowNum(1,5,KeyDownTime[i][j],5);
    548. if(KeyDownTime[i][j] >= TimeAdd[i][j])
    549. { //LCD_ShowNum(2,8,KeyDownTime[i][j],5);
    550. KeyAction(KeyCodeMap[i][j]);
    551. TimeAdd[i][j] += 80; //设置长按时跳动的速度,越小越快
    552. }
    553. }
    554. else
    555. TimeAdd[i][j] = 1000;
    556. }
    557. }
    558. }
    559. void KeyScan()
    560. {
    561. static unsigned char keyout = 0;
    562. unsigned char i = 0;
    563. static unsigned char keybuf[4][4] = {{0xFF,0xFF,0xFF,0xFF},
    564. {0xFF,0xFF,0xFF,0xFF},
    565. {0xFF,0xFF,0xFF,0xFF},
    566. {0xFF,0xFF,0xFF,0xFF}
    567. };
    568. keybuf[keyout][0] = (keybuf[keyout][0]<<1) | P14; //所以每行要左移8次,4行就左移32次,32毫秒就能跳出抖动
    569. keybuf[keyout][1] = (keybuf[keyout][1]<<1) | P15;
    570. keybuf[keyout][2] = (keybuf[keyout][2]<<1) | P16;
    571. keybuf[keyout][3] = (keybuf[keyout][3]<<1) | P17;
    572. for(i=0;i<4;i++)
    573. {
    574. if((keybuf[keyout][i] & 0xFF) == 0x00) //0x00表示后8位为0就判断为0,因为初始值
    575. { //为0xFF,所以至少要进入8次中断,左移8次
    576. KeySta[keyout][i] = 0; //与0xFF才可能等于0x00
    577. KeyDownTime[keyout][i] += 4; //所以这这里要加上4毫秒。
    578. }
    579. else if((keybuf[keyout][i] & 0xFF) == 0xFF) //0xFF表示8位为1就判断为1
    580. {
    581. KeySta[keyout][i] = 1;
    582. KeyDownTime[keyout][i] = 0;
    583. }
    584. }
    585. keyout++;
    586. // if(keyout>=3)
    587. // {
    588. // keyout = 0;
    589. // }
    590. keyout &= 0x03;
    591. switch(keyout)
    592. {
    593. //case 0: P00=1;P01=1;P02=1;P03=0;break;
    594. //case 1: P00=1;P01=1;P02=0;P03=1;break;
    595. //case 2: P00=1;P01=0;P02=1;P03=1;break;
    596. //case 3: P00=0;P01=1;P02=1;P03=1;break;
    597. //优化后如下:
    598. case 0: P10=1;P13=0; break;
    599. case 1: P13=1;P12=0; break;
    600. case 2: P12=1;P11=0; break;
    601. case 3: P11=1;P10=0; break;
    602. default: break;
    603. }
    604. }
    605. //***********************************************************************************//***********
    606. mani.c
    607. #include
    608. #include "LCD1602.h"
    609. #include "DS1302.h"
    610. #include "Key.h"
    611. void main()
    612. {
    613. TMOD &= 0xF0; //设置定时器模式
    614. TMOD |= 0x01; //设置定时器模式
    615. TL0 = 0x18; //设置定时初值,1毫秒@12.000MHz
    616. TH0 = 0xFC; //设置定时初值
    617. TF0 = 0; //清除TF0标志
    618. TR0 = 1; //定时器0开始计时
    619. EA = 1;
    620. ET0 = 1;
    621. LCD_Init();
    622. DS1302_Init();
    623. LCD_ShowString(1,1," - -");
    624. LCD_ShowString(2,1," : :");
    625. DS1302_SetTime(); //设置时间,用数组里面的数值设置
    626. while(1)
    627. {
    628. KeyDriver();
    629. switch(MODE)
    630. {
    631. case 0 : Time_Show(); break;
    632. case 1 : DS1302_SetTime();LCD_Show_Button(); break;
    633. }
    634. }
    635. }
    636. void InterruptTimer0() interrupt 1
    637. {
    638. static unsigned int T0_Count = 0;
    639. TL0 = 0x18;
    640. TH0 = 0xFC;
    641. T0_Count++;
    642. if(T0_Count==500)
    643. {
    644. T0_Count = 0;
    645. TimeSetFlashFlag = !TimeSetFlashFlag;
    646. }
    647. KeyScan();
    648. }

     

  • 相关阅读:
    速领!最新最全的C6678+Kintex-7视频/高速AD开发案例合集来了,附上源码!
    2023.10.21 关于 阻塞队列
    H5页面获取用户位置信息方案及测试流程
    栈和队列(详解)
    ThreadLocal详解
    centos8安装mysql报错
    Linux常见的文件系统
    阿里云消息团队创新论文被软件工程顶会 FM 2024 录用
    02 数学软件与建模---MATLAB入门
    opencv之VideoCapture与VideoWriter笔记
  • 原文地址:https://blog.csdn.net/asty008/article/details/126447813