问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32F103 CubeMX 使用hal库控制DS18B20

创作时间:
作者:
@小白创作中心

STM32F103 CubeMX 使用hal库控制DS18B20

引用
CSDN
1.
https://blog.csdn.net/chen1658137632/article/details/136877983

本文详细介绍了如何使用STM32F103微控制器和CubeMX工具通过HAL库控制DS18B20温度传感器。内容涵盖硬件连接、CubeMX配置、程序编写等步骤,并提供了完整的代码示例。

硬件连接

需要购买一个DS18B20的模块,代码中使用 PB5 作为信号的连接。

CubeMX配置

  1. 配置debug口
  2. 配置外部晶振
  3. 配置串口
  4. 配置PB5 作为连接的GPIO
  5. 配置时钟72M
  6. 生成代码

程序编写

主要需要3段程序的编写:

  1. main函数的编写
  2. 18B20.c 函数的编写
  3. 18B20.h 函数的编写

main函数的编写

添加18b20 头文件

/* USER CODE BEGIN Includes */
#include "18b20.h"
/* USER CODE END Includes */

添加串口重定向

/* USER CODE BEGIN PV */
#include <stdio.h>
//重定向c库函数printf到串口USARTx,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口USARTx */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
    return (ch);
}
/* USER CODE END PV */

添加下面main函数的编写信息,进行了一个初始化,如果不成功就报错,成功的话就继续

int main(void)
{
  /* USER CODE BEGIN 1 */
  float temperature = 0;
  /* USER CODE END 1 */
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  //等待成功初始化
  while(DS18B20_Init())
  {
      printf("DS18B20 checked failed!!!\r\n");
      HAL_Delay(500);
  }
  printf("DS18B20 checked success!!!\r\n");
  while (1)
  {
       temperature = DS18B20_Get_Temperature();
       if(temperature < 0)
           printf("temperature = -%.2f degree\r\n",temperature/10);
       else
           printf("temperature = %.2f degree\r\n",temperature/10);
       HAL_Delay(200);
  }
}

下面就是18B20.c的文件

整体结构和正点原子的差不多,在移植的时候做了一些适配

#include "18b20.h"
/****************************************************************************
函数名:delay_us
功能:微秒级延时
输入:延时数据
输出:无
返回值:无
备注:
****************************************************************************/
void delay_us(uint32_t time)
{
  time *= 10;
  while(time)
    time--;
}
/****************************************************************************
函数名:DS18B20_IO_IN
功能:使DS18B20_DQ引脚变为输入模式
输入:无
输出:无
返回值:无
备注:DQ引脚为PA5
****************************************************************************/
void DS18B20_IO_IN(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.Pin = GPIO_PIN_5;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
}
/****************************************************************************
函数名:DS18B20_IO_OUT
功能:使DS18B20_DQ引脚变为推挽输出模式
输入:无
输出:无
返回值:无
备注:DQ引脚为PA5
****************************************************************************/
void DS18B20_IO_OUT(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.Pin = GPIO_PIN_5;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
}
/***************************************************************************
函数名:DS18B20_Rst
功  能:发送复位信号
输  入: 无
输  出:无
返回值:无
备  注:
***************************************************************************/
void DS18B20_Rst(void){
  DS18B20_IO_OUT();//引脚输出模式
  
  //拉低总线并延时750us
  DS18B20_DQ_OUT_LOW;
  delay_us(750);     
  
  //释放总线为高电平并延时等待15~60us
  DS18B20_DQ_OUT_HIGH;
  delay_us(15);
}
  
