DS18B20_ATY.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /**
  2. * @file DS18B20_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of DS18B20 for all embedded device
  20. *
  21. * @version
  22. * - 1_01_220927 > ATY
  23. * -# Preliminary version, first Release
  24. * - Undone
  25. ********************************************************************************
  26. */
  27. #ifndef __DS18B20_ATY_C
  28. #define __DS18B20_ATY_C
  29. #include "DS18B20_ATY.h"
  30. /******************************* For user *************************************/
  31. /******************************************************************************/
  32. #include "DS18B20.h"
  33. #include "delay.h"
  34. #include "usart.h"
  35. u8 ROM_ID[8];
  36. u8 Refresh_OLED_Data = 0;
  37. /*******************************************
  38. DS18B20 单总线对延时精度要求非常高!!!
  39. 本程序使用了系统嘀嗒定时器来当做精准延时。
  40. DQ :GPIOB_7
  41. *******************************************/
  42. /*功能:DS18B20初始化*/
  43. void DS18B20_Init(void)
  44. {
  45. /*1.GPIOC口初始化*/
  46. RCC->APB2ENR |= 1 << 3;
  47. GPIOB->CRL &= 0x0FFFFFFF;
  48. GPIOB->CRL |= 0x30000000;
  49. GPIOB->ODR |= 1 << 7;
  50. /*2.检测DS18B20设备是否正常*/
  51. switch(DS18B20_CheckDevice())
  52. {
  53. case 0: printf("DS18B20_Init OK!\n"); break;
  54. case 1: printf("DS18B20设备响应复位信号失败!\n"); break;
  55. case 2: printf("DS18B20设备释放总线失败!\n"); break;
  56. }
  57. }
  58. /*功能:向DS18B20发送一个复位信号*/
  59. void DS18B20_SendRestSingle(void)
  60. {
  61. /*主机发送复位信号*/
  62. DS18B20_OutPut_Mode();
  63. DS18B20_OUT = 0; //拉低总线480~960 us ,对 DS18B20 芯片进行复位
  64. DelayUs(750);
  65. DS18B20_OUT = 1;
  66. DelayUs(15); //释放总线15~60 us
  67. }
  68. /*
  69. 功能:检测DS18B20存在脉冲
  70. 返回值:
  71. 0 DS18B20设备正常
  72. 1 DS18B20设备响应复位信号失败
  73. 2 DS18B20设备释放总线失败
  74. */
  75. u8 DS18B20_CheckReadySingle(void)
  76. {
  77. u8 cnt = 0;
  78. /*1.检测存在脉冲*/
  79. DS18B20_InPut_Mode();
  80. while(DS18B20_IN && cnt < 240) //等待DS18B20 拉低总线 (60~240 us 响应复位信号)
  81. {
  82. DelayUs(1);
  83. cnt++;
  84. }
  85. if(cnt > 240) return 1;
  86. /*2.检测DS18B20是否释放总线*/
  87. cnt = 0;
  88. DS18B20_InPut_Mode();
  89. while((!DS18B20_IN) && cnt < 240) //判断DS18B20是否释放总线(60~240 us 响应复位信号之后会释放总线)
  90. {
  91. DelayUs(1);
  92. cnt++;
  93. }
  94. if(cnt > 240) return 2;
  95. else return 0;
  96. }
  97. /*
  98. 功能:检测DS18B20设备是否正常
  99. 返回值:
  100. 0 DS18B20设备正常
  101. 1 DS18B20设备响应复位信号失败
  102. 2 DS18B20设备释放总线失败
  103. */
  104. u8 DS18B20_CheckDevice(void)
  105. {
  106. DS18B20_SendRestSingle();/*1.主机发送复位信号*/
  107. return DS18B20_CheckReadySingle();/*2.检测存在脉冲*/
  108. }
  109. /*功能:向DS18B20写一个字节数据(命令)*/
  110. u8 BS18B20_WriteByte(u8 cmd)
  111. {
  112. u8 i = 0;
  113. DS18B20_OutPut_Mode();
  114. for(i = 0; i < 8; i++)
  115. {
  116. DS18B20_OUT = 0;
  117. DelayUs(2); //主机拉低总线写数据时间隙2us
  118. DS18B20_OUT = cmd & 0x01; //如果该写入位为1,必须在15us之内把总线拉高,为0 保持60us即可。
  119. DelayUs(60); //确保DS18B20已经成功读取到该位数据
  120. DS18B20_OUT = 1; //一位发送完成
  121. cmd >>= 1;
  122. DelayUs(2); //位间隙2us
  123. }
  124. return 0;
  125. }
  126. /*功能:从DS18B20读取一个字节数据*/
  127. u8 DS18B20_ReadByte(void)
  128. {
  129. u8 i, data = 0;
  130. for(i = 0; i < 8; i++)
  131. {
  132. DS18B20_OutPut_Mode();//初始化为输出模式
  133. DS18B20_OUT = 0;
  134. DelayUs(2); //主机拉低总线读数据时间隙2us
  135. DS18B20_OUT = 1; //释放总线,准备读取位数据
  136. DS18B20_InPut_Mode(); //初始化为输入模式
  137. DelayUs(10); //等待DS18B20的数据输出
  138. data >>= 1; //高位补0,默认以0为准
  139. if(DS18B20_IN) data |= 0x80;
  140. DelayUs(60); //延时确保DS18B20采样周期已经过去(非常重要)
  141. DS18B20_OUT = 1; //释放总线准备读取下一位位数据
  142. }
  143. return data;
  144. }
  145. /*
  146. 函数功能: 读取一次DS18B20的温度数据
  147. 返 回 值: 读取的温度数据
  148. 考虑的情况: 总线上只是接了一个DS18B20的情况
  149. */
  150. u16 DS18B20_GetTemperature(void)
  151. {
  152. u16 temp = 0;
  153. u8 temp_H, temp_L;
  154. int intT, decT;
  155. DS18B20_CheckDevice(); //发送复位脉冲、检测存在脉冲
  156. BS18B20_WriteByte(0xCC); //跳过ROM序列检测
  157. BS18B20_WriteByte(0x44); //启动一次温度转换
  158. //等待温度转换完成
  159. while(DS18B20_ReadByte() != 0xFF){}
  160. DS18B20_CheckDevice(); //发送复位脉冲、检测存在脉冲
  161. BS18B20_WriteByte(0xCC); //跳过ROM序列检测
  162. BS18B20_WriteByte(0xBE); //读取温度
  163. temp_L = DS18B20_ReadByte(); //读取的温度低位数据
  164. temp_H = DS18B20_ReadByte(); //读取的温度高位数据
  165. temp = temp_L | (temp_H << 8); //合成温度
  166. intT = temp >> 4; /*合成实际温度整数部分****精度相对上面的更高*/
  167. decT = temp & 0xF; /*合成实际温度小数部分*/
  168. printf("温度:%d.%d ℃ \n", intT, decT);
  169. return temp;
  170. }
  171. ///*功能:从DS18B20读取温度值,多点测温*/
  172. //u16 DS18B20_GetTemperature(void)
  173. //{
  174. // u16 temp;
  175. // u8 TL,TH;
  176. // DS18B20_SendRestSingle(); /*1.主机发送复位信号*/
  177. // if(DS18B20_CheckReadySingle()) return 0xFF; /*2.检测存在脉冲*/
  178. // DS18B20_MatchROM(); /*3.匹配 ROM 指令 (仅适用于总线上有多个设备)*/
  179. BS18B20_WriteByte(0xCC); /*3.跳跃 ROM 指令 (仅适用于总线上只有一个设备)*/
  180. // BS18B20_WriteByte(0x44); /*4.启动温度转换*/
  181. // while(DS18B20_ReadByte()!=0xFF); //等待温度转换成功
  182. // DS18B20_SendRestSingle(); /*5.主机发送复位信号*/
  183. // if(DS18B20_CheckReadySingle()) return 0xFF; /*6.检测存在脉冲*/
  184. // DS18B20_MatchROM(); /*6.匹配 ROM 指令 (仅适用于总线上有多个设备)*/
  185. BS18B20_WriteByte(0xCC); /*7.跳跃 ROM 指令 (仅适用于总线上只有一个设备)*/
  186. // BS18B20_WriteByte(0xBE); /*8.发送读取温度命令*/
  187. //
  188. // TL = DS18B20_ReadByte(); /*9.读取温度高低位、校验位*/
  189. // TH = DS18B20_ReadByte();
  190. // DS18B20_SendRestSingle(); /*10.主机发送复位信号,示意停止读取剩下的数据*/
  191. // temp = TH<<8 | TL; /*11.合成温度值*/
  192. // return temp;
  193. //
  194. temp = temp * 0.0625; /*直接合成实际温度*/
  195. value = temp * 100 + (value > 0 ? 0.5 : -0.5); //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
  196. //
  197. intT = temp >> 4; /*合成实际温度整数部分****精度相对上面的更高*/
  198. decT = temp & 0xF; /*合成实际温度小数部分*/
  199. ///* crc = x^8 + x^5 + x^4 + 1*/
  200. //}
  201. /*功能:从DS18B20读取ROM信息 (ROM_ID= 28-92-AF-AC-17-13-1-F1)*/
  202. u8 DS18B20_ReadRomInfo(void)
  203. {
  204. u8 i = 0;
  205. BS18B20_WriteByte(0x33); /*4.启动读取ROM*/
  206. for(i = 0; i < 8; i++)
  207. {
  208. ROM_ID[i] = DS18B20_ReadByte();
  209. }
  210. printf("ROM_ID= ");
  211. for(i = 0; i < 8; i++)
  212. {
  213. printf("%X", ROM_ID[i]);
  214. if(i == 7) printf("\n");
  215. else printf("-");
  216. }
  217. return 0;
  218. }
  219. /*
  220. ROM_ID[0]=0x28
  221. ROM_ID[1]=0x92
  222. ROM_ID[2]=0xAF
  223. ROM_ID[3]=0xAC
  224. ROM_ID[4]=0x17
  225. ROM_ID[5]=0x13
  226. ROM_ID[6]=0x1
  227. ROM_ID[7]=0xF1
  228. */
  229. /*功能:匹配 DS18B20 ROM信息*/
  230. u8 DS18B20_MatchROM(void)
  231. {
  232. u8 i = 0;
  233. BS18B20_WriteByte(0x55); /*4.匹配64位 ROM 信息*/
  234. for(i = 0; i < 8; i++)
  235. {
  236. BS18B20_WriteByte(ROM_ID[i]);
  237. }
  238. return 0;
  239. }
  240. #endif /* __DS18B20_ATY_C */
  241. /******************************** End Of File *********************************/