找回密码
 立即注册

QQ登录

只需一步,快速开始

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

采用DS12CR887时钟芯片驱动的51单片机数字时钟,lcd1602显示

[复制链接]
跳转到指定楼层
楼主
基于51单片机数字时钟,网上一般都是用51单片机+ds1302做的精度没有我这个好,这次是采用DS12CR887时钟芯片,1602液晶显示,经过本人测试成功.特发布在51黑电子论坛.

完整源码下载: 51-clock.rar (75.05 KB, 下载次数: 37)



DS12CR887的驱动程序:
  1. /*
  2. * RTC.c
  3. *
  4. * Created: 12/3
  5. * Author: 詹磊
  6. */
  7. #include"File_h\main.h"
  8. #include"File_h\LCD1602.h"
  9. #include"File_h\key.h"
  10. #include"File_h\RTC.h"
  11. //-------------------------------------------//
  12. //函数名:写DS12CR887数据函数
  13. //入口:Addre:所写数据的地址
  14. //                Data:需要写入的数据
  15. //出口:Void
  16. //功能:写DS12CR887内数据
  17. //-------------------------------------------//
  18. void WriteDS12CR887(unsigned char Addre,unsigned char Data)
  19. {
  20.         DS12CR887_DS=1;
  21.         DS12CR887_RW=1;
  22.         DS12CR887_AS=1;
  23.         DS12CR887_DataPutIO=Addre;
  24.         DS12CR887_CS=0;               
  25.         DS12CR887_AS=0;
  26.         DS12CR887_DataPutIO=Data;
  27.         DS12CR887_RW=0;
  28.         DS12CR887_RW=1;
  29.         DS12CR887_CS=1;
  30.         DS12CR887_AS=1;
  31. }
  32. //-------------------------------------------//
  33. //函数名:读DS12CR887数据函数
  34. //入口:Addre:所读数据的地址
  35. //出口:unsigned char :所读出的数据
  36. //功能:读DS12CR887内数据
  37. //-------------------------------------------//
  38. unsigned char ReadDS12CR887(unsigned char Addre)
  39. {
  40.          unsigned char ds_date;
  41.         DS12CR887_RW=1;                           
  42.         DS12CR887_DS=1;
  43.         DS12CR887_AS=1;        
  44.         DS12CR887_DataPutIO=Addre;
  45.         DS12CR887_CS=0;
  46.         DS12CR887_AS=0;
  47.         DS12CR887_DataPutIO=0xff;
  48.         DS12CR887_DS=0;
  49.         ds_date=DS12CR887_DataPutIO;
  50.         DS12CR887_DS=1;
  51.         DS12CR887_CS=1;
  52.         DS12CR887_AS=1;
  53.         return ds_date;        
  54. }
  55. //-------------------------------------------//
  56. //函数名:时钟芯片始化
  57. //入口:Void
  58. //出口:Void
  59. //功能:配置相关寄存器等
  60. //-------------------------------------------//
  61. void RTC_Init()
  62. {        
  63.         /*
  64.         WriteDS12CR887(0x00,0x57);
  65.         WriteDS12CR887(0x02,0x59);
  66.         WriteDS12CR887(0x04,0x23);
  67.         WriteDS12CR887(0x06,0x07);
  68.         WriteDS12CR887(0x07,0x30);
  69.         WriteDS12CR887(0x08,0x12);
  70.         WriteDS12CR887(0x09,0x01);
  71.         */
  72.         ///*
  73.         WriteDS12CR887(0x00,57);
  74.         WriteDS12CR887(0x02,59);
  75.         WriteDS12CR887(0x04,23);
  76.         WriteDS12CR887(0x06,07);
  77.         WriteDS12CR887(0x07,30);
  78.         WriteDS12CR887(0x08,12);
  79.         WriteDS12CR887(0x09,01);
  80.         //*/
  81.         WriteDS12CR887(0x0A,0x20);
  82.         WriteDS12CR887(0x0B,0x06);
  83. }
  84. //-------------------------------------------//
  85. //函数名:读时钟数据函数
  86. //入口:*tp:所读时间数据的结构体指针
  87. //                *dp:所读日期数据的结构体指针
  88. //出口:Void
  89. //功能:读时钟数据
  90. //-------------------------------------------//
  91. void GetRTC_Data(TimeData *tp,DateData *dp)
  92. {        
  93.         tp->second=ReadDS12CR887(0x00);
  94.         tp->minute=ReadDS12CR887(0x02);
  95.         tp->hour=ReadDS12CR887(0x04);
  96.         dp->day=ReadDS12CR887(0x06);
  97.         dp->date=ReadDS12CR887(0x07);
  98.         dp->month=ReadDS12CR887(0x08);
  99.         dp->year=ReadDS12CR887(0x09);
  100. }
  101. //-------------------------------------------//
  102. //函数名:调时间数据函数
  103. //入口:*tp:所写时间数据的结构体指针
  104. //出口:Void
  105. //功能:调时间数据
  106. //-------------------------------------------//
  107. void WriteRTC_TimeData(TimeData *tp)
  108. {
  109.         WriteDS12CR887(0x00,tp->second);
  110.         WriteDS12CR887(0x02,tp->minute);
  111.         WriteDS12CR887(0x04,tp->hour);
  112. }
  113. //-------------------------------------------//
  114. //函数名:调日期数据函数
  115. //入口:*dp:所写日期数据的结构体指针
  116. //出口:Void
  117. //功能:调日期数据
  118. //-------------------------------------------//
  119. void WriteRTC_DateData(DateData *dp)
  120. {
  121.         WriteDS12CR887(0x06,dp->day);
  122.         WriteDS12CR887(0x07,dp->date);
  123.         WriteDS12CR887(0x08,dp->month);
  124.         WriteDS12CR887(0x09,dp->year);
  125. }
  126. //-------------------------------------------//
  127. //函数名:调闹钟数据函数
  128. //入口:*atp:所写闹钟数据的结构体指针
  129. //出口:Void
  130. //功能:调闹钟数据
  131. //-------------------------------------------//
  132. void WriteRTC_AlarmData(TimeData *atp)
  133. {
  134.         WriteDS12CR887(0x01,atp->second);
  135.         WriteDS12CR887(0x03,atp->minute);
  136.         WriteDS12CR887(0x05,atp->hour);
  137. }