/***************************************************************************
函数名:DS18B20_Check
功  能:检测DS18B20返回的存在脉冲
输  入: 无
输  出:无
返回值:0:成功  1:失败   2:释放总线失败
备  注:
***************************************************************************/
uint8_t DS18B20_Check(void){
  //定义一个脉冲持续时间
  uint8_t retry = 0;
  //引脚设为输入模式
  DS18B20_IO_IN();
  while(DS18B20_DQ_IN && retry < 200){
    retry++;
    delay_us(1);
  }
  
  if(retry >= 200)
    return 1;
  else
    retry = 0;
  
  //判断DS18B20是否释放总线
  while(!DS18B20_DQ_IN && retry < 240){
    retry++;
    delay_us(1);
  }
  
  if(retry >= 240)
    return 2;
  
  return 0;
}
/***************************************************************************
函数名:DS18B20_Write_Byte
功  能:向DS18B20写一个字节
输  入: 要写入的字节
输  出:无
返回值:无
备  注:
***************************************************************************/
void DS18B20_Write_Byte(uint8_t data){
  uint8_t j;
  uint8_t databit;
  DS18B20_IO_OUT();
  for(j=1;j<=8;j++){
    databit=data&0x01;//取数据最低位
    data=data>>1;     //右移一位
    if(databit){      //当前位写1
      DS18B20_DQ_OUT_LOW;
      delay_us(2);
      DS18B20_DQ_OUT_HIGH;
      delay_us(60);
    }else{          //当前位写0
      DS18B20_DQ_OUT_LOW;
      delay_us(60);
      DS18B20_DQ_OUT_HIGH;
      delay_us(2);
    }
  }
}
/***************************************************************************
函数名:DS18B20_Read_Bit
功  能:向DS18B20读一个位
输  入: 无
输  出:无
返回值:读入数据
备  注:
***************************************************************************/
uint8_t DS18B20_Read_Bit(void){
  uint8_t data;
  DS18B20_IO_OUT();
  DS18B20_DQ_OUT_LOW;
  delay_us(2);
  DS18B20_DQ_OUT_HIGH;
  DS18B20_IO_IN();
  delay_us(12);
  
  if(DS18B20_DQ_IN)
    data = 1;
  else
    data = 0;
  
  delay_us(50);
  return data;
}
/***************************************************************************
函数名:DS18B20_Read_Byte
功  能:向DS18B20读一个字节
输  入: 无
输  出:无
返回值:读入数据
备  注:
***************************************************************************/
uint8_t DS18B20_Read_Byte(void){
  uint8_t i,j,data;
  data = 0;
  for(i=1;i<=8;i++){
    j = DS18B20_Read_Bit();
    data = (j<<7)|(data>>1);
    /*j=0或1,j<<7=0x00或0x80,和data右移一位相或,即把1/0写入最高位,下次再往右移位*/
  }
  return data;
}
/***************************************************************************
函数名:DS18B20_Start
功  能:DS18B20开启
输  入: 无
输  出:无
返回值:无
备  注:
***************************************************************************/
void DS18B20_Start(void){
  DS18B20_Rst();
  DS18B20_Check();
  DS18B20_Write_Byte(0xcc);//跳过ROM
  DS18B20_Write_Byte(0x44);//温度变换命令
}
/***************************************************************************
函数名:DS18B20_Init
功  能:DS18B20初始化
输  入: 无
输  出:无
返回值:无
备  注:
***************************************************************************/
uint8_t DS18B20_Init(void){
  //引脚初始化
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.Pin = GPIO_PIN_5;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull = GPIO_PULLUP;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
  
  DS18B20_Rst();
  return DS18B20_Check();
}
/***************************************************************************
函数名:DS18B20_Read_Temperature
功  能:读取一次温度
输  入: 无
输  出:无
返回值:读取到的温度数据
备  注:适用于总线上只有一个DS18B20的情况
***************************************************************************/
short DS18B20_Get_Temperature(uint8_t a){
  uint8_t temp;
  uint8_t TL,TH;
  short temperature;
  
  DS18B20_Start();
  DS18B20_Rst();
  DS18B20_Check();
  DS18B20_Write_Byte(0xcc);//跳过ROM
  DS18B20_Write_Byte(0xbe);//读暂存器
  TL = DS18B20_Read_Byte();//低八位
  TH = DS18B20_Read_Byte();//高八位
  
  //判断温度值是否为负数
  if(TH>0x70){
    TH = ~TH;
    TL = ~TL;
    temp = 0;
  }else
    temp = 1;
  
  temperature = TH;
  temperature <<= 8;
  temperature += TL;
  temperature = (float)temperature*0.625;
  if(temperature)
    return temperature;
  else
    return -temperature;
}

18b20.h文件

#include "main.h"
#define DQ_GPIO_Port GPIOB
#define DQ_Pin GPIO_PIN_5
#define  DS18B20_DQ_OUT_HIGH       HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET)
#define  DS18B20_DQ_OUT_LOW        HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET)
#define  DS18B20_DQ_IN             HAL_GPIO_ReadPin(DQ_GPIO_Port, DQ_Pin)
uint8_t DS18B20_Init(void);
short DS18B20_Get_Temperature(uint8_t a);
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号