STM32F407霸天虎HAL库CubeMX学习笔记——DS18B20

  • 一、软件准备
  • 二、硬件准备
  • 三、CubeMX配置
  • 四、Keil
    • printf重写
    • tim.c
    • DS18B20.h
    • DS18B20.c
      • DS18B20操作时序实现
        • 1、 复位信号:
        • 2、向DS18B20写一个字节时序
        • 3、从DS18B20读取一个字节数据时序
        • 4、DS18B20读取温度函数实现
    • Main.c
  • 五、实验效果

一、软件准备

软件准备

二、硬件准备

STM32F407霸天虎
DAP高速下载器
USB转串口线
DS18B20温度传感器

工作原理
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。

三、CubeMX配置

STM32F407霸天虎用的是STM32F407ZGT6

选择外部高速时钟


我们这里选择LED_B,又因为霸道开发板上的LED是默认低电平点亮的,所以这里我们GPIO选择默认输出高电平

根据STM32F407霸道开发板原理图可以知道DS18B20的数据引脚是在PE3上

这里配置PE3为输出模式,其他具体配置如下:

USART1选择异步通信,其他配置默认

时钟树选择168MHz,具体配置方法见上篇的时钟树配置

因为DS18B20是单总线通讯,所以我们这里需要使用到us微秒级别的延时,选择普通定时器TIM6,具体配置如下:

PSC填写168-1,这是在STM32芯片定义好了的公式,实际上用到的还是168

而后根据自己的喜好编辑工程的名称,存放位置,IDE选择ARM-MDKV5

最后点击

到此CubeMX的配置就完成了。

四、Keil

由于我们的Debug用的是DAP,如图下选择Debug和下载配置

printf重写

首先勾选Use MicroLIB调用MDK的微库,MicroLIB是对C标准库高度优化之后的库,比标准库代码更少,使用效率更高。

添加至usart.c文件的用户自定义代码块1中
这里直接操作寄存器来发送,效率更高

#if 1
#include <stdio.h>
int fputc(int ch,FILE *stream)
{//阻塞判断串口是否发送完成while((USART1->SR & 0x40)==0);//串口发送完成,将发送该字符USART1->DR = (uint8_t)ch;return ch;
}
#endif

tim.c

在该文件的最末尾加上us函数

