驱动程序一:基于STM32自码 DS18B20驱动程序

为了加深对于底层驱动开发的认识和理解,楼主决定自撸常见模块,传感器的驱动程序。-------立贴为证。

DS18B20是一款单总线可编程分辨率的数字温度计,详细内容可见中英文datasheet,笔者不在赘述。

很早就接触到的温度传感器,也相信每一个曾学习过嵌入式开发的人都用过,笔者在STM32F4上自码DS18B20驱动,有些小小心得:

1.初始化时序要注意,笔者亲测,在MCU控制单总线为低电平240us即可(数据手册上要求至少480us)释放总线,等待60us后即可检测到到DS18B20返回的拉低单总线信号,此处,需注意至少应在此等待120us,否则可能会导致温度传感器无法正常工作。


2.初学者需注意时序,对于DS18B20的操作都必需经过三步:初始化,ROM命令(多为跳过指令0xCC),DS18B20功能命令。再次强调对其的每一个操作必须经过这三步,可阅读code加深理解。

3.在读取DS18B20时,注意顺序,DS18B20先发送低位,在字节读取时应当注意。

4.初学者应尝试实现对于DS18B20内部ROM的8位系列号(28H),和48位唯一序列号进行读取,以及修改温度传感器内部EEPROM的过温、低温报警值。(可参考笔者code)


废话不多说,上码:

#include <ds18b20.h>
#include "delay.h"
#include "usart.h"	

//ds18b20初始化
void  init_ds18b20( void )
{
	init_onewire_out();
	GPIO_ResetBits(GPIOG,GPIO_Pin_9);
	delay_us(480);
	init_onewir
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是基于HAL库的STM32F407驱动DS18B20的示例程序: ```c #include "stm32f4xx_hal.h" #define DS18B20_PORT GPIOA #define DS18B20_PIN GPIO_PIN_0 void delay_us(uint32_t us) { uint32_t time = us * (SystemCoreClock / 1000000) / 5; while(time--); } void ds18b20_init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = DS18B20_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); delay_us(60); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct); while(HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN) == GPIO_PIN_RESET); while(HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN) == GPIO_PIN_SET); delay_us(40); } void ds18b20_write_bit(uint8_t bit) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(2); if(bit) { HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); } delay_us(60); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); } uint8_t ds18b20_read_bit(void) { uint8_t bit = 0; HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET); delay_us(10); bit = HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN); delay_us(50); return bit; } void ds18b20_write_byte(uint8_t byte) { uint8_t bit; for(int i = 0; i < 8; i++) { bit = byte & 0x01; byte >>= 1; ds18b20_write_bit(bit); } } uint8_t ds18b20_read_byte(void) { uint8_t byte = 0; for(int i = 0; i < 8; i++) { byte >>= 1; byte |= (ds18b20_read_bit() << 7); } return byte; } float ds18b20_read_temperature(void) { uint8_t scratchpad[9]; float temperature; ds18b20_init(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0x44); HAL_Delay(750); ds18b20_init(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0xBE); for(int i = 0; i < 9; i++) { scratchpad[i] = ds18b20_read_byte(); } temperature = scratchpad[0] | (scratchpad[1] << 8); temperature /= 16.0f; return temperature; } int main(void) { float temperature; HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); while(1) { temperature = ds18b20_read_temperature(); // Do something with the temperature value } } ``` 此示例中,我们使用PA0作为DS18B20的数据线。ds18b20_init函数用于初始化DS18B20ds18b20_read_temperature函数用于读取温度值。我们首先发送跳过ROM命令(0xCC),然后发送转换命令(0x44),等待750ms,再次发送跳过ROM命令和读取温度命令(0xBE),以读取DS18B20的温度值。最终,我们将温度值除以16.0,以获得实际温度值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值