当前位置:   article > 正文

STM32F1使用HAL库驱动DS18B20_stm32 ds18b20 hal库

stm32 ds18b20 hal库

目录

DS18B20概述

工程配置

 命令手册

单总线协议

 初始化时序

 写时序

读时序

读取温度

驱动附录


DS18B20概述

 DS18B20是一款单总线(one wire)芯片,因此其DQ引脚与单片机相连的IO口既要是输入也要是输出,cubeMX的初始化引脚设置只能选择其一,这里我们使用手动配置引脚。

工程配置

先用cubeMX生成一个工程模板,初始化时钟等等。

 命令手册

 这里有两个重要的指令,0x44表示触发芯片进行温度转化,0xbe表示请求读取温度转化后的值。

还有一个常用指令为0xCC,意义是跳过读取芯片ROM而节约时间。

单总线协议

由于是单总线协议,要想写指令,收数据都要遵循其标准,下面查看其时序

 初始化时序

单片机将DQ线拉低480us至960us后释放总线,ds18b20检测到总线电平变化,会等待15-60us,这段时间总线电平被电阻拉高,然后ds18b20会将总线拉低60-240us,作为应答信号,表明总线上存在ds18b20芯片。然后ds18b20释放总线,电阻将总线拉高。

整个过程为初始化

代码如下

  1. void onewire_init()
  2. {
  3. GPIO_InitTypeDef GPIO_InitStruct = {0};
  4. __HAL_RCC_GPIOB_CLK_ENABLE();
  5. GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
  6. GPIO_InitStruct.Pin=GPIO_PIN_9;
  7. GPIO_InitStruct.Pull=GPIO_NOPULL;
  8. GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
  9. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
  10. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  11. HAL_Delay_us(500);
  12. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
  13. HAL_Delay_us(50);
  14. onewire_release();
  15. HAL_Delay_us(500);
  16. }

用逻辑分析仪检测如下

实际应答时间约为110us 

 写时序

写时序分为写0时序和写1时序.

写0时序

单片机拉低总线,产生一个下降沿并保持总线低电平60us-120us,在这期间,18b20会在下降沿出现后大约15us-60us内读取总线电平。然后单片机释放总线,由上拉电阻拉高,直至下一次写时序,这段时间为恢复时间,需要大于1us

写1时序

单片机拉低总线,产生一个下降沿并保持总线低电平1-15us,在这期间,18b20会在下降沿出现后大约15us-60us内读取总线电平。然后单片机释放总线,由上拉电阻拉高,直至下一次写时序,这段时间为恢复时间,需要大于1us

  1. void onewire_write(uint8_t dat)
  2. {
  3. onewire_hold();
  4. if(dat==0)
  5. {
  6. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  7. HAL_Delay_us(60);
  8. onewire_release();
  9. HAL_Delay_us(2);
  10. }
  11. else
  12. {
  13. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  14. HAL_Delay_us(2);
  15. onewire_release();
  16. HAL_Delay_us(60);
  17. }
  18. }

读时序

 

读时序分为读0时序和读1时序

读0时序

单片机拉低总线并至少保持1us的总线低电平,然后释放总线,此时总线电平将由18b20决定,单片机在下降沿后15us处读取总线电平值,为低电平

读1时序

单片机拉低总线并至少保持1us的总线低电平,然后释放总线,此时总线电平将由18b20决定,单片机在下降沿后15us处读取总线电平值,为高电平

  1. uint8_t onewire_read()
  2. {
  3. uint8_t t;
  4. onewire_hold();
  5. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  6. HAL_Delay_us(2);
  7. onewire_release();
  8. HAL_Delay_us(12);
  9. t=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
  10. HAL_Delay_us(50);
  11. return t;
  12. }

读取温度

  1. float ds18b20_getTemp()
  2. {
  3. uint16_t temp;
  4. float value;
  5. uint8_t lsb,msb;
  6. onewire_init();
  7. onewire_sendbyte(0xcc);
  8. onewire_sendbyte(0x44);
  9. HAL_Delay(750);
  10. onewire_init();
  11. onewire_sendbyte(0xcc);
  12. onewire_sendbyte(0xbe);
  13. lsb=onewire_readbyte();
  14. msb=onewire_readbyte();
  15. temp=msb;
  16. temp=(temp<<8)+lsb;
  17. if((temp&0xf800)==0xf800)
  18. {
  19. temp=(~temp)+1;
  20. value=temp*(-0.0625);
  21. }
  22. else
  23. {
  24. value=temp*0.0625;
  25. }
  26. return value;
  27. }

逻辑分析仪波形

 上图为开启温度转化的引脚逻辑电平变化

上图为读取温度值

读取到的值为0000 0001 1011 1110

 由图可知为16*1+8*1+2*1+1*1+0.5+0.25+0.125=27.875°C

与串口显示温度值一致

 至此,ds18b20的温度转化,温度读取已经完成

驱动附录

