dht11温湿度传感器stm32f103c8t6
时间: 2024-04-21 21:21:32 浏览: 171
DHT11温湿度传感器是一种常用的数字温湿度传感器,适用于各种温湿度测量场景。它可以通过数字信号输出当前环境的温度和湿度值。而STM32F103C8T6是一款常用的低功耗、高性能的ARM Cortex-M3微控制器,广泛应用于嵌入式系统开发。
要在STM32F103C8T6上使用DHT11温湿度传感器,你需要连接它们并编写相应的代码来读取传感器的数据。以下是一般的连接方式:
1. 将DHT11的VCC引脚连接到STM32F103C8T6的3.3V电源引脚。
2. 将DHT11的GND引脚连接到STM32F103C8T6的地引脚。
3. 将DHT11的DATA引脚连接到STM32F103C8T6的一个GPIO引脚。
在编写代码时,你需要使用STM32的GPIO库来配置和读取GPIO引脚的状态。具体步骤如下:
1. 初始化GPIO引脚为输入模式。
2. 发送启动信号给DHT11传感器。
3. 等待DHT11传感器的响应信号。
4. 接收DHT11传感器发送的数据。
5. 解析接收到的数据,得到温度和湿度值。
需要注意的是,DHT11传感器的通信协议是一种单总线协议,需要按照一定的时序进行数据的读取和解析。
相关问题
dht11温湿度传感器stm32f103C8T6
### 使用STM32F103C8T6与DHT11温湿度传感器进行连接和编程
#### 硬件连接说明
为了使STM32F103C8T6能够读取来自DHT11的温湿度数据,两者之间需建立正确的硬件连接。具体来说:
- DHT11的VCC引脚应接到STM32F103C8T6的3.3V电源端口;
- GND接地线要连至STM32的地线接口;
- 数据信号线(通常标记为DATA)应当接入任意一个GPIO引脚上用于单总线通讯;此案例中推荐PA0作为输入/输出控制管脚[^1]。
#### 软件配置流程
针对上述提到的硬件设置,在软件层面同样需要做相应的初始化工作来确保能顺利获取并处理由DHT11传来的信息流。以下是具体的编码指南:
##### 初始化外设资源
```c
#include "stm32f1xx_hal.h"
// 定义使用的GPIO引脚
#define DHT11_PIN GPIO_PIN_0
#define DHT11_PORT GPIOA
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1){
// 主循环体内的操作...
}
}
/**
* @brief 配置系统时钟.
*/
void SystemClock_Config(void){
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* Initializes the CPU, AHB and APB busses clocks */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){
Error_Handler();
}
}
/* GPIO Initialization Function */
static void MX_GPIO_Init(void){
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 设置DHT11所用的IO口模式
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DHT11_PORT,&GPIO_InitStruct);
}
```
这段代码完成了基本的系统时钟设定以及指定给定GPIO引脚的工作方式——推挽输出形式下的无上下拉电阻状态,并将其速度等级调整到了较低水平以便于后续通信过程中的稳定性和可靠性。
##### 编写读取函数
接下来定义专门用来从DHT11接收数据包的方法`read_dht11_data()`,该方法负责启动一次完整的测量周期并向调用者返回解析后的浮点数值表示当前环境条件下的相对湿度百分比值及摄氏度计数。
```c
uint8_t read_bit(){
uint32_t timeout=HAL_GetTick()+100;//超时保护机制
HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_RESET);
HAL_Delay(20); //等待至少18ms让设备准备好响应查询请求
HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_SET);
while(HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)==GPIO_PIN_RESET && HAL_GetTick()<timeout){}//等待上升沿到来
timeout=HAL_GetTick()+100;
delay_us(40);//跳过固定宽度脉冲区间
return HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)?1:0;
}
float humidity,float temperature;
bool read_dht11_data(float* h,float*t){
bool success=true;
uint8_t data[5]={0},checksum=0;
int i,j,k;
for(i=0;i<5;++i){
for(j=7;j>=0;--j){
k=read_bit()?1<<j:0;
data[i]|=k;
}
}
checksum=data[0]+data[1]+data[2]+data[3];
if(checksum==data[4]){
*h=(data[0]<<8|data[1])/10.0f;
*t=(data[2]<<8|data[3])/10.0f;
}else{
success=false;
}
return success;
}
```
这里实现了对DHT11发出的一系列高低电平变化序列的捕捉逻辑,按照官方文档给出的数据帧结构逐位重构出原始字节数组后再计算校验码验证其准确性最后转换成易于理解的形式供应用程序进一步分析使用[^2][^3]。
---
dht11温湿度传感器stm32f103c8t6 代码
下面是使用STM32F103C8T6和DHT11温湿度传感器的示例代码:
```c
#include "stm32f10x.h"
#include <stdio.h>
#define DHT11_PIN GPIO_Pin_0
#define DHT11_PORT GPIOB
void Delay_us(uint32_t microseconds)
{
microseconds *= (SystemCoreClock / 1000000) / 5;
while (microseconds--)
{
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
void DHT11_Start(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
GPIO_SetBits(DHT11_PORT, DHT11_PIN);
Delay_us(1000);
GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
Delay_us(18000);
GPIO_SetBits(DHT11_PORT, DHT11_PIN);
Delay_us(40);
GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}
void DHT11_Check_Response(void)
{
while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
;
while (!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
;
while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
;
}
uint8_t DHT11_Read(void)
{
uint8_t i, j;
uint8_t data = 0;
for (j = 0; j < 8; j++)
{
while (!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
;
Delay_us(40);
if (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
{
data |= (1 << (7 - j));
}
while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
;
}
return data;
}
int main(void)
{
uint8_t Humidity, Temperature;
char buffer[20];
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
while (1)
{
DHT11_Start();
DHT11_Check_Response();
Humidity = DHT11_Read();
DHT11_Read();
Temperature = DHT11_Read();
DHT11_Read();
DHT11_Read();
sprintf(buffer, "Humidity: %d.%d %%\n", Humidity / 10, Humidity % 10);
printf(buffer);
sprintf(buffer, "Temperature: %d.%d C\n\n", Temperature / 10, Temperature % 10);
printf(buffer);
Delay_us(2000000);
}
}
```
在这个例子中,使用PB0作为DHT11的数据引脚。代码通过设置GPIO引脚的输入和输出模式来控制DHT11的通信。它使用延迟函数来生成所需的时间间隔,并从DHT11读取温度和湿度数据。最后,将温度和湿度值格式化为字符串并打印到终端上。
请注意,此代码仅供参考,您可能需要根据自己的硬件配置进行修改。
阅读全文
相关推荐