void delay_us(uint16_t us)
{uint16_t differ=0xffff-us-5;   //设定定时器计数器起始值 HAL_TIM_Base_Start(&htim6);           //启动定时器__HAL_TIM_SetCounter(&htim6,differ); while(differ < 0xffff-5)                     //补偿,判断            { differ = __HAL_TIM_GetCounter(&htim6);   //查询计数器的计数值 } HAL_TIM_Base_Stop(&htim6);}

DS18B20.h

先在DS18B20.h中宏定义封装以下函数:

  1. GPIO输出模式配置
  2. GPIO输入模式配置
  3. GPIO输出高电平
  4. GPIO输出低电平
  5. GPIO读取输入
    相关引脚定义已在mian.h文件中
#ifndef      __DS18B20_H
#define     __DS18B20_H#include "main.h"
#include "tim.h"
#include "usart.h"
#include <stdio.h>//IO方向设置
#define DS18B20_IO_IN()  {DS18B20_GPIO_Port->MODER&=~(3<<(3*2));DS18B20_GPIO_Port->MODER|=0<<3*2;}  //PE3输入模式
#define DS18B20_IO_OUT() {DS18B20_GPIO_Port->MODER&=~(3<<(3*2));DS18B20_GPIO_Port->MODER|=1<<3*2;}  //PE3输出模式/* DS18B20控制IO操作函数 */
#define DS18B20_Out(n)        (n? HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_RESET))
#define DS18B20_In()           HAL_GPIO_ReadPin(DS18B20_GPIO_Port,DS18B20_Pin)void DS18B20_Init(void);
uint16_t DS18B20_Read_Temperature(void);#endif

DS18B20.c

DS18B20操作时序实现

1、 复位信号:

此部分在DS18B20.c中实现

/*** @brief    发送复位信号* @param    none* @retval   none
*/
static void DS18B20_Reset(void)
{//设置DS18B20为输出模式DS18B20_IO_OUT();//拉低总线480-960usDS18B20_Out(0);delay_us(660);//释放总线15-60usDS18B20_Out(1);delay_us(30);
}
/*** @brief    检测DS18B20存在脉冲* @param    none* @retval   0 DS18B20设备正常* @retval   1  DS18B20设备响应复位信号失败* @retval   2  DS18B20设备释放总线失败
*/
static uint8_t DS18B20_Check_Pulse(void)
{uint8_t cnt = 0;//检测是否存在脉冲DS18B20_IO_IN();//等待DS18B20 拉低总线 (60~240 us 响应复位信号)while (DS18B20_In() && cnt < 240) {delay_us(1);cnt++;}if (cnt > 240) {return 1;}/* 2.检测DS18B20是否释放总线 */    cnt = 0;DS18B20_IO_IN();
//判断DS18B20是否释放总线(60~240 us 响应复位信号之后会释放总线)while ((!DS18B20_In()) && cnt<240) {delay_us(1);cnt++;}if (cnt > 240) {return 2;} else {return 0;}
}/*** @brief    检测DS18B20是否正常* @param    none* @retval   0 DS18B20设备正常* @retval   1  DS18B20设备响应复位信号失败* @retval   2  DS18B20设备释放总线失败
*/
static uint8_t DS18B20_Check(void)
{//发送复位信号DS18B20_Reset();//检测是否存在脉冲return DS18B20_Check_Pulse();
}/*** @brief    DS18B20初始化* @param    none* @retval   none
*/
void DS18B20_Init(void)
{if(DS18B20_Check() == 0){printf("DS18B20设备初始化成功!\r\n");}else if(DS18B20_Check() == 1){printf("DS18B20设备响应复位信号失败!\r\n");}else{printf("DS18B20设备释放总线失败!\r\n");}
}

2、向DS18B20写一个字节时序

代码如下:

/*** @brief    向DS18B20写一个字节* @param    cmd 要写入的字节* @retval   none
*/
static uint8_t DS18B20_Write_Byte(uint8_t cmd)
{uint8_t i = 0;/* 1. 设置总线为输出模式 */DS18B20_IO_OUT();/* 2. 发送数据,低位在前 */for (i = 0; i < 8; i++) {DS18B20_Out(0);delay_us(2);  DS18B20_Out(cmd & 0x01);delay_us(60);DS18B20_Out(1);cmd >>= 1;delay_us(2);}return 0;
}

3、从DS18B20读取一个字节数据时序


代码如下:

/*** @brief    从DS18B20读一个字节* @param    none* @retval   读取到的一个字节数据
*/
uint8_t DS18B20_Read_Byte(void)
{uint8_t i = 0;uint8_t data = 0;/* 读取数据 */for (i  =0; i < 8; i++)   {DS18B20_IO_OUT();DS18B20_Out(0);  delay_us(2);DS18B20_Out(1);DS18B20_IO_IN();delay_us(10);data >>= 1 ;if (DS18B20_In()) {data |= 0x80;}delay_us(60);DS18B20_Out(1);}return data;
}

4、DS18B20读取温度函数实现

温度转换指令:0x44(启动Ds18b20启动转换温度)
读暂存器指令:0xBE(读取暂存器中的九字节数据)

代码如下:

/*** @brief    从DS18B20读取一次数据* @param    none* @retval   读取到的温度数据* @note     适用于总线上只有一个DS18B20的情况
*/
uint16_t DS18B20_Read_Temperature(void)
{uint16_t temp = 0;uint8_t  temp_H, temp_L;DS18B20_Check();DS18B20_Write_Byte(0xCC);DS18B20_Write_Byte(0x44);while (DS18B20_Read_Byte() != 0xFF);DS18B20_Check();   //必须,不能省略DS18B20_Write_Byte(0xCC);DS18B20_Write_Byte(0xBE); temp_L = DS18B20_Read_Byte(); temp_H = DS18B20_Read_Byte(); temp   = temp_L | (temp_H << 8);return temp;
}

Main.c

在头文件包含处添加代码:

/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "ds18b20.h"
/* USER CODE END Includes */

添加变量:

/* USER CODE BEGIN PV */
uint16_t temp;
int      intT, decT;
/* USER CODE END PV */

在main函数里添加

  /* USER CODE BEGIN 2 */printf("\r\nhi! 物联网小白Jayce!\r\n");printf("DS18B20 Test!\r\n");DS18B20_Init();/* USER CODE END 2 */

在while循环里添加

     temp = DS18B20_Read_Temperature();intT   = temp >> 4 ;          /*合成实际温度整数部分****精度相对上面的更高*/ decT   = temp & 0xF ;         /*合成实际温度小数部分*/HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin);printf("当前温度为:%d.%d℃\r\n", intT, decT);    HAL_Delay(1000);HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin);

五、实验效果

开发板上蓝灯每闪一次就打印一次温度信息

