1、开发平台
- 使用野火STM32H750开发板
- 无RTOS
- 使用HAL库进行开发
硬件连接:
SDA---->PA12
2、DHT11介绍
起始信号:
从机响应信号:
传输:
贴上代码:
dht11.h
#ifndef __dht11_h
#define __dht11_h
#include "main.h"
/*底层接口*/
#define __DHT11_GPIO_INIT() dht11_gpio_init()
#define __DHT11_MODE(MODE) DHT11_MODE(MODE)
#define __DHT11_OUT_H() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET)
#define __DHT11_OUT_L() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET)
#define __DHT11_READ() HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)
#define __DHT11_DELAY_MS(nms) delay_ms(nms)
#define __DHT11_DELAY_US(nms) delay_us(nms)
/*硬件接口*/
#define __DHT11_PIN_CLK() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DHT11_PIN GPIO_PIN_12
#define DHT11_PORT GPIOA
/*延时函数*/
#define SYSCLK 400000000/1000000 //指明CPU工作频率为(SystemCoreClock/1000000)MHz
#define A 6 //一次循环所花的周期数
#define B 3 //调用、初始化、返回总共所用的周期数
#define delay_us(nus) wait(((nus)*(SYSCLK)-(B))/(A))
#define delay_ms(nms) delay_us((nms)*1000)
#define delay_s(ns) delay_ms((ns)*1000)
/*结构体成员定义*/
typedef struct
{
uint8_t humi_int; //湿度的整数部分
uint8_t humi_deci; //湿度的小数部分
uint8_t temp_int; //温度的整数部分
uint8_t temp_deci; //温度的小数部分
uint8_t check_sum; //校验和
}DHT11_Data_TypeDef;
/*函数声明*/
void wait(unsigned long n);
void dht11_init(void);
uint8_t ReadByte(void);
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);
void DHT11_PRINTF(void);
#endif
dht11.c
#include "dht11.h"
GPIO_InitTypeDef DHT11_GPIO_Init;
DHT11_Data_TypeDef DHT11_Data;
/****************************************************************
*@function: dht11_gpio_init
*@input : none
*@output : none
*@describe: DHT11的GPIO口初始化
*@author : sola
****************************************************************/
void dht11_gpio_init(void)
{
__DHT11_PIN_CLK(); //开启时钟
DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
/****************************************************************
*@function: DHT11_MODE
*@input : mode (0/1)
*@output : none
*@describe: DHT11 GPIO输入输出模式选择
*@author : sola
****************************************************************/
void DHT11_MODE(uint8_t mode)
{
if(mode == 0)
{
DHT11_GPIO_Init.Mode = GPIO_MODE_INPUT;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
else if(mode == 1)
{
DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
}
/*---------------------------应用层----------------------------*/
/****************************************************************
*@function: dht11_delay
*@input : n (MHz)
*@output : none
*@describe: 延时
*@author : sola
****************************************************************/
void wait(unsigned long n)
{
do{
n--;
}while(n);
}
/****************************************************************
*@function: dht11_init
*@input : none
*@output : none
*@describe: DHT11 起始信号
*@author : sola
****************************************************************/
void dht11_init(void)
{
__DHT11_GPIO_INIT();
}
/****************************************************************
*@function: ReadByte
*@input : none
*@output : temp
*@describe: 读一个字节
*@author : sola
****************************************************************/
uint8_t ReadByte(void) {
uint8_t i, temp = 0;
for(i=0;i<8;i++) {
while(__DHT11_READ() == 0);
__DHT11_DELAY_US(40); //40us
if(__DHT11_READ() == 1) {
while(__DHT11_READ() == 1);
temp |= (uint8_t)(0x01<<(7-i));
}
else {
temp &= (uint8_t)~(0x01<<(7-i));
}
}
return temp;
}
/****************************************************************
*@function: Read_DHT11
*@input : *DHT11_Data
*@output : temp
*@describe: DHT11 读数据
*@author : sola
****************************************************************/
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data) {
__DHT11_MODE(1); //配置为输出
__DHT11_OUT_L(); //拉低
__DHT11_DELAY_MS(18); //18ms
__DHT11_OUT_H(); //拉高
__DHT11_DELAY_US(13); //13us
__DHT11_MODE(0); //配置为输入
if(__DHT11_READ() == 0) {
while(__DHT11_READ() == 0);
while(__DHT11_READ() == 1);
DHT11_Data->humi_int= ReadByte(); //读取湿度整数
DHT11_Data->humi_deci= ReadByte(); //读取湿度小数
DHT11_Data->temp_int= ReadByte(); //读取温度整数
DHT11_Data->temp_deci= ReadByte(); //读取温度整数
DHT11_Data->check_sum= ReadByte(); //应答读取
__DHT11_MODE(1); //配置为输出
__DHT11_OUT_H();
if(DHT11_Data->check_sum ==
DHT11_Data->humi_int +
DHT11_Data->humi_deci +
DHT11_Data->temp_int+
DHT11_Data->temp_deci) {
return SUCCESS;
}
else {
return ERROR;
}
}
return 0;
}
/****************************************************************
*@function: DHT11_PRINTF
*@input : none
*@output : none
*@describe: DHT11 打印数据
*@author : sola
****************************************************************/
#if 1
void DHT11_PRINTF(void) {
if(Read_DHT11(&DHT11_Data) == SUCCESS) {
printf("rnrn湿度为%d.%d %RH ,温度为 %d.%d℃ rn",
DHT11_Data.humi_int,
DHT11_Data.humi_deci,
DHT11_Data.temp_int,
DHT11_Data.temp_deci);
}
}
#endif
移植也方便,就修改几个地方就好了。
注意:如果移植后通讯不成功,请修改delay_us和delay_ms,也可以调节参数A,这个在不同MCU上需要执行的周期时间是不一样的。
1、开发平台
- 使用野火STM32H750开发板
- 无RTOS
- 使用HAL库进行开发
硬件连接:
SDA---->PA12
2、DHT11介绍
起始信号:
从机响应信号:
传输:
贴上代码:
dht11.h
#ifndef __dht11_h
#define __dht11_h
#include "main.h"
/*底层接口*/
#define __DHT11_GPIO_INIT() dht11_gpio_init()
#define __DHT11_MODE(MODE) DHT11_MODE(MODE)
#define __DHT11_OUT_H() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET)
#define __DHT11_OUT_L() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET)
#define __DHT11_READ() HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)
#define __DHT11_DELAY_MS(nms) delay_ms(nms)
#define __DHT11_DELAY_US(nms) delay_us(nms)
/*硬件接口*/
#define __DHT11_PIN_CLK() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DHT11_PIN GPIO_PIN_12
#define DHT11_PORT GPIOA
/*延时函数*/
#define SYSCLK 400000000/1000000 //指明CPU工作频率为(SystemCoreClock/1000000)MHz
#define A 6 //一次循环所花的周期数
#define B 3 //调用、初始化、返回总共所用的周期数
#define delay_us(nus) wait(((nus)*(SYSCLK)-(B))/(A))
#define delay_ms(nms) delay_us((nms)*1000)
#define delay_s(ns) delay_ms((ns)*1000)
/*结构体成员定义*/
typedef struct
{
uint8_t humi_int; //湿度的整数部分
uint8_t humi_deci; //湿度的小数部分
uint8_t temp_int; //温度的整数部分
uint8_t temp_deci; //温度的小数部分
uint8_t check_sum; //校验和
}DHT11_Data_TypeDef;
/*函数声明*/
void wait(unsigned long n);
void dht11_init(void);
uint8_t ReadByte(void);
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);
void DHT11_PRINTF(void);
#endif
dht11.c
#include "dht11.h"
GPIO_InitTypeDef DHT11_GPIO_Init;
DHT11_Data_TypeDef DHT11_Data;
/****************************************************************
*@function: dht11_gpio_init
*@input : none
*@output : none
*@describe: DHT11的GPIO口初始化
*@author : sola
****************************************************************/
void dht11_gpio_init(void)
{
__DHT11_PIN_CLK(); //开启时钟
DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
/****************************************************************
*@function: DHT11_MODE
*@input : mode (0/1)
*@output : none
*@describe: DHT11 GPIO输入输出模式选择
*@author : sola
****************************************************************/
void DHT11_MODE(uint8_t mode)
{
if(mode == 0)
{
DHT11_GPIO_Init.Mode = GPIO_MODE_INPUT;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
else if(mode == 1)
{
DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
DHT11_GPIO_Init.Pin = DHT11_PIN;
DHT11_GPIO_Init.Pull = GPIO_NOPULL;
DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}
}
/*---------------------------应用层----------------------------*/
/****************************************************************
*@function: dht11_delay
*@input : n (MHz)
*@output : none
*@describe: 延时
*@author : sola
****************************************************************/
void wait(unsigned long n)
{
do{
n--;
}while(n);
}
/****************************************************************
*@function: dht11_init
*@input : none
*@output : none
*@describe: DHT11 起始信号
*@author : sola
****************************************************************/
void dht11_init(void)
{
__DHT11_GPIO_INIT();
}
/****************************************************************
*@function: ReadByte
*@input : none
*@output : temp
*@describe: 读一个字节
*@author : sola
****************************************************************/
uint8_t ReadByte(void) {
uint8_t i, temp = 0;
for(i=0;i<8;i++) {
while(__DHT11_READ() == 0);
__DHT11_DELAY_US(40); //40us
if(__DHT11_READ() == 1) {
while(__DHT11_READ() == 1);
temp |= (uint8_t)(0x01<<(7-i));
}
else {
temp &= (uint8_t)~(0x01<<(7-i));
}
}
return temp;
}
/****************************************************************
*@function: Read_DHT11
*@input : *DHT11_Data
*@output : temp
*@describe: DHT11 读数据
*@author : sola
****************************************************************/
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data) {
__DHT11_MODE(1); //配置为输出
__DHT11_OUT_L(); //拉低
__DHT11_DELAY_MS(18); //18ms
__DHT11_OUT_H(); //拉高
__DHT11_DELAY_US(13); //13us
__DHT11_MODE(0); //配置为输入
if(__DHT11_READ() == 0) {
while(__DHT11_READ() == 0);
while(__DHT11_READ() == 1);
DHT11_Data->humi_int= ReadByte(); //读取湿度整数
DHT11_Data->humi_deci= ReadByte(); //读取湿度小数
DHT11_Data->temp_int= ReadByte(); //读取温度整数
DHT11_Data->temp_deci= ReadByte(); //读取温度整数
DHT11_Data->check_sum= ReadByte(); //应答读取
__DHT11_MODE(1); //配置为输出
__DHT11_OUT_H();
if(DHT11_Data->check_sum ==
DHT11_Data->humi_int +
DHT11_Data->humi_deci +
DHT11_Data->temp_int+
DHT11_Data->temp_deci) {
return SUCCESS;
}
else {
return ERROR;
}
}
return 0;
}
/****************************************************************
*@function: DHT11_PRINTF
*@input : none
*@output : none
*@describe: DHT11 打印数据
*@author : sola
****************************************************************/
#if 1
void DHT11_PRINTF(void) {
if(Read_DHT11(&DHT11_Data) == SUCCESS) {
printf("rnrn湿度为%d.%d %RH ,温度为 %d.%d℃ rn",
DHT11_Data.humi_int,
DHT11_Data.humi_deci,
DHT11_Data.temp_int,
DHT11_Data.temp_deci);
}
}
#endif
移植也方便,就修改几个地方就好了。
注意:如果移植后通讯不成功,请修改delay_us和delay_ms,也可以调节参数A,这个在不同MCU上需要执行的周期时间是不一样的。
举报