ds18b20.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "ds18b20.h"
  2. #include "delay.h"
  3. //复位DS18B20
  4. void DS18B20_Rst(void)
  5. {
  6. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  7. DS18B20_DQ_OUT=0; //拉低DQ
  8. delay_us(750); //拉低750us
  9. DS18B20_DQ_OUT=1; //DQ=1
  10. delay_us(15); //15US
  11. }
  12. //等待DS18B20的回应
  13. //返回1:未检测到DS18B20的存在
  14. //返回0:存在
  15. u8 DS18B20_Check(void)
  16. {
  17. u8 retry=0;
  18. DS18B20_IO_IN(); //SET PG11 INPUT
  19. while (DS18B20_DQ_IN&&retry<200)
  20. {
  21. retry++;
  22. delay_us(1);
  23. };
  24. if(retry>=200)return 1;
  25. else retry=0;
  26. while (!DS18B20_DQ_IN&&retry<240)
  27. {
  28. retry++;
  29. delay_us(1);
  30. };
  31. if(retry>=240)return 1;
  32. return 0;
  33. }
  34. //从DS18B20读取一个位
  35. //返回值:1/0
  36. u8 DS18B20_Read_Bit(void)
  37. {
  38. u8 data;
  39. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  40. DS18B20_DQ_OUT=0;
  41. delay_us(2);
  42. DS18B20_DQ_OUT=1;
  43. DS18B20_IO_IN(); //SET PG11 INPUT
  44. delay_us(12);
  45. if(DS18B20_DQ_IN)data=1;
  46. else data=0;
  47. delay_us(50);
  48. return data;
  49. }
  50. //从DS18B20读取一个字节
  51. //返回值:读到的数据
  52. u8 DS18B20_Read_Byte(void)
  53. {
  54. u8 i,j,dat;
  55. dat=0;
  56. for (i=1;i<=8;i++)
  57. {
  58. j=DS18B20_Read_Bit();
  59. dat=(j<<7)|(dat>>1);
  60. }
  61. return dat;
  62. }
  63. //写一个字节到DS18B20
  64. //dat:要写入的字节
  65. void DS18B20_Write_Byte(u8 dat)
  66. {
  67. u8 j;
  68. u8 testb;
  69. DS18B20_IO_OUT(); //SET PG11 OUTPUT;
  70. for (j=1;j<=8;j++)
  71. {
  72. testb=dat&0x01;
  73. dat=dat>>1;
  74. if (testb)
  75. {
  76. DS18B20_DQ_OUT=0; // Write 1
  77. delay_us(2);
  78. DS18B20_DQ_OUT=1;
  79. delay_us(60);
  80. }
  81. else
  82. {
  83. DS18B20_DQ_OUT=0; // Write 0
  84. delay_us(60);
  85. DS18B20_DQ_OUT=1;
  86. delay_us(2);
  87. }
  88. }
  89. }
  90. //开始温度转换
  91. void DS18B20_Start(void)
  92. {
  93. DS18B20_Rst();
  94. DS18B20_Check();
  95. DS18B20_Write_Byte(0xcc); // skip rom
  96. DS18B20_Write_Byte(0x44); // convert
  97. }
  98. //初始化DS18B20的IO口 DQ 同时检测DS的存在
  99. //返回1:不存在
  100. //返回0:存在
  101. u8 DS18B20_Init(void)
  102. {
  103. GPIO_InitTypeDef GPIO_InitStructure;
  104. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  105. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;
  106. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  107. /* Push-pill output, it can be other output types */
  108. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  109. GPIO_Init(GPIOB, &GPIO_InitStructure);
  110. DS18B20_Rst();
  111. return DS18B20_Check();
  112. }
  113. void Input_Mode(void)
  114. {
  115. GPIO_InitTypeDef GPIO_InitStructure;
  116. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PORTG.11 推挽输出
  117. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  118. GPIO_Init(GPIOB, &GPIO_InitStructure);
  119. }
  120. void Output_Mode(void)
  121. {
  122. GPIO_InitTypeDef GPIO_InitStructure;
  123. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PORTG.11 推挽输出
  124. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  125. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  126. GPIO_Init(GPIOB, &GPIO_InitStructure);
  127. }
  128. //从ds18b20得到温度值
  129. //精度:0.1C
  130. //返回值:温度值 (-550~1250)
  131. short DS18B20_Get_Temp(void)
  132. {
  133. u8 temp;
  134. u8 TL,TH;
  135. short tem;
  136. DS18B20_Start (); // ds1820 start convert
  137. DS18B20_Rst();
  138. DS18B20_Check();
  139. DS18B20_Write_Byte(0xcc); // skip rom
  140. DS18B20_Write_Byte(0xbe); // convert
  141. TL=DS18B20_Read_Byte(); // LSB
  142. TH=DS18B20_Read_Byte(); // MSB
  143. if(TH>7)
  144. {
  145. TH=~TH;
  146. TL=~TL;
  147. temp=0; //温度为负
  148. }else temp=1; //温度为正
  149. tem=TH; //获得高八位
  150. tem<<=8;
  151. tem+=TL; //获得底八位
  152. tem=(float)tem*0.625; //转换
  153. if(temp)return tem; //返回温度值
  154. else return -tem;
  155. }