复制代码


按键驱动程序:
  1. /*
  2. * key.c
  3. *
  4. * Created: 12/3
  5. * Author: 詹磊
  6. */
  7. #include"File_h\main.h"
  8. #include"File_h\LCD1602.h"
  9. #include"File_h\key.h"
  10. #include"File_h\RTC.h"
  11. //-------------------------------------------//
  12. bit KEY_flag=0;
  13. bit LongKEY_flag=0,LongKEY_START=1;
  14. unsigned char KeyBuffer[KeyBufferSize]={0,0,0,0};                //键盘缓存区数组
  15. unsigned char KeyIndexW=0;                                                                //键盘缓存队列写入指针
  16. unsigned char KeyIndexR=0;                                                                //键盘缓存队列读取指针
  17. unsigned char KeyCount=0;                                                                //键盘缓存队列内记录的按键次数
  18. //-------------------------------------------//
  19. //函数名:按键始化
  20. //入口:Void
  21. //出口:Void
  22. //功能:配置按键IO口模式等
  23. //-------------------------------------------//
  24. void InitKey()
  25. {
  26.         KEYControl|=KEYFullValue;
  27. }
  28. //-------------------------------------------//
  29. //函数名:按键压栈函数
  30. //入口:Key:需要压入按键缓存的键值
  31. //出口:Void
  32. //功能:将一次键值压入按键缓存中
  33. //-------------------------------------------//
  34. void KeyInBuffer(unsigned char Key)
  35. {
  36.         bit tempEA;
  37.         if(KeyCount>=KeyBufferSize)                                                        //缓存已满,放弃本次按键
  38.                 return;
  39.         tempEA=EA;
  40.         EA=0;                                                                                                //涉及共享数据,关中断
  41.         KeyCount++;
  42.         KeyBuffer[KeyIndexW]=Key;
  43.         if(++KeyIndexW>=KeyBufferSize)                                                //如果队列头指针越界,循环队列
  44.                 KeyIndexW=0;
  45.         EA=tempEA;                                                                                        //开中断
  46. }
  47. //-------------------------------------------//
  48. //函数名:按键出栈函数
  49. //入口:Void
  50. //出口:unsigned char 返回键值
  51. //功能:从键盘缓存中读取一次键值,调用一次会把按键缓存中所调用的那个按键的键值删除
  52. //-------------------------------------------//
  53. unsigned char GetKey()
  54. {
  55.         uchar Key;
  56.         bit tempEA;
  57.         if(KeyCount==0)
  58.                 return 0;
  59.         tempEA=EA;
  60.         EA=0;                                                                                                //涉及共享数据,关中断
  61.         KeyCount--;
  62.         Key=KeyBuffer[KeyIndexR];
  63.         if(++KeyIndexR>=KeyBufferSize)                                                //如果队列头指针越界,循环队列
  64.                 KeyIndexR=0;
  65.         EA=tempEA;                                                                                        //开中断
  66.         return Key;
  67. }
  68. //-------------------------------------------//
  69. //函数名:按键扫描函数
  70. //入口:Void
  71. //出口:Void
  72. //功能:扫描IO口按键输入情况,如果有按键事件,那么就保存键值到按键堆栈区中
  73. //-------------------------------------------//
  74. void CheckKey()
  75. {
  76.         static unsigned char KeyTemp,KeyStateTime;
  77.         unsigned int temp;
  78.         unsigned char timeTemp;
  79.         if((TestKey!=KEYFullValue)&&(KEY_flag!=1))                        //查询是否有按键按下
  80.         {               
  81.                 for(temp=KeyDelayTime;temp>0;temp--)                        //延时消抖
  82.                         if(TestKey==KEYFullValue)
  83.                                 return;
  84.                 if(TestKey!=KEYFullValue)                                                //消抖后检测按键是否还按下;如果是,
  85.                                                                                                                 //则说明是有效按键;如果不是,
  86.                                                                                                                 //则认为抖动
  87.                 {
  88.                         LongKEY_START=1;                                                        //长按开始标志
  89.                         KEY_flag=1;                                                                        //标志有按键按下
  90.                         KeyTemp=KEYControl&KEYFullValue;                        //记录键值
  91.                 }               
  92.         }
  93.         if((TestKey==KEYFullValue)&&(KEY_flag==1)&&(LongKEY_flag==0))        //松手且之前有按键按下去过,但未响应过长按键
  94.         {
  95.                 KEY_flag=0;
  96.                 switch(KeyTemp)                                                                        //键值压栈
  97.                 {
  98.                         case KEY1:KeyInBuffer(1);
  99.                                 break;
  100.                         case KEY2:KeyInBuffer(2);
  101.                                 break;
  102.                         case KEY3:KeyInBuffer(3);
  103.                                 break;
  104.                         case KEY4:KeyInBuffer(4);
  105.                                 break;
  106.                         case KEY5:KeyInBuffer(5);
  107.                                 break;
  108.                         case KEY6:KeyInBuffer(6);
  109.                                 break;
  110.                         /*case KEY7:
  111.                                 break;
  112.                         case KEY8:
  113.                                 break;*/
  114.                         default:
  115.                                 break;
  116.                 }
  117.         }
  118.         else if((TestKey!=KEYFullValue)&&(KEY_flag==1))                //如果消抖完成且一直按键按着
  119.         {
  120.                 KeyStateTime++;                                                                           //那么按键状态时间自++
  121.                 if(LongKEY_START)
  122.                         timeTemp=LongKeyActionTime;
  123.                 else
  124.                         timeTemp=KeyStateTimeFull;
  125.                 if(KeyStateTime>timeTemp)                                                   //检测按键状态时间是否达到所需时间
  126.                 {
  127.                         LongKEY_flag=1;                                                                   //长按键标志置位,表示响应长按键
  128.                         KeyStateTime=0;                                                                   //清除按键状态时间,为下次做准备
  129.                         LongKEY_START=0;
  130.                         switch(KeyTemp)                                                                //键值压栈
  131.                         {
  132.                                 case KEY1:KeyInBuffer(0x81);
  133.                                         break;
  134.                                 case KEY2:KeyInBuffer(0x82);
  135.                                         break;
  136.                                 case KEY3:KeyInBuffer(0x83);
  137.                                         break;
  138.                                 case KEY4:KeyInBuffer(0x84);
  139.                                         break;
  140.                                 case KEY5:KeyInBuffer(0x85);
  141.                                         break;
  142.                                 case KEY6:KeyInBuffer(0x86);
  143.                                         break;
  144.                                 /*case KEY7:
  145.                                         break;
  146.                                 case KEY8:
  147.                                         break;*/
  148.                                 default:
  149.                                         break;
  150.                         }
  151.                  }
  152.         }
  153.         if((LongKEY_flag==1)&&(TestKey==KEYFullValue))                //如果响应过长按键,且按键现在松开了
  154.         {
  155.                 KEY_flag=0;
  156.                 KeyStateTime=0;
  157.                 LongKEY_flag=0;
  158.         }
  159. }
复制代码



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

使用道具 举报

沙发
ID:47286 发表于 2017-3-16 09:34 | 只看该作者
已经下载收藏 慢慢学习 感谢分享
回复

使用道具 举报

板凳
ID:74784 发表于 2017-3-16 19:06 | 只看该作者
没有硬件接线图吗?
回复

使用道具 举报

地板
ID:37684 发表于 2017-7-12 12:39 | 只看该作者
努力赚黑比啊!
回复

使用道具 举报

5#
ID:482380 发表于 2019-3-1 16:27 | 只看该作者
下载学习中
回复

使用道具 举报

6#
ID:419064 发表于 2019-3-1 19:38 | 只看该作者
可惜没有硬件接线图,试着从源码查看,只能逐一实验单片机脚看看能否接的对
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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