DS1302.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. #include "Data_deal.h"
  2. #include "DS1302.h"
  3. #include "sys_delay.h"
  4. uint8_t time_buf[7] = {0x20,0x20,0x05,0x29,0x17,0x20,0x14}; //初始时间2020年5月29号17点41分14秒 星期五
  5. //DS1302初始化
  6. void ds1302_Init(void)
  7. {
  8. GPIO_InitTypeDef GPIO_InitStruct = {0};
  9. __HAL_RCC_GPIOB_CLK_ENABLE();
  10. __HAL_RCC_GPIOE_CLK_ENABLE();
  11. GPIO_InitStruct.Pin = DS1302_RST;
  12. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  13. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  14. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  15. GPIO_InitStruct.Pin = DS1302_DATA;
  16. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  17. // GPIO_InitStruct.Pull = GPIO_NOPULL;
  18. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  19. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  20. GPIO_InitStruct.Pin = DS1302_SCK;
  21. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  22. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  23. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  24. HAL_GPIO_WritePin(GPIOE, DS1302_DATA,GPIO_PIN_SET); //拉高
  25. HAL_GPIO_WritePin(GPIOE, DS1302_RST,GPIO_PIN_SET); //置低
  26. HAL_GPIO_WritePin(GPIOB, DS1302_SCK,GPIO_PIN_RESET); //置低
  27. }
  28. void DS1302_IO_IN(void)
  29. {
  30. GPIO_InitTypeDef GPIO_InitStruct = {0};
  31. __HAL_RCC_GPIOE_CLK_ENABLE();
  32. GPIO_InitStruct.Pin = DS1302_DATA;
  33. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  34. GPIO_InitStruct.Pull = GPIO_NOPULL;
  35. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  36. }
  37. void DS1302_IO_OUT(void)
  38. {
  39. GPIO_InitTypeDef GPIO_InitStruct = {0};
  40. __HAL_RCC_GPIOE_CLK_ENABLE();
  41. GPIO_InitStruct.Pin = DS1302_DATA;
  42. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  43. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  44. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  45. }
  46. //void delay_us(uint32_t us)
  47. //{
  48. // uint32_t delay = (HAL_RCC_GetHCLKFreq() / 6000000 * us);
  49. // while (delay--)
  50. // {
  51. // ;
  52. // }
  53. //}
  54. //向DS1302写入一个字节数据
  55. void ds1302_Write_Byte(uint8_t addr, uint8_t data)
  56. {
  57. uint8_t i;
  58. DS1302_RST_0; //停止DS1302总线
  59. delay_us(10);
  60. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  61. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  62. DS1302_RST_1; //启动DS1302总线
  63. addr = addr & 0xFE; //最低位置零,写数据
  64. DS1302_IO_OUT();
  65. for(i = 0; i < 8; i ++) //写地址
  66. {
  67. if (addr & 0x01)
  68. DS1302_DATA_OUT_1;
  69. else
  70. DS1302_DATA_OUT_0;
  71. DS1302_SCK_1; //产生时钟
  72. delay_us(10);
  73. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  74. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  75. DS1302_SCK_0;
  76. addr = addr>>1;
  77. }
  78. for (i = 0; i < 8; i ++) //写数据
  79. {
  80. if(data & 0x01)
  81. DS1302_DATA_OUT_1;
  82. else
  83. DS1302_DATA_OUT_0;
  84. DS1302_SCK_1; //产生时钟
  85. delay_us(10);
  86. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  87. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  88. DS1302_SCK_0;
  89. data = data>>1;
  90. }
  91. DS1302_RST_0; //停止DS1302总线
  92. }
  93. //从DS1302读出一个字节数据
  94. uint8_t ds1302_Read_Byte(uint8_t addr)
  95. {
  96. uint8_t i,temp;
  97. DS1302_RST_0; //停止DS1302总线
  98. delay_us(10);
  99. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  100. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  101. DS1302_RST_1; //启动DS1302总线
  102. addr = addr | 0x01; //最低位置高,读数据
  103. DS1302_IO_OUT();
  104. for(i = 0; i < 8; i ++) //写地址
  105. {
  106. if (addr & 0x01)
  107. DS1302_DATA_OUT_1;
  108. else
  109. DS1302_DATA_OUT_0;
  110. DS1302_SCK_1; //产生时钟
  111. delay_us(10);
  112. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  113. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  114. DS1302_SCK_0;
  115. addr = addr>>1;
  116. }
  117. DS1302_IO_IN();
  118. for (i = 0; i < 8; i ++) //读数据
  119. {
  120. temp = temp >> 1;
  121. if(DS1302_DATA_IN())
  122. temp |= 0x80;
  123. else
  124. temp &= 0x7F;
  125. DS1302_SCK_1; //产生时钟
  126. delay_us(10);
  127. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  128. __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  129. DS1302_SCK_0;
  130. }
  131. DS1302_RST_0; //停止DS1302总线
  132. return temp;
  133. }
  134. //向DS1302写入时间数据
  135. void ds1302_Write_Time(uint8_t *Time_buf)
  136. {
  137. ds1302_Write_Byte(ds1302_control_add, 0x00); //关闭写保护
  138. ds1302_Write_Byte(ds1302_sec_add, 0x80); //暂停时钟
  139. //DS1302_Write_Byte(ds1302_charger_add, 0xA9); //涓流充电
  140. ds1302_Write_Byte(ds1302_year_add,HEX2BCD(Time_buf[1])); //年
  141. ds1302_Write_Byte(ds1302_month_add,HEX2BCD(Time_buf[2])); //月
  142. ds1302_Write_Byte(ds1302_date_add,HEX2BCD(Time_buf[3])); //日
  143. ds1302_Write_Byte(ds1302_hr_add,HEX2BCD(Time_buf[4])); //时
  144. ds1302_Write_Byte(ds1302_min_add,HEX2BCD(Time_buf[5])); //分
  145. ds1302_Write_Byte(ds1302_sec_add,HEX2BCD(Time_buf[6])); //秒
  146. //ds1302_Write_Byte(ds1302_day_add,time_buf[7]); //周
  147. ds1302_Write_Byte(ds1302_control_add,0x80); //打开写保护
  148. }
  149. //从DS302读出时钟数据
  150. void ds1302_Read_Time(void)
  151. {
  152. time_buf[1] = ds1302_Read_Byte(ds1302_year_add); //年
  153. time_buf[2] = ds1302_Read_Byte(ds1302_month_add); //月
  154. time_buf[3] = ds1302_Read_Byte(ds1302_date_add); //日
  155. time_buf[4] = ds1302_Read_Byte(ds1302_hr_add); //时
  156. time_buf[5] = ds1302_Read_Byte(ds1302_min_add); //分
  157. time_buf[6] = (ds1302_Read_Byte(ds1302_sec_add))&0x7f; //秒,屏蔽秒的第7位,避免超出59
  158. //time_buf[7] = ds1302_Read_Byte(ds1302_day_add); //周
  159. //Can_Send_Hu_Msg(0xb1,time_buf,8,0x1b,0x00000012);
  160. }
  161. void ds1302_SynTime(SDateTime * datetime)
  162. {
  163. ds1302_Read_Time();
  164. datetime->year = BCD2HEX(time_buf[1]);
  165. datetime->month = BCD2HEX(time_buf[2]);
  166. datetime->day = BCD2HEX(time_buf[3]);
  167. datetime->hour = BCD2HEX(time_buf[4]);
  168. datetime->min = BCD2HEX(time_buf[5]);
  169. datetime->sec = BCD2HEX(time_buf[6]);
  170. return;
  171. }
  172. //DS1302向上层返回时间数据
  173. void ds1302_Get_Time(uint8_t *time)
  174. {
  175. ds1302_Read_Time();
  176. time[0]=(time_buf[0]>>4); //年
  177. time[1]=(time_buf[0]&0x0f);
  178. time[2]=(time_buf[1]>>4);
  179. time[3]=(time_buf[1]&0x0f);
  180. time[4]=(time_buf[2]>>4); //月
  181. time[5]=(time_buf[2]&0x0f);
  182. time[6]=(time_buf[3]>>4); //日
  183. time[7]=(time_buf[3]&0x0f);
  184. //time[8]=(time_buf[7]&0x07); //星期
  185. time[9]=(time_buf[4]>>4); //时
  186. time[10]=(time_buf[4]&0x0f);
  187. time[11]=(time_buf[5]>>4); //分
  188. time[12]=(time_buf[5]&0x0f);
  189. time[13]=(time_buf[6]>>4); //秒
  190. time[14]=(time_buf[6]&0x0f);
  191. }
  192. //////////////////////////////////////--以下李伟添加 李伟修改 20210613
  193. //ds1302------stm32f746vgt6
  194. //pin5 rst--pin98--Pe1
  195. //pin6 io pin97--PE0
  196. //pin7 sck pin96--PB9
  197. /*
  198. 1、 初始化IO口。
  199. void GPIO_Config(void)
  200. {
  201. GPIO_InitTypeDef GPIO_InitStructure;
  202. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE);
  203. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14;
  204. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  205. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  206. GPIO_Init(GPIOD, &GPIO_InitStructure);
  207. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE);
  208. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  209. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  210. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  211. GPIO_Init(GPIOD, &GPIO_InitStructure);
  212. }
  213. 2、 ds1302_init(); // 调用ds1302初始化程序
  214. 3、 get_result() ; //定时读取ds1302时间 这个函数每隔一段时间调用一次。比如50ms调用一次。
  215. */
  216. #define RST_1 HAL_GPIO_WritePin(GPIOE, DS1302_RST, GPIO_PIN_SET) //GPIO_SetBits(GPIOE, GPIO_PIN_1);
  217. #define RST_0 HAL_GPIO_WritePin(GPIOE, DS1302_RST, GPIO_PIN_RESET) //GPIO_ResetBits(GPIOE, GPIO_PIN_1);
  218. #define IO_1 HAL_GPIO_WritePin(GPIOE, DS1302_DATA, GPIO_PIN_SET) //GPIO_SetBits(GPIOD, GPIO_Pin_13);
  219. #define IO_0 HAL_GPIO_WritePin(GPIOE, DS1302_DATA, GPIO_PIN_RESET) //GPIO_ResetBits(GPIOD, GPIO_Pin_13);
  220. #define SCLK_1 HAL_GPIO_WritePin(GPIOB, DS1302_SCK, GPIO_PIN_SET) //GPIO_SetBits(GPIOB, GPIO_Pin_9);
  221. #define SCLK_0 HAL_GPIO_WritePin(GPIOB, DS1302_SCK, GPIO_PIN_RESET) //DS1302_SCK_0 //GPIO_ResetBits(GPIOB, GPIO_Pin_9);
  222. /*定义待设置的时间: 秒、 分、 时、 日、 月、 星期、年、控制字*/
  223. volatile char time_tab[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  224. char tableDS1302[7];
  225. char date_1302[6];
  226. char time_1302[6];
  227. unsigned int year;
  228. unsigned char month;
  229. unsigned char date;
  230. unsigned char hour;
  231. unsigned char min;
  232. unsigned char sec;
  233. /********************************************************************
  234. 函 数 ds1302_initV2()DS1302初始化函数
  235. 功 能:DS1302初始化
  236. 入口参数:无
  237. 返 回 值:无
  238. ***********************************************************************/
  239. void ds1302_initV2(void)
  240. {
  241. SCLK_0;
  242. RST_0;
  243. RST_1;
  244. ds1302_writeV2(0x8e);
  245. ds1302_writeV2(0);
  246. RST_0;
  247. }
  248. /********************************************************************
  249. 函 数 名:ds1302_write()写一个字节数据函数
  250. 功 能:DS1302中写入一个字节
  251. 入口参数:time_tx 要写入的一个字节
  252. 返 回 值:无
  253. ***********************************************************************/
  254. void ds1302_writeV2(unsigned char time_tx)
  255. {
  256. int j;
  257. Set_IO_OUT();
  258. for(j=0;j<8;j++)
  259. {
  260. IO_0;
  261. SCLK_0;
  262. if((time_tx&0x01)!=0) IO_1;
  263. time_tx=time_tx>>1;
  264. SCLK_1;
  265. }
  266. SCLK_0;
  267. }
  268. /********************************************************************
  269. 函 数 名:ds1302_read()读一个字节函数
  270. 功 能:从DS1302读一个字节
  271. 入口参数:无
  272. 返 回 值:unsigned char :读取的数据
  273. ***********************************************************************/
  274. unsigned char ds1302_readV2(void)
  275. {
  276. int j;
  277. unsigned char time_rx=0;
  278. Set_IO_INPUT();
  279. for(j=0;j<8;j++)
  280. {
  281. SCLK_0;
  282. time_rx=time_rx>>1;
  283. //if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_13)==1) time_rx|=0x80;//把接收到的数据放到接收寄存器的最高位
  284. if (DS1302_DATA_IN()==1) time_rx|=0x80;//把接收到的数据放到接收寄存器的最高位
  285. SCLK_1;
  286. }
  287. SCLK_0;
  288. return(time_rx);
  289. }
  290. /********************************************************************
  291. 函 数 名:set_time()设置时间函数
  292. 功 能:设置初始时间
  293. 说 明:使用了多字节写方式
  294. 入口参数:无
  295. 返 回 值:无
  296. ***********************************************************************/
  297. void set_time(void)
  298. {
  299. int i;
  300. RST_1;
  301. ds1302_writeV2(0xbe);
  302. for(i=0;i<8;i++)
  303. {
  304. ds1302_writeV2(time_tab[i]);
  305. }
  306. RST_0;
  307. }
  308. /********************************************************************
  309. 函 数 名:get_all()读取全部时间信息函数
  310. 功 能:读取DS1302内部的全部时间信息
  311. 入口参数:无
  312. 返 回 值:无。
  313. ***********************************************************************/
  314. void DS1302_get_all(void)
  315. {
  316. int i;
  317. RST_1;
  318. ds1302_writeV2(0xbf);
  319. for(i=0;i<7;i++)
  320. {
  321. tableDS1302[i]=ds1302_readV2();
  322. }
  323. RST_0;
  324. }
  325. /********************************************************************
  326. 函 数 名:get_time()读取时间函数
  327. 功 能:读取DS1302当前时间
  328. 入口参数:无
  329. 返 回 值:无。
  330. ***********************************************************************/
  331. void get_timeV2(void)
  332. {
  333. DS1302_get_all();
  334. time_1302[0]=tableDS1302[0]&0x0F;//求秒的个位
  335. time_1302[1]=tableDS1302[0]&0x70; //求秒的十位
  336. time_1302[1]>>=4;//右移4位
  337. time_1302[2]=tableDS1302[1]&0x0F; //求分的个位
  338. time_1302[3]=tableDS1302[1]&0x70; //求分的十位
  339. time_1302[3]>>=4;
  340. time_1302[4]=tableDS1302[2]&0x0F; //求时的个位
  341. time_1302[5]=tableDS1302[2]&0x70; //求时的十位
  342. time_1302[5]>>=4;
  343. }
  344. /********************************************************************
  345. 函 数 名:get_date()读取日期函数
  346. 功 能:读取DS1302当前日期
  347. 入口参数:无
  348. 返 回 值:无。
  349. ***********************************************************************/
  350. void get_date(void)
  351. {
  352. DS1302_get_all();
  353. date_1302[0]=tableDS1302[3]&0x0F;//求日的个位
  354. date_1302[1]=tableDS1302[3]&0x30; //求日的十位
  355. date_1302[1]>>=4;//右移4位
  356. date_1302[2]=tableDS1302[4]&0x0F; //求月的个位
  357. date_1302[3]=tableDS1302[4]&0x10; //求月的十位
  358. date_1302[3]>>=4;
  359. date_1302[4]=tableDS1302[6]&0x0F; //求年的个位
  360. date_1302[5]=tableDS1302[6]&0xF0; //求年的十位
  361. date_1302[5]>>=4;
  362. }
  363. void get_result(void)
  364. {
  365. int i;
  366. int j;
  367. get_date();
  368. i=date_1302[5];
  369. j=date_1302[4];
  370. year=i*10+j;
  371. i=date_1302[3];
  372. j=date_1302[2];
  373. month=i*10+j;
  374. i=date_1302[1];
  375. j=date_1302[0];
  376. date=i*10+j;
  377. get_timeV2();
  378. i=time_1302[5];
  379. j=time_1302[4];
  380. hour=i*10+j;
  381. i=time_1302[3];
  382. j=time_1302[2];
  383. min=i*10+j;
  384. i=time_1302[1];
  385. j=time_1302[0];
  386. sec=i*10+j;
  387. }
  388. void Set_IO_OUT(void)
  389. {
  390. GPIO_InitTypeDef GPIO_InitStructure; /*定义一个GPIO_InitTypeDef类型的结构体*/
  391. __HAL_RCC_GPIOE_CLK_ENABLE();
  392. GPIO_InitStructure.Pin = DS1302_DATA;
  393. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // /设置引脚模式为输入
  394. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
  395. //GPIO_Init(GPIOE, &GPIO_InitStructure);
  396. HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
  397. }
  398. void Set_IO_INPUT(void)
  399. {
  400. GPIO_InitTypeDef GPIO_InitStructure; /*定义一个GPIO_InitTypeDef类型的结构体*/
  401. __HAL_RCC_GPIOE_CLK_ENABLE();
  402. GPIO_InitStructure.Pin = DS1302_DATA;
  403. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;//GPIO_MODE_INPUT; // /设置引脚模式为输入
  404. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
  405. //GPIO_Init(GPIOE, &GPIO_InitStructure);
  406. HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
  407. }