382 lines
12 KiB
C
382 lines
12 KiB
C
#include "mw_dht11.h"
|
||
|
||
#include "stdint.h"
|
||
/* user define */
|
||
|
||
#include "public_diy.h"
|
||
#include "bsp_timer.h"
|
||
#include "stm32f10x_gpio.h"
|
||
#include "stm32f10x_rcc.h"
|
||
/* 用户头文件定义 */
|
||
#define DHT11BUS_GPIO_PORT (GPIOB)
|
||
#define DHT11BUS_GPIO_PIN (GPIO_Pin_1)
|
||
#define DHT11BUS_GPIO_RCC (RCC_APB2Periph_GPIOB)
|
||
|
||
/* 用户安装函数 */
|
||
/*************************************************************************************
|
||
* @brief dht11用 延迟若干us
|
||
* @param[in/out] delay_us【参数注释】
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_delay_us(uint16_t delay_us)
|
||
{
|
||
bsp_DelayUS(delay_us);
|
||
}
|
||
/*************************************************************************************
|
||
* @brief dht11用 延迟若干ms
|
||
* @param[in/out] delay_ms【参数注释】
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_delay_ms(uint16_t delay_ms)
|
||
{
|
||
bsp_DelayMS(delay_ms);
|
||
}
|
||
|
||
/*************************************************************************************
|
||
* @brief dht11的单总线为 输出 高电平
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_output_high(void)
|
||
{
|
||
// DHT11BUS_GPIO_PORT->BSRR = DHT11BUS_GPIO_PIN;
|
||
// GPIO_SetBits(DHT11BUS_GPIO_PORT, DHT11BUS_GPIO_PIN);
|
||
GPIO_WriteBit(DHT11BUS_GPIO_PORT, DHT11BUS_GPIO_PIN, (BitAction)1);
|
||
}
|
||
/*************************************************************************************
|
||
* @brief dht11的单总线为 输出 低电平
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_output_low(void)
|
||
{
|
||
// DHT11BUS_GPIO_PORT->BRR = DHT11BUS_GPIO_PIN;
|
||
GPIO_WriteBit(DHT11BUS_GPIO_PORT, DHT11BUS_GPIO_PIN, (BitAction)0);
|
||
}
|
||
|
||
/*************************************************************************************
|
||
* @brief 将dht11的单总线改为输入
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_io_input(void)
|
||
{
|
||
|
||
// GPIO_InitTypeDef GPIO_InitStructure;
|
||
/* 打开GPIO时钟 */
|
||
// RCC_APB2PeriphClockCmd(DHT11BUS_GPIO_RCC, ENABLE);
|
||
|
||
// GPIO_InitStructure.GPIO_Pin = DHT11BUS_GPIO_PIN;
|
||
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 设为 输出开漏模式 */
|
||
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* IO口最大速度 */
|
||
// GPIO_Init(DHT11BUS_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
// #if DHT11BUS_GPIO_PIN == GPIO_Pin_0
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFFFFF0;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8;
|
||
// #endif
|
||
|
||
// #if DHT11BUS_GPIO_PIN == GPIO_Pin_1
|
||
DHT11BUS_GPIO_PORT->CRL &= 0xFFFFFF0F;
|
||
DHT11BUS_GPIO_PORT->CRL |= 4 << 4;
|
||
// #endif
|
||
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_2
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFFF0FF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 8;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_3
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFF0FFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 12;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_4
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFF0FFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 16;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_5
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFF0FFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 20;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_6
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xF0FFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 24;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_7
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0x0FFFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 8 << 28;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_8
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFFFF0;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_9
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFFF0F;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 4;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_10
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFF0FF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 8;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_11
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFF0FFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 12;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_12
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFF0FFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 16;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_13
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFF0FFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 20;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_14
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xF0FFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 24;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_15
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0x0FFFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 8 << 28;
|
||
// #endif
|
||
}
|
||
/*************************************************************************************
|
||
* @brief 将dht11的单总线改为输出
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
static void dht11_io_output(void)
|
||
{
|
||
// #if ((DHT11BUS_GPIO_PIN) == (GPIO_Pin_0))
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFFFFF0;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_1
|
||
DHT11BUS_GPIO_PORT->CRL &= 0xFFFFFF0F;
|
||
DHT11BUS_GPIO_PORT->CRL |= 7 << 4;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_2
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFFF0FF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 8;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_3
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFFF0FFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 12;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_4
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFFF0FFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 16;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_5
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xFF0FFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 20;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_6
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0xF0FFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 24;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_7
|
||
// DHT11BUS_GPIO_PORT->CRL &= 0x0FFFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRL |= 3 << 28;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_8
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFFFF0;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_9
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFFF0F;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 4;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_10
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFFF0FF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 8;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_11
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFFF0FFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 12;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_12
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFFF0FFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 16;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_13
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xFF0FFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 20;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_14
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0xF0FFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 24;
|
||
// #elif DHT11BUS_GPIO_PIN == GPIO_Pin_15
|
||
// DHT11BUS_GPIO_PORT->CRH &= 0x0FFFFFFF;
|
||
// DHT11BUS_GPIO_PORT->CRH |= 3 << 28;
|
||
// #endif
|
||
}
|
||
|
||
/*************************************************************************************
|
||
* @brief 获取dht11输出状态
|
||
* @return uint8_t 【返回值注释】
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
uint8_t dht11_read_io_state(void)
|
||
{
|
||
// return (uint8_t)(DHT11BUS_GPIO_PORT->ODR & DHT11BUS_GPIO_PIN);
|
||
return GPIO_ReadInputDataBit(DHT11BUS_GPIO_PORT, DHT11BUS_GPIO_PIN);
|
||
}
|
||
/*************************************************************************************
|
||
* @brief dht11 单总线所需的gpio初始化
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
void dht11_gpio_init(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
/* 打开GPIO时钟 */
|
||
RCC_APB2PeriphClockCmd(DHT11BUS_GPIO_RCC, ENABLE);
|
||
|
||
GPIO_InitStructure.GPIO_Pin = DHT11BUS_GPIO_PIN;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; /* 设为 输出开漏模式 */
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* IO口最大速度 */
|
||
GPIO_Init(DHT11BUS_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
dht11_output_high();
|
||
|
||
}
|
||
|
||
/*************************************************************************************
|
||
* @brief dht11开始信号
|
||
* @return uint8_t RET_ERROR RET_OK
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
uint8_t dht11_start(void)
|
||
{
|
||
uint8_t tmp_timer = 0;
|
||
// 关总中断
|
||
DISABLE_INT();
|
||
//1.配置引脚为输出模式
|
||
dht11_io_output();
|
||
//2.把引脚电平拉低并持续20ms
|
||
dht11_output_low();
|
||
dht11_delay_ms(20);
|
||
|
||
//3.把引脚电平拉高并持续20us
|
||
dht11_output_high();
|
||
dht11_delay_us(30);
|
||
|
||
dht11_io_input();
|
||
// 等待dht11 拉低
|
||
while(dht11_read_io_state() == 0 && tmp_timer < 101)
|
||
{
|
||
tmp_timer++;
|
||
dht11_delay_us(1);
|
||
__NOP();
|
||
}
|
||
if(tmp_timer > 100 || tmp_timer < 20)
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
// 检测是否存在第二个高电平
|
||
tmp_timer = 0; // 重置计数器
|
||
while (dht11_read_io_state() == 1 && tmp_timer < 101) // 等待DHT11释放总线,持续时间40~80us
|
||
{
|
||
tmp_timer++; // 总线拉高时计数
|
||
dht11_delay_us(1);
|
||
}
|
||
ENABLE_INT(); // 开总中断
|
||
if (tmp_timer>100 || tmp_timer<20) // 检测响应信号之后的高电平
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
|
||
// 均存在, 响应正常
|
||
return RET_OK;
|
||
}
|
||
|
||
uint8_t dht11_read_byte(uint8_t *ret_byte)
|
||
{
|
||
uint8_t tmp_timer = 0;
|
||
uint8_t tmp_i;
|
||
// uint8_t ret_byte = 0;
|
||
|
||
DISABLE_INT(); // 关总中断
|
||
dht11_io_input();
|
||
for (tmp_i = 0; tmp_i < 8; tmp_i++)
|
||
{
|
||
/* 等待低电平,数据位前都有50us低电平时隙 */
|
||
while (dht11_read_io_state() > 0 && tmp_timer < 101)
|
||
{
|
||
tmp_timer++;
|
||
dht11_delay_us(1);
|
||
}
|
||
if(tmp_timer > 100)
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
tmp_timer = 0;
|
||
/* 等待高电平,开始传输数据位 */
|
||
while (dht11_read_io_state() == 0 && tmp_timer < 101)
|
||
{
|
||
tmp_timer++;
|
||
dht11_delay_us(1);
|
||
}
|
||
if(tmp_timer > 100)
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
|
||
dht11_delay_us(40);
|
||
|
||
*ret_byte <<= 1; // 因高位在前,所以左移byt,最低位补0
|
||
if (dht11_read_io_state() > 0) // 将总线电平值读取到byt最低位中
|
||
{
|
||
*ret_byte |= 0x01;
|
||
}
|
||
}
|
||
ENABLE_INT(); // 开总中断
|
||
|
||
return RET_OK;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief 读取数据
|
||
* @param Temp_H 温度整数部分
|
||
* @param Temp_L 温度小数部分
|
||
* @param Humi_H 湿度整数部分
|
||
* @param Humi_L 湿度小数部分
|
||
* @retval 0-成功,1-失败
|
||
*/
|
||
uint8_t mw_dht11_read_data(uint8_t *Temp_H,uint8_t *Temp_L,uint8_t *Humi_H,uint8_t *Humi_L)
|
||
{
|
||
uint8_t sta = RET_ERROR;
|
||
uint8_t i;
|
||
uint8_t buf[5];
|
||
|
||
if(dht11_start() == RET_OK) // 检测响应信号
|
||
{
|
||
for(i=0;i<5;i++) // 读取40位数据
|
||
{
|
||
sta = dht11_read_byte(&buf[i]); // 读取1字节数据
|
||
if(sta == RET_ERROR)
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
}
|
||
|
||
if(buf[0]+buf[1]+buf[2]+buf[3] == buf[4]) // 校验成功
|
||
{
|
||
*Humi_H = buf[0]; // 湿度 整数部分数据
|
||
*Humi_L = buf[1]; // 湿度 小数部分数据
|
||
*Temp_H = buf[2]; // 温度 整数部分数据
|
||
*Temp_L = buf[3]; // 温度 小数部分数据
|
||
return RET_OK;
|
||
}
|
||
else
|
||
{
|
||
return RET_ERROR;
|
||
}
|
||
}
|
||
else // 响应失败返回-1
|
||
{
|
||
*Temp_H = 0;
|
||
*Temp_L = 0;
|
||
*Humi_H = 0;
|
||
*Humi_L = 0;
|
||
|
||
return RET_ERROR;
|
||
}
|
||
}
|
||
/*************************************************************************************
|
||
* @brief dht11初始化
|
||
*
|
||
* @warning 【不可重入,阻塞等警告】
|
||
* @note 【重大修改】
|
||
*************************************************************************************/
|
||
void mw_dht11_init(void)
|
||
{
|
||
dht11_gpio_init();
|
||
}
|