STM32·HAL库开发(九)USART串口通信——案例:DHT11温湿度传感器
STM32开发之USART串口通信:案例:DHT11温湿度传感器数据发送到串口
·
目录
【demo · 串口打印温湿度:DHT11】
【驱动流程】
① 主机将DHT11数据引脚拉为低电平,持续至少18ms
② 主机将DHT11数据引脚拉为高电平,持续20~40us,等待DHT11响应
③ 如果DHT11存在,则会有80us的响应信号,此时数据引脚会被拉为低电平,否则数据引脚始终为高电平
④ 接下来控制权转移给DHT11,DHT11会继续把数据引脚拉高80us,然后开始返回数据
⑤ 首先,DHT11会拉低数据引脚50us,表示开始传输数据位
⑥ 接下来便是DHT11发送数据位,数据位的高低电平取决于数据位拉高的时间:如果数据位高电平的时间为26us~28us,则代表数据位是低电平 ‘0’;如果数据位高电平的时间为70us,则代表数据位是高电平 ‘1’
【数据格式】
40位数据=8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位
其中湿度小数部分为 0,且温度低位 Bit8 为 1 则表示负温度,否则为正温度
数据传送正确时,校验和数据=“ 8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据” 所得结果的末8位
【时序图】
【代码】
/* dht11.h */
#ifndef __DHT11_H__
#define __DHT11_H__
#include "main.h"
void DHT_GPIO_Init(uint32_t Mode); // DHT11 GPIO初始化
void DHT11_Start(void); // DHT11 触发信号
void Read_Data_From_DHT(void); // DHT11 数据处理
#endif /*__ DHT11_H__ */
/* dht11.c */
/* 注意:此代码未进行DHT11是否存在的检测,DHT11不存在时依然有数据,只不过数据有误 */
#include "dht11.h"
#include "delay_us.h"
#include "stdio.h"
#define DHT_HIGHT HAL_GPIO_WritePin(DHT11_Port, DHT11_Pin, GPIO_PIN_SET)
#define DHT_LOW HAL_GPIO_WritePin(DHT11_Port, DHT11_Pin, GPIO_PIN_RESET)
#define DHT_Read HAL_GPIO_ReadPin(DHT11_Port, DHT11_Pin)
uint8_t datas[5]; // 数组内有 5 个元素,每个元素都是一个无符号 8 位整数
// DHT11 GPIO初始化
void DHT_GPIO_Init(uint32_t Mode)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = DHT11_Pin;
GPIO_InitStruct.Mode = Mode;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DHT11_Port, &GPIO_InitStruct);
}
// DHT11 触发信号
void DHT11_Start(void)
{
DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);
DHT_HIGHT;
DHT_LOW;
HAL_Delay(30);
DHT_HIGHT;
DHT_GPIO_Init(GPIO_MODE_INPUT);
while(DHT_Read);
while(!DHT_Read);
while(DHT_Read);
}
// DHT11 数据处理
void Read_Data_From_DHT(void)
{
int i; //轮数: 4轮
int j; //每一轮读多少次: 8次
char tmp;
char flag;
DHT11_Start();
DHT_GPIO_Init(GPIO_MODE_INPUT);
for(i= 0;i < 5;i++)
{
for(j=0;j<8;j++)
{
while(!DHT_Read);
delay_us(40);
if(DHT_Read == 1)
{
flag = 1;
while(DHT_Read);
}
else
{
flag = 0;
}
tmp = tmp << 1;
tmp |= flag;
}
datas[i] = tmp;
}
}
/* delay_us.h */
#ifndef __DELAY_US_H__
#define __DELAY_US_H__
#include "main.h"
#define CPU_FREQUENCY_MHZ 72 // STM32时钟主频
void delay_us(__IO uint32_t delay);
/* delay_us.c */
#include "delay_us.h"
void delay_us(__IO uint32_t delay)
{
int last, curr, val;
int temp;
while (delay != 0)
{
temp = delay > 900 ? 900 : delay;
last = SysTick->VAL;
curr = last - CPU_FREQUENCY_MHZ * temp;
if (curr >= 0)
{
do
{
val = SysTick->VAL;
}
while ((val < last) && (val >= curr));
}
else
{
curr += CPU_FREQUENCY_MHZ * 1000;
do
{
val = SysTick->VAL;
}
while ((val <= last) || (val > curr));
}
delay -= temp;
}
}
/* usart.h */
int fputc(int ch, FILE *f);
/* usart.c */
#include "stdio.h"
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
Keil上勾选微库
更多推荐
所有评论(0)