DS1302.c 13 KB

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