找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机+DS12887实现的万年历程序

[复制链接]
跳转到指定楼层
楼主
ID:731890 发表于 2024-1-3 14:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本工程采用STC89C52RC读取DS12887时钟芯片的数据实现的,因为DS12887本身具有后备电池,所以即使设备掉电,时钟芯片依然通过使用后备电池运行,当设备上电后,读取的时钟依然是准确的。因此不用担心掉电后时钟运行不准确

DS12887简介
DS12887是DALLAS公司的实时时钟芯片RTC(Real Time Clock),它功能丰富,应用广泛,PC机内的时钟信号就是由D512887提供的。DS12887内部自带晶体振荡器及锂电池,可计算到2100年前的秒、分、小时、星期、日、月、年七种日历信息并带闰年补偿,断电后能运行10年之久不丢失数据。可选用夏令时,具有24小时或12小时两种制式。它在工业控制及仪器仪表中有广泛用途。DS12887上电时,当Vcc高于4.25V  200mS后,芯片可以被外部程序操作。当Vcc低于4.25V时,芯片处于写保护状态(所有的输入均无效),同时所有输出呈高阻状态。当Vcc低于3V时,芯片将自动把供电方式切换为由内部电池供电。

DS12887内部寄存器说明
DS12887有128个RAM单元。其中4个单元用作控制寄存器,10个单元用作存放时钟字节,114字节为通用RAM。其主要寄存器如下:

DS12887内部寄存器A:
  
UIP
  
DV2
DV1
DV0
RS3
RS2
RS1
RS0
UIP=l:更新已到,不能读/写DSl2887;UIP=0:更新末到,能读/写DS12887。
DV2,DV1,DV0应设置为010,表示打开晶振,允许计时。
RS3,RS2,RS1,RS0为方波频率选择位,产生方波周期中断。

DS12887内部寄存器B:
  
SET
  
PIE
AIE
UIE
SQWE
DM
24/12
DSE
SET=0:时间更新正常进行,每秒计数1次;SET=1:禁止更新,程序可初始化时间和日历。
PIE=l:允许周期中断;PIE=0:禁止周期中断。
AIE=1:允许报警中断;AIE=0:禁止报警中断。
UIE=1:允许更新结束中断;UIE=0:禁止更新结束中断。
SQWE为方波允许位。SQWE=1:将RS3,RS2,RS1,RS0选定的方波输出。
DM=1:BCD码;DM=0:二进制。该位不受复位信号影响
24/12:1表示24[小]时制;0表示12[小]时制。
DSE为夏时制允许位。DSE=l:采用夏时制;DSE=0:不采用夏时制。

DS12887内部寄存器C:
  
IRQF
  
PF
AF
UF
0
0
0
0
IRQF为中断申请标志。
PF为方波周期中断标志。PF=1:方波周期结束,申请中断。
AF为闹铃中断标志。AF=1:当前时间与闹铃时间匹配时即刻申请中断。
UF为更新周期结束中断标志。UF二I:更新周期结束时申请中断。

DS12887内部寄存器D:
  
VRT
  
0
0
0
0
0
0
0
VRT为内部锂电池状态。VRT=1:锂电池正常;VRT=0:锂电池耗尽。

D512887内部存储器功能如附表所示。
  
地址
  
功能
取值范围(十进制数)
取值范围(二进制数)
取值范围(BCD码)
0
0~59
00~3B
00~59
1
秒闹铃
0~59
00~3B
00~59
2
0~59
00~3B
00~59
3
分闹铃
0~59
00~3B
00~59
4
12[小]时模式
0~12
01~0C   AM
  
81~8C   PM
01~12   AM
  
81~92   PM
24[小]时模式
0~23
00~17
00~23
5
时闹铃,12[小]时制
1~12
01~0C   AM
  
81~8C   PM
01~12   AM
  
81~92   PM
时闹铃,24[小]时制
0~23
00~17
00~23
6
星期(星期天=1)
1~7
01~07
01~07
7
1~31
01~1F
01~31
8
1~12
01~0C
01~12
9
0~99
00~63
00~99
10
控制寄存器A






11
控制寄存器B






12
控制寄存器C






13
控制寄存器D






50
世纪
0~99
NA
19,20