onewire.c

  1. #include "onewire.h"
  2. void HAL_Delay_us(uint32_t nus)
  3. {
  4. uint32_t ticks;
  5. uint32_t told,tnow,tcnt=0;
  6. uint32_t reload=SysTick->LOAD;
  7. ticks=nus*72;
  8. told=SysTick->VAL;
  9. while(1)
  10. {
  11. tnow=SysTick->VAL;
  12. if(tnow!=told)
  13. {
  14. if(tnow<told)tcnt+=told-tnow;
  15. else tcnt+=reload-tnow+told;
  16. told=tnow;
  17. if(tcnt>=ticks)break;
  18. }
  19. }
  20. }
  21. void onewire_release()
  22. {
  23. GPIO_InitTypeDef GPIO_InitStruct = {0};
  24. GPIO_InitStruct.Mode=GPIO_MODE_INPUT;
  25. GPIO_InitStruct.Pull=GPIO_NOPULL;
  26. GPIO_InitStruct.Pin=GPIO_PIN_9;
  27. GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
  28. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
  29. }
  30. void onewire_hold()
  31. {
  32. GPIO_InitTypeDef GPIO_InitStruct = {0};
  33. GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
  34. GPIO_InitStruct.Pin=GPIO_PIN_9;
  35. GPIO_InitStruct.Pull=GPIO_PULLUP;
  36. GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
  37. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
  38. }
  39. void onewire_init()
  40. {
  41. GPIO_InitTypeDef GPIO_InitStruct = {0};
  42. __HAL_RCC_GPIOB_CLK_ENABLE();
  43. GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
  44. GPIO_InitStruct.Pin=GPIO_PIN_9;
  45. GPIO_InitStruct.Pull=GPIO_NOPULL;
  46. GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
  47. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
  48. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  49. HAL_Delay_us(500);
  50. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
  51. HAL_Delay_us(50);
  52. onewire_release();
  53. HAL_Delay_us(500);
  54. }
  55. void onewire_write(uint8_t dat)
  56. {
  57. onewire_hold();
  58. if(dat==0)
  59. {
  60. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  61. HAL_Delay_us(60);
  62. onewire_release();
  63. HAL_Delay_us(2);
  64. }
  65. else
  66. {
  67. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  68. HAL_Delay_us(2);
  69. onewire_release();
  70. HAL_Delay_us(60);
  71. }
  72. }
  73. uint8_t onewire_read()
  74. {
  75. uint8_t t;
  76. onewire_hold();
  77. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
  78. HAL_Delay_us(2);
  79. onewire_release();
  80. HAL_Delay_us(12);
  81. t=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
  82. HAL_Delay_us(50);
  83. return t;
  84. }
  85. void onewire_sendbyte(uint8_t dat)
  86. {
  87. uint8_t i;
  88. for(i=0;i<8;i++)
  89. {
  90. if((dat&0x01)==1)
  91. onewire_write(1);
  92. else
  93. onewire_write(0);
  94. dat=dat>>1;
  95. }
  96. }
  97. uint8_t onewire_readbyte(void) // read one byte
  98. {
  99. uint8_t i,j,dat;
  100. dat=0;
  101. for (i=1;i<=8;i++)
  102. {
  103. j=onewire_read();
  104. dat=(j<<7)|(dat>>1);
  105. }
  106. return dat;
  107. }

onewire.h

  1. #ifndef ONEWIRE_H
  2. #define ONEWIRE_H
  3. #include "main.h"
  4. void onewire_init();
  5. void onewire_write(uint8_t dat);
  6. uint8_t onewire_read();
  7. uint8_t onewire_readbyte(void);
  8. void onewire_sendbyte(uint8_t dat);
  9. #endif

ds18b20.c

  1. #include "ds18b20.h"
  2. #include "onewire.h"
  3. void ds18b20_init()
  4. {
  5. onewire_init();
  6. }
  7. float ds18b20_getTemp()
  8. {
  9. uint16_t temp;
  10. float value;
  11. uint8_t lsb,msb;
  12. onewire_init();
  13. onewire_sendbyte(0xcc);
  14. onewire_sendbyte(0x44);
  15. HAL_Delay(750);
  16. onewire_init();
  17. onewire_sendbyte(0xcc);
  18. onewire_sendbyte(0xbe);
  19. lsb=onewire_readbyte();
  20. msb=onewire_readbyte();
  21. temp=msb;
  22. temp=(temp<<8)+lsb;
  23. if((temp&0xf800)==0xf800)
  24. {
  25. temp=(~temp)+1;
  26. value=temp*(-0.0625);
  27. }
  28. else
  29. {
  30. value=temp*0.0625;
  31. }
  32. return value;
  33. }

ds18b20.h

  1. #ifndef DS18B20_H
  2. #define DS18B20_H
  3. #include "main.h"
  4. void ds18b20_init();
  5. float ds18b20_getTemp();
  6. #endif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/170661
推荐阅读
相关标签
  

闽ICP备14008679号