[STM32F4] STM32 HAL库函数驱动DB18B20

[复制链接]
561|17
 楼主| yiyigirl2014 发表于 2023-3-27 21:08 | 显示全部楼层 |阅读模式
以下是一个基于STM32 HAL库函数的DB18B20驱动示例,假设使用的是STM32F4系列芯片。

首先,需要在STM32CubeMX中配置GPIO引脚,将其用作1-wire总线引脚。这可以通过以下步骤完成:
打开STM32CubeMX,创建一个新的工程
在“Pinout & Configuration”选项卡中,找到要用作1-wire总线引脚的GPIO引脚。
单击该引脚,将其配置为GPIO输出模式,初始电平为高电平(上拉模式)。
在代码中包含必要的头文件:
  1. #include "stm32f4xx_hal.h"
  2. #include <string.h>
  3. #include <stdio.h>
定义DS18B20的命令和常量:
  1. #define DS18B20_SKIP_ROM                0xCC
  2. #define DS18B20_CONVERT_T               0x44
  3. #define DS18B20_READ_SCRATCHPAD         0xBE
  4. #define DS18B20_RESOLUTION              0x1F
  5. #define DS18B20_DATA_SIZE               9
在代码中定义相关变量:
  1. GPIO_InitTypeDef GPIO_InitStruct = {0};
  2. TIM_HandleTypeDef htim3 = {0};
  3. UART_HandleTypeDef huart2 = {0};
编写DS18B20初始化函数:
  1. void ds18b20_init(void)
  2. {
  3.   GPIO_InitStruct.Pin = GPIO_PIN_0;
  4.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  5.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  6.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  7.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  8.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
  9.   HAL_Delay(480);
  10.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  11.   HAL_Delay(50);
  12.   HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
  13.   HAL_Delay(480);
  14. }
编写DS18B20发送命令函数:
  1. void ds18b20_send_cmd(uint8_t cmd)
  2. {
  3.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
  4.   HAL_Delay(2);
  5.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  6.   HAL_Delay(10);
  7.   for (uint8_t i = 0; i < 8; i++) {
  8.     if (cmd & (1 << i)) {
  9.       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
  10.       HAL_Delay(2);
  11.       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  12.       HAL_Delay(60);
  13.     } else {
  14.       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
  15.       HAL_Delay(60);
  16.       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  17.       HAL_Delay(2);
  18.     }
  19.   }
  20. }


 楼主| yiyigirl2014 发表于 2023-3-27 21:09 | 显示全部楼层
本帖最后由 yiyigirl2014 于 2023-3-27 21:13 编辑

编写DS18B20读取数据函数:
  1. void ds18b20_read_data(uint8_t *data)
  2. {
  3.   ds18b20_send_cmd(DS18B20_SKIP_ROM);
  4.   ds18b20_send_cmd(DS18B20_CONVERT_T);
  5.   HAL_Delay(750);
  6.   ds18b20_send_cmd(DS18B20_SKIP_ROM
  7.   ds18b20_send_cmd(DS18B20_READ_SCRATCHPAD);
  8.   for (uint8_t i = 0; i < DS18B20_DATA_SIZE; i++)
  9.   {
  10.     data[i] = 0;
  11.     for (uint8_t j = 0; j < 8; j++) {
  12.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
  13.     HAL_Delay(2);
  14.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  15.     HAL_Delay(2);
  16.     if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)) {
  17.     data[i] |= (1 << j);
  18.     }
  19.    HAL_Delay(60);
  20.   }
  21.   }
  22. }
 楼主| yiyigirl2014 发表于 2023-3-27 21:10 | 显示全部楼层
编写DS18B20读取温度值函数:
  1. float ds18b20_read_temp(void)
  2. {
  3.   uint8_t data[DS18B20_DATA_SIZE];
  4.   ds18b20_read_data(data);

  5.   uint16_t raw_temp = data[0] | (data[1] << 8);
  6.   uint8_t resolution = (data[4] & DS18B20_RESOLUTION) >> 5;
  7.   float temp = (float)raw_temp / 16.0f;

  8.   if (resolution == 0) {
  9.     temp *= 0.5f;
  10.   } else if (resolution == 2) {
  11.     temp *= 2.0f;
  12.   } else if (resolution == 3) {
  13.     temp *= 4.0f;
  14.   }

  15.   return temp;
  16. }

 楼主| yiyigirl2014 发表于 2023-3-27 21:11 | 显示全部楼层
在main函数中调用DS18B20初始化函数和读取温度值函数:
  1. int main(void)
  2. {
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   MX_GPIO_Init();
  6.   MX_USART2_UART_Init();
  7.   MX_TIM3_Init();

  8.   ds18b20_init();
  9.   float temp = ds18b20_read_temp();

  10.   char buf[32];
  11.   snprintf(buf, sizeof(buf), "Temperature: %.2f\r\n", temp);
  12.   HAL_UART_Transmit(&huart2, (uint8_t*)buf, strlen(buf), HAL_MAX_DELAY);

  13.   while (1) {}
  14. }
 楼主| yiyigirl2014 发表于 2023-3-27 21:11 | 显示全部楼层
这个示例代码假设您已经配置了UART并且使用了printf函数,如果您没有配置UART或者不使用printf函数,可以根据您的需求进行修改。另外,这个示例代码只是提供一个基本的DS18B20驱动方法,您可以根据您的具体需求进行修改和完善。
Clyde011 发表于 2024-1-27 09:08 | 显示全部楼层

需要设定一个阈值来对像素点进行设置
Uriah 发表于 2024-1-27 12:07 | 显示全部楼层

二值化就是让图像的像素点矩阵中的每个像素点的灰度值为0(黑色)或者255(白色
您需要登录后才可以回帖 登录 | 注册

本版积分规则

230

主题

3676

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部