以下是部分代码:

  1. #include <REG51.H>
  2. #include <ABSACC.H>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. //============================
  6. #define C8155 XBYTE[0x7000]
  7. #define PA XBYTE[0x7001]
  8. #define PB XBYTE[0x7002]
  9. #define PC XBYTE[0x7003]
  10. //============================
  11. #define sec XBYTE[0x8000]
  12. #define min XBYTE[0x8002]
  13. #define hou XBYTE[0x8004]
  14. #define week XBYTE[0x8006]
  15. #define day XBYTE[0x8007]
  16. #define mon XBYTE[0x8008]
  17. #define year XBYTE[0x8009]
  18. #define cent XBYTE[0x8032]
  19. #define DS12887A XBYTE[0x800a]
  20. #define DS12887B XBYTE[0x800b]
  21. #define DS12887C XBYTE[0x800c]
  22. //===============================
  23. sbit set_inc=P1^0;
  24. sbit set_dec=P1^1;
  25. sbit inc=P1^2;
  26. sbit dec=P1^3;
  27. uchar disbit;
  28. bit flag;
  29. uchar SEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,
  30.                 0x6d,0x7d,0x07,0x7f,0x6f};
  31. uchar code act_PB[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  32. uchar code act_PC[5]={0xfe,0xfd,0xfb,0xf7,0xef};
  33. char ms=0;
  34. char data ram_year,ram_mon,ram_day,ram_week,ram_hou,ram_min,ram_sec;
  35. void scan_key(void);
  36. void delay(uint k);
  37. void wr_time(void);
  38. void rd_time(void);
  39. /******************************/
  40. void init_timer0(void)
  41. {
  42. TH0=-(2000/256);
  43. TL0=-(2000%256);
  44. TR0=1;
  45. }

  46. //***********************
  47. void init(void)
  48. {        init_timer0();         
  49.         EA=1;ET0=1;
  50.         C8155=0x0f;
  51.         DS12887A=0x20;
  52. }


  53. /**********************************/
  54. void time_dis(uchar disbit)
  55. {uchar y_week;
  56. switch(disbit)
  57. {
  58. case 0:{PA=SEG7[ram_sec%10];}break;
  59. case 1:{PA=SEG7[ram_sec/10];}break;
  60. case 2:{PA=SEG7[ram_min%10];}break;
  61. case 3:{PA=SEG7[ram_min/10];}break;
  62. case 4:{PA=SEG7[ram_hou%10];}break;
  63. case 5:{PA=SEG7[ram_hou/10];}break;
  64. case 6:{if(ram_week==1)y_week=9;
  65.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  66. case 7:{PA=SEG7[ram_day%10];}break;
  67. case 8:{PA=SEG7[ram_day/10];}break;
  68. case 9:{PA=SEG7[ram_mon%10];}break;
  69. case 10:{PA=SEG7[ram_mon/10];}break;
  70. case 11:{PA=SEG7[ram_year%10];}break;
  71. case 12:{PA=SEG7[ram_year/10];}break;
  72. default:break;
  73. }
  74. }
  75. /****************************************/
  76. void min_dis(uchar disbit)
  77. {uchar y_week;
  78. switch(disbit)
  79. {
  80. case 0:{PA=SEG7[ram_sec%10];}break;
  81. case 1:{PA=SEG7[ram_sec/10];}break;
  82. case 2:{PA=SEG7[ram_min%10]&0x7f;}break;
  83. case 3:{PA=SEG7[ram_min/10]&0x7f;}break;
  84. case 4:{PA=SEG7[ram_hou%10];}break;
  85. case 5:{PA=SEG7[ram_hou/10];}break;
  86. case 6:{if(ram_week==1)y_week=9;
  87.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  88. case 7:{PA=SEG7[ram_day%10];}break;
  89. case 8:{PA=SEG7[ram_day/10];}break;
  90. case 9:{PA=SEG7[ram_mon%10];}break;
  91. case 10:{PA=SEG7[ram_mon/10];}break;
  92. case 11:{PA=SEG7[ram_year%10];}break;
  93. case 12:{PA=SEG7[ram_year/10];}break;
  94. default:break;
  95. }
  96. }
  97. /***************************************/
  98. void hou_dis(uchar disbit)
  99. {uchar y_week;
  100. switch(disbit)
  101. {
  102. case 0:{PA=SEG7[ram_sec%10];}break;
  103. case 1:{PA=SEG7[ram_sec/10];}break;
  104. case 2:{PA=SEG7[ram_min%10];}break;
  105. case 3:{PA=SEG7[ram_min/10];}break;
  106. case 4:{PA=SEG7[ram_hou%10]&0x7f;}break;
  107. case 5:{PA=SEG7[ram_hou/10]&0x7f;}break;
  108. case 6:{if(ram_week==1)y_week=9;
  109.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  110. case 7:{PA=SEG7[ram_day%10];}break;
  111. case 8:{PA=SEG7[ram_day/10];}break;
  112. case 9:{PA=SEG7[ram_mon%10];}break;
  113. case 10:{PA=SEG7[ram_mon/10];}break;
  114. case 11:{PA=SEG7[ram_year%10];}break;
  115. case 12:{PA=SEG7[ram_year/10];}break;
  116. default:break;
  117. }
  118. }
  119. /***************************************/
  120. void week_dis(uchar disbit)
  121. {uchar y_week;
  122. switch(disbit)
  123. {
  124. case 0:{PA=SEG7[ram_sec%10];}break;
  125. case 1:{PA=SEG7[ram_sec/10];}break;
  126. case 2:{PA=SEG7[ram_min%10];}break;
  127. case 3:{PA=SEG7[ram_min/10];}break;
  128. case 4:{PA=SEG7[ram_hou%10];}break;
  129. case 5:{PA=SEG7[ram_hou/10];}break;
  130. case 6:{if(ram_week==1)y_week=9;
  131.                 else y_week=ram_week;PA=SEG7[y_week-1]&0x7f;}break;
  132. case 7:{PA=SEG7[ram_day%10];}break;
  133. case 8:{PA=SEG7[ram_day/10];}break;
  134. case 9:{PA=SEG7[ram_mon%10];}break;
  135. case 10:{PA=SEG7[ram_mon/10];}break;
  136. case 11:{PA=SEG7[ram_year%10];}break;
  137. case 12:{PA=SEG7[ram_year/10];}break;
  138. default:break;
  139. }
  140. }
  141. /**************************************/
  142. void day_dis(uchar disbit)
  143. {uchar y_week;
  144. switch(disbit)
  145. {
  146. case 0:{PA=SEG7[ram_sec%10];}break;
  147. case 1:{PA=SEG7[ram_sec/10];}break;
  148. case 2:{PA=SEG7[ram_min%10];}break;
  149. case 3:{PA=SEG7[ram_min/10];}break;
  150. case 4:{PA=SEG7[ram_hou%10];}break;
  151. case 5:{PA=SEG7[ram_hou/10];}break;
  152. case 6:{if(ram_week==1)y_week=9;
  153.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  154. case 7:{PA=SEG7[ram_day%10]&0x7f;}break;
  155. case 8:{PA=SEG7[ram_day/10]&0x7f;}break;
  156. case 9:{PA=SEG7[ram_mon%10];}break;
  157. case 10:{PA=SEG7[ram_mon/10];}break;
  158. case 11:{PA=SEG7[ram_year%10];}break;
  159. case 12:{PA=SEG7[ram_year/10];}break;
  160. default:break;
  161. }
  162. }
  163. /********************************************/
  164. void mon_dis(uchar disbit)
  165. {uchar y_week;
  166. switch(disbit)
  167. {
  168. case 0:{PA=SEG7[ram_sec%10];}break;
  169. case 1:{PA=SEG7[ram_sec/10];}break;
  170. case 2:{PA=SEG7[ram_min%10];}break;
  171. case 3:{PA=SEG7[ram_min/10];}break;
  172. case 4:{PA=SEG7[ram_hou%10];}break;
  173. case 5:{PA=SEG7[ram_hou/10];}break;
  174. case 6:{if(ram_week==1)y_week=9;
  175.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  176. case 7:{PA=SEG7[ram_day%10];}break;
  177. case 8:{PA=SEG7[ram_day/10];}break;
  178. case 9:{PA=SEG7[ram_mon%10]&0x7f;}break;
  179. case 10:{PA=SEG7[ram_mon/10]&0x7f;}break;
  180. case 11:{PA=SEG7[ram_year%10];}break;
  181. case 12:{PA=SEG7[ram_year/10];}break;
  182. default:break;
  183. }
  184. }
  185. /****************************************/
  186. void year_dis(uchar disbit)
  187. {uchar y_week;
  188. switch(disbit)
  189. {
  190. case 0:{PA=SEG7[ram_sec%10];}break;
  191. case 1:{PA=SEG7[ram_sec/10];}break;
  192. case 2:{PA=SEG7[ram_min%10];}break;
  193. case 3:{PA=SEG7[ram_min/10];}break;
  194. case 4:{PA=SEG7[ram_hou%10];}break;
  195. case 5:{PA=SEG7[ram_hou/10];}break;
  196. case 6:{if(ram_week==1)y_week=9;
  197.                 else y_week=ram_week;PA=SEG7[y_week-1];}break;
  198. case 7:{PA=SEG7[ram_day%10];}break;
  199. case 8:{PA=SEG7[ram_day/10];}break;
  200. case 9:{PA=SEG7[ram_mon%10];}break;
  201. case 10:{PA=SEG7[ram_mon/10];}break;
  202. case 11:{PA=SEG7[ram_year%10]&0x7f;}break;
  203. case 12:{PA=SEG7[ram_year/10]&0x7f;}break;
  204. default:break;
  205. }
  206. }
  207. /****************************************/
  208. void time0(void) interrupt 1 using 1
  209. {static uchar disbit;
  210.         TH0=-(2000/256);
  211.         TL0=-(2000%256);
  212.         PB=0xff;PC=0xff;
  213. switch(ms)
  214. {
  215. case 0:{time_dis(disbit);}break;
  216. case 1:{min_dis(disbit);}break;
  217. case 2:{hou_dis(disbit);}break;
  218. case 3:{week_dis(disbit);}break;
  219. case 4:{day_dis(disbit);}break;
  220. case 5:{mon_dis(disbit);}break;
  221. case 6:{year_dis(disbit);}break;
  222. default:break;
  223. }
  224. disbit++;
  225. if(disbit>12)disbit=0;
  226. if(disbit<8){PB=act_PB[disbit];PC=0xff;}
  227. else {PB=0xff;PC=act_PC[disbit-8];}
  228. }
  229. /***********************************/
  230. void main(void)
  231. {
  232. init();
  233. rd_time();
  234. while(1)
  235. {
  236. scan_key();
  237. if(ms==0){
  238.                 if(flag){wr_time();flag=0;}
  239.                 else rd_time();
  240.                 }
  241. }
  242. }
  243. /*****************************************/
  244. void wr_time(void)
  245. {
  246.         DS12887B=0x86;
  247.         year=ram_year;mon=ram_mon;day=ram_day;
  248.         week=ram_week;hou=ram_hou;min=ram_min;
  249.         DS12887B=0x06;
  250. }
  251. /*******************************************/
  252. void rd_time(void)
  253. {
  254. uchar data temp,x;
  255. do{temp=DS12887A;x=temp|0x7f;}while(x==0xff);
  256.         ram_year=year;ram_mon=mon;ram_day=day;
  257.         ram_week=week;ram_hou=hou;ram_min=min;ram_sec=sec;
  258. }
  259. /*****************************************/
  260. void scan_key(void)
  261. {
  262. if(!set_inc){ms++;delay(200);if(ms>6)ms=0;}
  263. if(!set_dec){ms--;delay(200);if(ms<0)ms=6;}
  264. if(ms==1){flag=1;if(!inc){ram_min++;if(ram_min>59)ram_min=59;delay(200);}
  265.                 if(!dec){ram_min--;if(ram_min<1)ram_min=1;delay(200);}        }
  266. if(ms==2){        if(!inc){ram_hou++;if(ram_hou>23)ram_hou=23;delay(200);}
  267.                 if(!dec){ram_hou--;if(ram_hou<0)ram_hou=0;delay(200);}        }
  268. if(ms==3){        if(!inc){ram_week++;if(ram_week>7)ram_week=7;delay(200);}
  269.                 if(!dec){ram_week--;if(ram_week<1)ram_week=1;delay(200);} }
  270. if(ms==4){        if(!inc){ram_day++;if(ram_day>31)ram_day=31;delay(200);}
  271.                 if(!dec){ram_day--;if(ram_day<1)ram_day=1;delay(200);}        }
  272. if(ms==5){        if(!inc){ram_mon++;if(ram_mon>12)ram_mon=12;delay(200);}
  273.                 if(!dec){ram_mon--;if(ram_mon<1)ram_mon=1;delay(200);}        }
  274. if(ms==6){flag=1;if(!inc){ram_year++;if(ram_year>99)ram_year=99;delay(200);}
  275.                 if(!dec){ram_year--;if(ram_year<0)ram_day=0;delay(200);} }
  276. }
  277. /********************************************************/
  278. void delay(uint k)
  279. {
  280. uint i,j;
  281. for(i=0;i<k;i++){
  282. for(j=0;j<60;j++)
  283. {;}}
  284. }
  285. /*****************end********************/

复制代码
原理图: 无
仿真: 无
代码: ds12887.7z (13.82 KB, 下载次数: 6)

评分

参与人数 1黑币 +50 收起 理由
admin + 50

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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