找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4681|回复: 4
打印 上一主题 下一主题
收起左侧

使用DS1302的时钟单片机程序 Lcd1602液晶显示

[复制链接]
跳转到指定楼层
楼主
附件和图发:


51单片机源程序:
  1. #include<reg52.h>

  2. struct sTime{  //日期时间结构体申明
  3.         unsigned int year;
  4.         unsigned char mon;
  5.         unsigned char day;
  6.         unsigned char hour;
  7.         unsigned char min;
  8.         unsigned char sec;
  9.         unsigned char week;
  10. };

  11. bit flag200ms = 1;         //200ms 定时标志
  12. struct sTime bufTime; //日期时间缓冲区
  13. unsigned char setIndex = 0;        //时间设置索引 0 0 就表示正常运行,
  14. unsigned char T0RH, T0RL;

  15. void RefreshTimeShow();
  16. void ConfigTimer0(unsigned int ms);
  17. extern void KeyScan();
  18. extern void KeyDriver();
  19. extern void InitLcd1602();
  20. extern void LcdOpenCursor();
  21. extern void LcdCloseCursor();
  22. extern void LcdSetCursor(unsigned char x, unsigned char y);
  23. extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
  24. extern void InitDS1302();
  25. extern void SetRealTime(struct sTime *time);
  26. extern void GetRealTime(struct sTime *time);

  27. void main()
  28. {
  29.         unsigned char psec = 0xaa;        //秒备份,初值 AA 确保首次读取时间后刷新显示

  30.         EA = 1;
  31.         ConfigTimer0(1);
  32.         InitLcd1602();
  33.         InitDS1302();
  34.         LcdShowStr(0, 0, "20  -  -   Week "); //初始化屏幕上固定不变的内容
  35.         LcdShowStr(4, 1, "  :  :  ");

  36.         while(1)
  37.         {
  38.                 KeyDriver();         //调用按键驱动
  39.                 if(flag200ms && (setIndex == 0))
  40.                 {                                                                 
  41.                         flag200ms = 0;                                 //每隔200ms且未处于设置状态时,
  42.                         GetRealTime(&bufTime);             //获取当前时间
  43.                         if(psec != bufTime.sec)                 //检测到时间有变化时刷新显示
  44.                         {
  45.                                 RefreshTimeShow();
  46.                                 psec = bufTime.sec;                //用当前值更新上次秒数
  47.                         }        
  48.                 }
  49.         }
  50. }
  51. /* 将一个BCD码字节显示到屏幕上,(x,y)-屏幕起始坐标,bcd-待显示BCD码 */
  52. void ShowBCDByte(unsigned char x, unsigned char y, unsigned char bcd)
  53. {
  54.         unsigned char str[4];

  55.         str[0] = (bcd >> 4) + '0';
  56.         str[1] = (bcd & 0x0f) + '0';
  57.         str[2] = '\0';
  58.         LcdShowStr(x, y, str);
  59. }

  60. void ShowBCDWeek(unsigned char x, unsigned char y, unsigned char bcd)
  61. {
  62.         unsigned char str[3];

  63.         str[0] = (bcd & 0x0f) + '0';
  64.         str[1] = '\0';
  65.         LcdShowStr(x, y, str);
  66. }
  67. /* 刷新日期时间的显示         */
  68. void RefreshTimeShow()
  69. {
  70.         ShowBCDByte(2, 0, bufTime.year);
  71.         ShowBCDByte(5, 0, bufTime.mon);
  72.         ShowBCDByte(8, 0, bufTime.day);
  73.         ShowBCDByte(4, 1, bufTime.hour);
  74.         ShowBCDByte(7, 1, bufTime.min);
  75.         ShowBCDByte(10, 1, bufTime.sec);
  76.         ShowBCDWeek(15, 0, bufTime.week);               
  77. }
  78. /* 刷新当前设置位的光标指示    */
  79. void RefreshSetCursorShow()
  80. {
  81.         switch(setIndex)
  82.         {
  83.                 case 1: LcdSetCursor(2, 0); break;
  84.                 case 2: LcdSetCursor(3, 0); break;
  85.                 case 3: LcdSetCursor(5, 0); break;
  86.                 case 4: LcdSetCursor(6, 0); break;
  87.                 case 5: LcdSetCursor(8, 0); break;
  88.                 case 6: LcdSetCursor(9, 0); break;
  89.                 case 7: LcdSetCursor(4, 1); break;
  90.                 case 8: LcdSetCursor(5, 1); break;
  91.                 case 9: LcdSetCursor(7, 1); break;
  92.                 case 10: LcdSetCursor(8, 1); break;
  93.                 case 11: LcdSetCursor(15, 0); break;
  94.                 default: break;
  95.         }
  96. }        

  97. unsigned char DecrBCDHight(unsigned char bcd)
  98. {


  99.         if((bcd & 0xf0) > 0x00)
  100.         {
  101.                 bcd -= 0x10;
  102.         }
  103.         else
  104.         {
  105.                 if(setIndex == 1)
  106.                         bcd        |= 0x90;
  107.                 else if(setIndex == 3)
  108.                         bcd |= 0x10;
  109.                 else if(setIndex == 5)
  110.                         bcd |= 0x30;
  111.                 else if(setIndex == 7)
  112.                         bcd |= 0x20;
  113.                 else if((setIndex == 9))
  114.                         bcd |= 0x60;
  115.         }
  116.         
  117.         return bcd;
  118. }

  119. unsigned char DecrBCDLow(unsigned char bcd)
  120. {


  121.         if((bcd & 0x0f) > 0x00)
  122.         {
  123.                 bcd -= 0x01;
  124.         }
  125.         else if(setIndex == 11)
  126.         {
  127.                 bcd |= 0x07;
  128.         }
  129.         else
  130.         {
  131.                 bcd        |= 0x09;
  132.         }
  133.         
  134.         return bcd;
  135. }

  136. unsigned char IncrBCDHight(unsigned char bcd)
  137. {
  138.         if((setIndex == 1)&&((bcd & 0xf0)< 0x90))
  139.         {
  140.                         bcd += 0x10;
  141.         }
  142.         else if((setIndex == 3)&&(bcd < 0x10))
  143.         {
  144.                         bcd +=0x10;
  145.         }
  146.         else if((setIndex == 5)&&(bcd < 0x30))
  147.         {
  148.                         bcd += 0x10;
  149.         }
  150.         else if((setIndex == 7)&&(bcd < 0x20))
  151.         {
  152.                         bcd += 0x10;
  153.         }
  154.         else if(setIndex == 9)
  155.         {
  156.                         bcd += 0x10;
  157.         }                                   
  158.         else if(setIndex == 11)
  159.         {
  160.                 if(bcd < 0x07)
  161.                 {
  162.                         bcd++;
  163.                 }
  164.                 else
  165.                 {
  166.                         bcd = 0x01;
  167.                 }
  168.         }
  169.         else
  170.         {
  171.                 bcd        &= 0x0f;
  172.         }
  173.         
  174.         return bcd;
  175. }

  176. unsigned char IncrBCDLow(unsigned char bcd)
  177. {
  178.     if(setIndex != 11)
  179.         {
  180.                 if ((bcd&0x0F) < 0x09)
  181.                 bcd += 0x01;
  182.             else
  183.                 bcd &= 0xF0;
  184.         }
  185.         else
  186.         {
  187.                 if ((bcd&0x0F) < 0x07)
  188.                 bcd += 0x01;
  189.             else
  190.                 bcd &= 0x01;
  191.         }
  192.    
  193.     return bcd;
  194. }
  195. /* 递增当前设置位的值          */
  196. void IncrSetTime()
  197. {
  198.         switch(setIndex)
  199.         {
  200.                 case 1: bufTime.year = IncrBCDHight(bufTime.year); break;
  201.                 case 2: bufTime.year = IncrBCDLow(bufTime.year); break;
  202.                 case 3:        bufTime.mon = IncrBCDHight(bufTime.mon); break;
  203.                 case 4:        bufTime.mon = IncrBCDLow(bufTime.mon); break;
  204.                 case 5: bufTime.day = IncrBCDHight(bufTime.day); break;
  205.                 case 6:        bufTime.day = IncrBCDLow(bufTime.day); break;
  206.                 case 7: bufTime.hour = IncrBCDHight(bufTime.hour); break;
  207.                 case 8:        bufTime.hour = IncrBCDLow(bufTime.hour); break;
  208.                 case 9: bufTime.min = IncrBCDHight(bufTime.min); break;
  209.                 case 10: bufTime.min = IncrBCDLow(bufTime.min); break;
  210.                 case 11: bufTime.week = IncrBCDLow(bufTime.week); break;
  211.                 default: break;
  212.         }
  213.         RefreshTimeShow();
  214.         RefreshSetCursorShow();
  215. }
  216. /* 递减当前设置位的值           */
  217. void DecrSetTime()
  218. {
  219.         switch(setIndex)
  220.         {
  221.                 case 1: bufTime.year = DecrBCDHight(bufTime.year); break;
  222.                 case 2: bufTime.year = DecrBCDLow(bufTime.year); break;
  223.                 case 3:        bufTime.mon = DecrBCDHight(bufTime.mon); break;
  224.                 case 4:        bufTime.mon = DecrBCDLow(bufTime.mon); break;
  225.                 case 5: bufTime.day = DecrBCDHight(bufTime.day); break;
  226.                 case 6:        bufTime.day = DecrBCDLow(bufTime.day); break;
  227.                 case 7: bufTime.hour = DecrBCDHight(bufTime.hour); break;
  228.                 case 8:        bufTime.hour = DecrBCDLow(bufTime.hour); break;
  229.                 case 9: bufTime.min = DecrBCDHight(bufTime.min); break;
  230.                 case 10: bufTime.min = DecrBCDLow(bufTime.min); break;
  231.                 case 11: bufTime.week = DecrBCDLow(bufTime.week); break;
  232.                 default: break;
  233.         }
  234.         RefreshTimeShow();
  235.         RefreshSetCursorShow();
  236. }
  237. /* 左移设置位         */
  238. void LeftShiftTimeSet()
  239. {
  240.         if(setIndex != 0)
  241.         {
  242.                 if(setIndex > 1)
  243.                         setIndex--;
  244.                 else
  245.                         setIndex = 11;
  246.                 RefreshSetCursorShow();
  247.         }
  248. }
  249. /* 右移设置位           */
  250. void RightShifTimeSet()
  251. {
  252.         if(setIndex != 0)
  253.         {
  254.                 if(setIndex < 11)
  255.                         setIndex++;
  256.                 else
  257.                         setIndex = 1;
  258.                 RefreshSetCursorShow();        
  259.         }
  260. }
  261. /* 进入设置状态         */
  262. void EnterTimeSet()
  263. {
  264.         setIndex = 2;          //把设置索引设置为2,即可进入设置状态
  265.         LeftShiftTimeSet(); //再利用现成的左移操作移到位置1并完成显示刷新
  266.         LcdOpenCursor();   //打开光标闪烁效果
  267. }
  268. /* 退出设置状态,save-是否保存当前设置的时间值         */
  269. void ExitTimeSet(bit save) //save = 1 保存,save = 0 不保存
  270. {
  271.         setIndex = 0;           //把设置索引设置为0,即可退出设置状态
  272.         if(save)                   //需保存时即把当前设置时间写入DS1302
  273.                 SetRealTime(&bufTime);
  274.         LcdCloseCursor();        //关闭光标显示
  275. }
  276. /* 按键动作函数,根据键码执行相应的操作,keycode-按键键码 */
  277. void KeyAction(unsigned char keycode)
  278. {
  279.         if((keycode >= '0')&&(keycode <= '9'))//不响应字符键
  280.         {}
  281.         else if((keycode == 0x26)) //向上键,递增当前设置位的值
  282.         {
  283.                 IncrSetTime();
  284.         }
  285.         else if(keycode == 0x28)          //向下键,递减当前设置位的值
  286.         {
  287.                 DecrSetTime();
  288.         }
  289.         else if(keycode == 0x25)        //向左键,向左切换设置位
  290.         {
  291.                 LeftShiftTimeSet();
  292.         }
  293.         else if(keycode == 0x27)   //向右键,向右切换设置位
  294.         {
  295.                 RightShifTimeSet();
  296.         }
  297.         else if(keycode == 0x0d)  //回车键,进入设置模式/启用当前设置值
  298.         {
  299.                 if(setIndex == 0)         //不处于设置状态时,进入设置状态
  300.                 {
  301.                         EnterTimeSet();
  302.                 }
  303.                 else                        //已处于设置状态时,保存时间并退出设置状态
  304.                 {
  305.                         ExitTimeSet(1);
  306.                 }
  307.         }
  308.         else if(keycode == 0x1b) //Esc键,取消当前设置
  309.         {
  310.                 ExitTimeSet(0);
  311.         }
  312. }                           

  313. void ConfigTimer0(unsigned int ms)
  314. {
  315.         unsigned long tmp;

  316.         tmp = 11059200 / 12;
  317.         tmp = tmp * ms / 1000;
  318.         tmp = 65536 - tmp;
  319.         tmp = tmp + 28;
  320.         T0RH = (unsigned char)(tmp >> 8);
  321.         T0RL = (unsigned char)tmp;
  322.         TMOD = (TMOD & 0xf0)|0x01;
  323.         TH0 = T0RH;
  324.         TL0 = T0RL;
  325.         ET0 = 1;
  326.         TR0 = 1;
  327. }

  328. void IntTimer0() interrupt 1
  329. {
  330.         static unsigned char tmr200ms = 0;

  331.         TH0 = T0RH;
  332.         TL0 = T0RL;

  333.         KeyScan();
  334.         tmr200ms++;
  335.         if(tmr200ms >= 200)
  336.         {
  337.                 tmr200ms = 0;
  338.                 flag200ms = 1;
  339.         }
  340. }


复制代码


下载:
时钟.rar (4.99 KB, 下载次数: 37)



评分

参与人数 2黑币 +115 收起 理由
JACKLI + 15 共享资料的黑币奖励!
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:308395 发表于 2018-4-26 16:37 | 只看该作者
没有仿真,不知程序怎样,没看
回复

使用道具 举报

板凳
ID:223788 发表于 2018-5-8 20:42 | 只看该作者
试了一下,效果还不错,不过调日期的时候有一个小 bug ,但不影响使用。
回复

使用道具 举报

地板
ID:359743 发表于 2018-6-26 21:51 | 只看该作者
这个有仿真图吗?我不知道怎么连线。
求楼主联系qq 1575817894
可以给点好处
回复

使用道具 举报

5#
ID:359743 发表于 2018-6-26 21:52 | 只看该作者
JACKLI 发表于 2018-5-8 20:42
试了一下,效果还不错,不过调日期的时候有一个小 bug ,但不影响使用。

大神,这个仿真电路图怎么弄啊?
1575817894 我的qq
求联系
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表