ds18b20.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "ds18b20.h"
  2. #include "gd32f30x_libopt.h"
  3. #include "SysTick.h"
  4. #include "main.h"
  5. #define DS18B20_IO_IN() do { \
  6. gpio_init(GPIOC,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_1); \
  7. }while(0);
  8. #define DS18B20_IO_OUT() do { \
  9. gpio_init(GPIOC,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,GPIO_PIN_1); \
  10. gpio_bit_set(GPIOC,GPIO_PIN_1);\
  11. }while(0);
  12. //#define DS18B20_DQ_OUT PGout(11)
  13. //#define gpio_input_bit_get(GPIOC,GPIO_PIN_1) PGin(11)
  14. //复位DS18B20
  15. void DS18B20_Rst(void)
  16. {
  17. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  18. gpio_bit_reset(GPIOC,GPIO_PIN_1); //拉低DQ
  19. DelayNus(750); //拉低750us
  20. gpio_bit_set(GPIOC,GPIO_PIN_1); //DQ=1
  21. DelayNus(15); //15US
  22. }
  23. uint8_t DS18B20_Check(void)
  24. {
  25. uint8_t retry=0;
  26. DS18B20_IO_IN(); //SET PG11 INPUT
  27. while (gpio_input_bit_get(GPIOC,GPIO_PIN_1) && retry<200)
  28. {
  29. retry++;
  30. DelayNus(1);
  31. };
  32. if(retry>=200)return 1;
  33. else retry=0;
  34. while (!gpio_input_bit_get(GPIOC,GPIO_PIN_1) && retry<240)
  35. {
  36. retry++;
  37. DelayNus(1);
  38. };
  39. if(retry>=240)return 1;
  40. return 0;
  41. }
  42. //从DS18B20读取一个位
  43. //返回值:1/0
  44. uint8_t DS18B20_Read_Bit(void)
  45. {
  46. uint8_t data;
  47. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  48. gpio_bit_reset(GPIOC,GPIO_PIN_1);
  49. DelayNus(2);
  50. gpio_bit_set(GPIOC,GPIO_PIN_1);
  51. DS18B20_IO_IN(); //SET PG11 INPUT
  52. DelayNus(12);
  53. if(gpio_input_bit_get(GPIOC,GPIO_PIN_1))data=1;
  54. else data=0;
  55. DelayNus(50);
  56. return data;
  57. }
  58. //从DS18B20读取一个字节
  59. //返回值:读到的数据
  60. uint8_t DS18B20_Read_Byte(void)
  61. {
  62. uint8_t i,j,dat;
  63. dat=0;
  64. for (i=1;i<=8;i++)
  65. {
  66. j=DS18B20_Read_Bit();
  67. dat=(j<<7)|(dat>>1);
  68. }
  69. return dat;
  70. }
  71. //写一个字节到DS18B20
  72. //dat:要写入的字节
  73. void DS18B20_Write_Byte(uint8_t dat)
  74. {
  75. uint8_t j;
  76. uint8_t testb;
  77. DS18B20_IO_OUT(); //SET PG11 OUTPUT;
  78. for (j=1;j<=8;j++)
  79. {
  80. testb=dat&0x01;
  81. dat=dat>>1;
  82. if (testb)
  83. {
  84. gpio_bit_reset(GPIOC,GPIO_PIN_1); // Write 1
  85. DelayNus(2);
  86. gpio_bit_set(GPIOC,GPIO_PIN_1);
  87. DelayNus(60);
  88. }
  89. else
  90. {
  91. gpio_bit_reset(GPIOC,GPIO_PIN_1); // Write 0
  92. DelayNus(60);
  93. gpio_bit_set(GPIOC,GPIO_PIN_1);
  94. DelayNus(2);
  95. }
  96. }
  97. }
  98. //开始温度转换
  99. void DS18B20_Start(void)
  100. {
  101. DS18B20_Rst();
  102. DS18B20_Check();
  103. DS18B20_Write_Byte(0xcc); // skip rom
  104. DS18B20_Write_Byte(0x44); // convert
  105. }
  106. uint8_t DS18B20_Init(void)
  107. {
  108. gpio_init(GPIOC,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,GPIO_PIN_1); //设置GPIO输出模式及速度 SDA
  109. gpio_bit_set(GPIOC,GPIO_PIN_1);
  110. DS18B20_Rst();
  111. return DS18B20_Check();
  112. }
  113. static uint8_t count = 0;
  114. short DS18B20_Get_Temp(void)
  115. {
  116. sts_data_t *sts_d = get_sts();
  117. uint8_t temp = 0;
  118. uint8_t TL=0,TH=0;
  119. short tem=-550;
  120. DS18B20_Start (); // ds1820 start convert
  121. DS18B20_Rst();
  122. if(DS18B20_Check())
  123. {
  124. count++;
  125. if(count == 3)
  126. {
  127. sts_d->m_data.temprature_flag = 0;
  128. count = 0;
  129. }
  130. return tem;
  131. }else
  132. {
  133. sts_d->m_data.temprature_flag = 1;
  134. }
  135. DS18B20_Write_Byte(0xcc); // skip rom
  136. DS18B20_Write_Byte(0xbe); // convert
  137. TL=DS18B20_Read_Byte(); // LSB
  138. TH=DS18B20_Read_Byte(); // MSB
  139. if(TH>7)
  140. {
  141. TH=~TH;
  142. TL=~TL;
  143. temp=0; //温度为负
  144. }else temp=1; //温度为正
  145. tem=TH; //获得高八位
  146. tem<<=8;
  147. tem+=TL; //获得底八位
  148. tem=(float)tem*0.625; //转换
  149. if(temp)return tem; //返回温度值
  150. else return -tem;
  151. }