STM32F407霸天虎HAL库CubeMX学习笔记——DS18B20
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中宏定义封装以下函数:
- GPIO输出模式配置
- GPIO输入模式配置
- GPIO输出高电平
- GPIO输出低电平
- 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相关推荐
- STM32F407霸天虎HAL库学习笔记——串口发送
STM32F407霸天虎HAL库学习笔记--串口收发 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil printf重写 main函数 五.实验效果 一.软件准备 软件准备 二.硬件准备 ...
- STM32F407霸天虎HAL库学习笔记——使用ADC采集MQ135的数据并通过OLED显示
STM32F407霸天虎HAL库学习笔记--使用ADC采集MQ135的数据并通过OLED显示 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil MQ135.c MQ135.h main函 ...
- STM32 HAL库开发学习笔记: USART1串口通讯(中断方式) IDE-STM32CubeIDE
STM32串口通讯有三种方式,分别为阻塞(轮询).中断.DMA.这里将用中断的方式开发. 笔者也是刚入门STM32 HAL库开发,该笔记致希望于能帮到初学者,文中配置步骤.代码.实验现象均是笔者实践可 ...
- hal库开启中断关中断_stm32的HAL库开发学习笔记之外部中断
外部中断 中断线----EXTI线0~15(对应外部IO口的输入中断) 每个IO口都可以作为外部中断输入 每个中短线可以独立的配置触发方式(上升沿,下降沿,双边沿),触发/屏蔽,专用状态位. GPIO ...
- 【STM32】标准库与HAL库对照学习教程六--位带操作
[STM32]标准库与HAL库对照学习教程六--位带操作 一.前言 二.准备工作 三.位带介绍 1.位带操作 2.STM32位带及位带别名区域 四.位带区与位带别名区地址转换 五.GPIO的位带操作 ...
- 【STM32】标准库与HAL库对照学习教程八--串口通信详解
[STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...
- 【STM32】标准库与HAL库对照学习教程十三--软件IIC控制AT24C02
[STM32]标准库与HAL库对照学习教程十三--软件IIC控制AT24C02 一.前言 二.准备工作 三.AT24C02(EEPROM)介绍 1.AT24C02简介 2.引脚功能 3.设备地址 四. ...
- 【STM32】标准库与HAL库对照学习教程外设篇--红外避障传感器
[STM32]标准库与HAL库对照学习教程外设篇--红外避障传感器 一.前言 二.准备工作 三.红外避障传感器 1.传感器原理说明 2.传感器特性 四.标准库使用红外传感器 1.实验程序 2.实验效果 ...
- 【STM32】STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲
[STM32]STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲 一.前言 二.时钟是什么 三.时钟树 1.时钟树图 2.时钟树讲解 左边部分 中间部分 右边部分 特殊部分 四.初始化 ...
最新文章
- 8Manage CRM:智能时代会员“赢”销之宝
- python拟合曲线误差分析_python曲线拟合不能给出合理的拟合结果
- IDEA创建mavenWeb项目笔记
- C语言指针变量与一维数组
- ModelArts黑科技揭秘|模型智能评估、诊断,让模型来个“体检
- TensorFlow Seq2Seq
- Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere
- AndroidStudio安卓原生开发_UI控件介绍---Android原生开发工作笔记96
- 任正非回应一切:今天的困难十多年前就有预计(附问答实录)
- MongoDB在windows下的安装步骤:
- IOS中获取屏幕尺寸
- 雷诺方程推导及FDM求解
- Docker学习笔记:Centos7镜像时区修改
- 软件项目的规模、工作量和成本是如何进行估算或评估的?
- Android 抽屉用法
- WeUI实例(官方)
- [PATCH] ARM: add dtbImage.dt and dtbuImage.dt rules
- 【Matlab图像去噪】改进非局部均值红外图像混合噪声【含源码 1640期】
- Java后端解密微信小程序手机号数据
- D1-阿里音乐流行趋势预测竞赛数据清洗整合——纯python
热门文章
- 计算机函数成绩排名,EXCEL工具程序:成绩排名
- Python学习—— 用python来买彩票
- 初学编程两年多学习的总结!
- 数字计算机模拟计算机工作原理,数字计算机模拟计算机分类依据
- twisted reactor 实现源码解析
- 完美解决Column ‘xxx‘ in field list is ambiguous问题
- Python 中的find()函数
- SolidWorks2020安装教程
- Python获取视屏的帧率和总帧数
- 历史大讲堂:冷到没朋友的冷知识 Windows命令提示符为什么跟DOS那么像?