微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 第48节:利用DS1302做一个实时时钟

第48节:利用DS1302做一个实时时钟

时间:11-22 来源:互联网 点击:

  1. y_short(1);
  2. SCLK_dr=0; //清零时钟总线
  3. delay_short(1);
  4. DS1302_CE_dr = 1; //CE引脚为高,逻辑控制有效
  5. delay_short(1);
  6. //发送地址
  7. for ( i=0; i<8; i++ ) //循环8次移位
  8. {
  9. DIO_dr_sr = 0;
  10. temp = addr;
  11. if(temp&0x01)
  12. {
  13. DIO_dr_sr =1;
  14. }
  15. else
  16. {
  17. DIO_dr_sr =0;
  18. }
  19. delay_short(1);
  20. addr >>= 1; //右移一位
  21. SCLK_dr = 1;
  22. delay_short(1);
  23. SCLK_dr = 0;
  24. delay_short(1);
  25. }
  26. //发送数据
  27. for ( i=0; i<8; i++ ) //循环8次移位
  28. {
  29. DIO_dr_sr = 0;
  30. temp = dat;
  31. if(temp&0x01)
  32. {
  33. DIO_dr_sr =1;
  34. }
  35. else
  36. {
  37. DIO_dr_sr =0;
  38. }
  39. delay_short(1);
  40. dat >>= 1; //右移一位
  41. SCLK_dr = 1;
  42. delay_short(1);
  43. SCLK_dr = 0;
  44. delay_short(1);
  45. }
  46. DS1302_CE_dr = 0;
  47. delay_short(1);
  48. }
  49. //读取Ds1302时间的驱动 ,注意,此处读取的是BCD码,
  50. unsigned char Read1302 ( unsigned char addr )
  51. {
  52. unsigned char i,temp,dat1;
  53. DS1302_CE_dr=0; //单片机驱动DS1302属于SPI通讯方式,根据我的经验,不用关闭中断
  54. delay_short(1);
  55. SCLK_dr=0;
  56. delay_short(1);
  57. DS1302_CE_dr = 1;
  58. delay_short(1);
  59. //发送地址
  60. for ( i=0; i<8; i++ ) //循环8次移位
  61. {
  62. DIO_dr_sr = 0;
  63. temp = addr;
  64. if(temp&0x01)
  65. {
  66. DIO_dr_sr =1;
  67. }
  68. else
  69. {
  70. DIO_dr_sr =0;
  71. }
  72. delay_short(1);
  73. addr >>= 1; //右移一位
  74. SCLK_dr = 1;
  75. delay_short(1);
  76. SCLK_dr = 0;
  77. delay_short(1);
  78. }
  79. /* 注释二:
  80. * 51单片机IO口的特点,在读取数据之前必须先输出高电平,
  81. * 如果是PIC,AVR等单片机,这里应该把IO方向寄存器设置为输入
  82. */
  83. DIO_dr_sr =1; //51单片机IO口的特点,在读取数据之前必须先输出高电平,
  84. temp=0;
  85. for ( i=0; i<8; i++ )
  86. {
  87. temp>>=1;
  88. if(DIO_dr_sr==1)
  89. {
  90. temp=temp+0x80;
  91. }
  92. DIO_dr_sr =1;//51单片机IO口的特点,在读取数据之前必须先输出高电平
  93. delay_short(1);
  94. SCLK_dr = 1;
  95. delay_short(1);
  96. SCLK_dr = 0;
  97. delay_short(1);
  98. }
  99. DS1302_CE_dr=0;
  100. delay_short(1);
  101. dat1=temp;
  102. return (dat1);
  103. }
  104. unsigned char bcd_to_number(unsigned char ucBcdTemp)//BCD转原始数值
  105. {
  106. unsigned char ucNumberResult=0;
  107. unsigned char ucBcdTemp10;
  108. unsigned char ucBcdTemp1;
  109. ucBcdTemp10=ucBcdTemp;
  110. ucBcdTemp10=ucBcdTemp10>>4;
  111. ucBcdTemp1=ucBcdTemp;
  112. ucBcdTemp1=ucBcdTemp1&0x0f;
  113. ucNumberResult=ucBcdTemp10*10+ucBcdTemp1;
  114. return ucNumberResult;
  115. }
  116. unsigned char number_to_bcd(unsigned char ucNumberTemp) //原始数值转BCD
  117. {
  118. unsigned char ucBcdResult=0;
  119. unsigned char ucNumberTemp10;
  120. unsigned char ucNumberTemp1;
  121. ucNumberTemp10=ucNumberTemp;
  122. ucNumberTemp10=ucNumberTemp10/10;
  123. ucNumberTemp10=ucNumberTemp10<4;
  124. ucNumberTemp10=ucNumberTemp10&0xf0;
  125. ucNumberTemp1=ucNumberTemp;
  126. ucNumberTemp1=ucNumberTemp1%10;
  127. ucBcdResult=ucNumberTemp10|ucNumberTemp1;
  128. return ucBcdResult;
  129. }
  130. //日调整 每个月份的日最大取值不同,有的最大28日,有的最大29日,有的最大30,有的最大31
  131. unsigned char date_adjust(unsigned char ucYearTemp,unsigned char ucMonthTemp,unsigned char ucDateTemp) //日调整
  132. {
  133. unsigned char ucDayResult;
  134. unsigned int uiYearTemp;
  135. unsigned int uiYearYu;
  136. ucDayResult=ucDateTemp;
  137. switch(ucMonthTemp)//根据不同的月份来修正不同的日最大值
  138. {
  139. case 2://二月份要计算是否是闰年
  140. uiYearTemp=2000+ucYearTemp;
  141. uiYearYu=uiYearTemp%4;
  142. if(uiYearYu==0) //闰年
  143. {
  144. if(ucDayResult>29)
  145. {
  146. ucDayResult=29;
  147. }
  148. }
  149. else
  150. {
  151. if(ucDayResult>28)
  152. {
  153. ucDayResult=28;
  154. }
  155. }
  156. break;
  157. case 4:
  158. case 6:
  159. case 9:
  160. case 11:
  161. if(ucDayResult>30)
  162. {
  163. ucDayResult=30;
  164. }
  165. break;
  166. }
  167. return ucDayResult;
  168. }
  169. void ds1302_alarm_service(void) //ds1302出错报警
  170. {
  171. if(ucDs1302Error==1)//备用电池的电量用完了报警提示
  172. {
  173. if(uiDs1302Cnt>const_ds1302_0_5s)//大概0.5秒钟蜂鸣器响一次
  174. {
  175. ucDs1302Lock=1;//原子锁加锁
  176. uiDs1302Cnt=0; //计时器清零
  177. ucDs1302Lock=0;//原子锁解锁
  178. ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCnt
  179. uiVoiceCnt=const_voi

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top