ds1302.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "ds1302.h"
  2. //#define DS1302_DAT_INPUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=8;} //设置dio引脚输入模式
  3. //#define DS1302_DAT_OUTPUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=3;}//设置输出模式
  4. struct DS1302DATA ds1302Data = {22,4,26,22,02,0,6};
  5. u8 ascii_time[7] = {0}; //保存ascii格式数据
  6. u8 bcd_time[7] = {0}; //保存bcd码数据
  7. void DS1302_DAT_INPUT(void)//SDA配置输入模式
  8. {
  9. GPIO_InitTypeDef GPIO_InitStructure;
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IPU; //上拉输入
  13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  14. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化
  15. }
  16. void DS1302_DAT_OUTPUT(void)//SDA配置输出模式
  17. {
  18. GPIO_InitTypeDef GPIO_InitStructure;
  19. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  20. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP; //推挽输出
  22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  23. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化
  24. }
  25. static u8 AsciiToBcd(u8 asciiData)
  26. {
  27. u8 bcdData = 0;
  28. bcdData = (((asciiData/10)<<4)|((asciiData%10)));
  29. return bcdData;
  30. }
  31. static u8 BcdToAscii(u8 bcdData)
  32. {
  33. u8 asciiData = 0;
  34. asciiData = (((bcdData&0xf0)>>4)*10 + (bcdData&0x0f));
  35. return asciiData;
  36. }
  37. //IO口初始化
  38. void Ds1302_Gpio_Init(void)
  39. {
  40. GPIO_InitTypeDef GPIO_InitStructure;
  41. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE);
  42. //RST
  43. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
  44. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  45. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP;//推挽输出
  46. GPIO_Init(GPIOA, &GPIO_InitStructure);
  47. //CLK
  48. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_14;
  49. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  50. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP;//推挽输出
  51. GPIO_Init(GPIOB, &GPIO_InitStructure);
  52. //DIO
  53. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15;
  54. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  55. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP;//推挽输出
  56. GPIO_Init(GPIOB, &GPIO_InitStructure);
  57. }
  58. //读取一个字节的时序
  59. u8 Ds1302_ReadByte(void)
  60. {
  61. u8 i = 0, dat = 0;
  62. DS1302_DAT_INPUT();
  63. delay_us(5);
  64. for(i = 0; i <8; i++)
  65. {
  66. dat >>= 1;
  67. if(DS1302_DATIN == 1)dat |= 0x80;
  68. DS1302_CLK = 1;
  69. delay_us(2);
  70. DS1302_CLK = 0;
  71. delay_us(2);
  72. }
  73. return dat;
  74. }
  75. //写入一个字节的时序
  76. void Ds1302_WriteByte(u8 dat)
  77. {
  78. u8 i = 0, data = dat;
  79. DS1302_DAT_OUTPUT();
  80. DS1302_CLK = 0;
  81. delay_us(2);
  82. for(i = 0; i < 8; i++)
  83. {
  84. DS1302_DATOUT = data&0x01;
  85. delay_us(2);
  86. DS1302_CLK = 1;
  87. delay_us(2);
  88. DS1302_CLK = 0;
  89. data >>= 1;
  90. }
  91. }
  92. //写入一个寄存器
  93. void Ds1302_Write(u8 address,u8 dat)
  94. {
  95. DS1302_RST = 0;
  96. DS1302_CLK = 0;
  97. DS1302_RST = 1;
  98. Ds1302_WriteByte(address);
  99. Ds1302_WriteByte(dat);
  100. DS1302_CLK = 1;
  101. DS1302_RST = 0;
  102. }
  103. //单个写入时间
  104. void Ds1302_Write_Time_Singel(u8 address,u8 dat)
  105. {
  106. Ds1302_Write(DS1302_CONTROL_REG,0x00); //取消写保护
  107. Ds1302_Write(address,dat);
  108. Ds1302_Write(DS1302_CONTROL_REG,0x80); //打开写保护
  109. }
  110. //一次完成所有时间更新
  111. //start当前时钟运行还是停止
  112. void Ds1302_Write_Time_All(u8 start)
  113. {
  114. Ds1302_Write(DS1302_CONTROL_REG,0x00); //取消写保护
  115. Ds1302_Write(DS1302_SEC_REG,(AsciiToBcd(ds1302Data.sec)|start));
  116. Ds1302_Write(DS1302_MIN_REG,AsciiToBcd(ds1302Data.min));
  117. Ds1302_Write(DS1302_HR_REG,AsciiToBcd(ds1302Data.hour));
  118. Ds1302_Write(DS1302_DATE_REG,AsciiToBcd(ds1302Data.day));
  119. Ds1302_Write(DS1302_MONTH_REG,AsciiToBcd(ds1302Data.month));
  120. Ds1302_Write(DS1302_DAY_REG,AsciiToBcd(ds1302Data.week));
  121. Ds1302_Write(DS1302_YEAR_REG,AsciiToBcd(ds1302Data.year));
  122. Ds1302_Write(DS1302_CONTROL_REG,0x80); //打开写保护
  123. }
  124. //读取一个字节
  125. u8 Ds1302_Read(u8 address)
  126. {
  127. u8 data = 0;
  128. DS1302_RST = 0;
  129. DS1302_CLK = 0;
  130. DS1302_RST = 1;
  131. Ds1302_WriteByte(address|0x01); //读取地址需要与0x01相或,最低为变成1
  132. data = Ds1302_ReadByte();
  133. DS1302_CLK = 1;
  134. DS1302_RST = 0;
  135. return data;
  136. }
  137. //读取时间的时候默认让时间走起来
  138. void Ds1302_Readtime(void)
  139. {
  140. ds1302Data.sec = BcdToAscii(Ds1302_Read(DS1302_SEC_REG)); //秒
  141. ds1302Data.min = BcdToAscii(Ds1302_Read(DS1302_MIN_REG)); //分
  142. ds1302Data.hour = BcdToAscii(Ds1302_Read(DS1302_HR_REG)); //小时
  143. ds1302Data.day = BcdToAscii(Ds1302_Read(DS1302_DATE_REG)); //日
  144. ds1302Data.month = BcdToAscii(Ds1302_Read(DS1302_MONTH_REG)); //月
  145. ds1302Data.week = BcdToAscii(Ds1302_Read(DS1302_DAY_REG)); //星期几
  146. ds1302Data.year = BcdToAscii(Ds1302_Read(DS1302_YEAR_REG)); //年
  147. }