STM32F407霸天虎HAL库CubeMX学习笔记——DS18B20相关推荐

  1. STM32F407霸天虎HAL库学习笔记——串口发送

    STM32F407霸天虎HAL库学习笔记--串口收发 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil printf重写 main函数 五.实验效果 一.软件准备 软件准备 二.硬件准备 ...

  2. STM32F407霸天虎HAL库学习笔记——使用ADC采集MQ135的数据并通过OLED显示

    STM32F407霸天虎HAL库学习笔记--使用ADC采集MQ135的数据并通过OLED显示 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil MQ135.c MQ135.h main函 ...

  3. STM32 HAL库开发学习笔记: USART1串口通讯(中断方式) IDE-STM32CubeIDE

    STM32串口通讯有三种方式,分别为阻塞(轮询).中断.DMA.这里将用中断的方式开发. 笔者也是刚入门STM32 HAL库开发,该笔记致希望于能帮到初学者,文中配置步骤.代码.实验现象均是笔者实践可 ...

  4. hal库开启中断关中断_stm32的HAL库开发学习笔记之外部中断

    外部中断 中断线----EXTI线0~15(对应外部IO口的输入中断) 每个IO口都可以作为外部中断输入 每个中短线可以独立的配置触发方式(上升沿,下降沿,双边沿),触发/屏蔽,专用状态位. GPIO ...

  5. 【STM32】标准库与HAL库对照学习教程六--位带操作

    [STM32]标准库与HAL库对照学习教程六--位带操作 一.前言 二.准备工作 三.位带介绍 1.位带操作 2.STM32位带及位带别名区域 四.位带区与位带别名区地址转换 五.GPIO的位带操作 ...

  6. 【STM32】标准库与HAL库对照学习教程八--串口通信详解

    [STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...

  7. 【STM32】标准库与HAL库对照学习教程十三--软件IIC控制AT24C02

    [STM32]标准库与HAL库对照学习教程十三--软件IIC控制AT24C02 一.前言 二.准备工作 三.AT24C02(EEPROM)介绍 1.AT24C02简介 2.引脚功能 3.设备地址 四. ...

  8. 【STM32】标准库与HAL库对照学习教程外设篇--红外避障传感器

    [STM32]标准库与HAL库对照学习教程外设篇--红外避障传感器 一.前言 二.准备工作 三.红外避障传感器 1.传感器原理说明 2.传感器特性 四.标准库使用红外传感器 1.实验程序 2.实验效果 ...

  9. 【STM32】STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲

    [STM32]STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲 一.前言 二.时钟是什么 三.时钟树 1.时钟树图 2.时钟树讲解 左边部分 中间部分 右边部分 特殊部分 四.初始化 ...

最新文章

  1. 8Manage CRM:智能时代会员“赢”销之宝
  2. python拟合曲线误差分析_python曲线拟合不能给出合理的拟合结果
  3. IDEA创建mavenWeb项目笔记
  4. C语言指针变量与一维数组
  5. ModelArts黑科技揭秘|模型智能评估、诊断,让模型来个“体检
  6. TensorFlow Seq2Seq
  7. Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere
  8. AndroidStudio安卓原生开发_UI控件介绍---Android原生开发工作笔记96
  9. 任正非回应一切:今天的困难十多年前就有预计(附问答实录)
  10. MongoDB在windows下的安装步骤:
  11. IOS中获取屏幕尺寸
  12. 雷诺方程推导及FDM求解
  13. Docker学习笔记:Centos7镜像时区修改
  14. 软件项目的规模、工作量和成本是如何进行估算或评估的?
  15. Android 抽屉用法
  16. WeUI实例(官方)
  17. [PATCH] ARM: add dtbImage.dt and dtbuImage.dt rules
  18. 【Matlab图像去噪】改进非局部均值红外图像混合噪声【含源码 1640期】
  19. Java后端解密微信小程序手机号数据
  20. D1-阿里音乐流行趋势预测竞赛数据清洗整合——纯python

热门文章

  1. 计算机函数成绩排名,EXCEL工具程序:成绩排名
  2. Python学习—— 用python来买彩票
  3. 初学编程两年多学习的总结!
  4. 数字计算机模拟计算机工作原理,数字计算机模拟计算机分类依据
  5. twisted reactor 实现源码解析
  6. 完美解决Column ‘xxx‘ in field list is ambiguous问题
  7. Python 中的find()函数
  8. SolidWorks2020安装教程
  9. Python获取视屏的帧率和总帧数
  10. 历史大讲堂:冷到没朋友的冷知识 Windows命令提示符为什么跟DOS那么像?