题目:设计一个简单的温度监测系统,使用基于嵌入式C的微控制器来获取并显示温度数据。你需要连接一个温度传感器到微控制器,并编写代码来读取传感器数据并在显示屏上显示温度值。
要求:
- 选择一个合适的温度传感器(例如LM35或DS18B20或DHT11)并将其连接到微控制器的适当引脚。
- 编写嵌入式C代码,初始化传感器并读取其输出数据。
- 将读取到的温度数据进行适当的转换,确保显示的温度值是以摄氏度为单位。
- 如果你没有实际的硬件,可以在代码中模拟传感器输出,然后将温度值显示在终端或串行监视器上。
解答:
(1)硬件图
上述仿真图是一个简单的DHT11温度传感器原理图,我用了一个DHT11做参考.
(2)经典电路图
上述是一个模拟电路图
(3) 编写嵌入式C代码
DHT11传感器与STM32的连接需要使用一个数字引脚来读取传感器的数据。以下是一个示例代码,演示如何在STM32上使用DHT11温度传感器获取温度数据并将其显示在终端上。
步骤 1:包含必要的头文件
#include "main.h"
#include "stdio.h"
#include "dwt_delay.h" // 自定义的微秒级延迟函数
#include "DHT11.h" // DHT11库
步骤 2:初始化HAL库和硬件
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
DWT_Delay_Init(); // 初始化微秒级延迟函数
DHT11_Init(); // 初始化DHT11传感器
while (1) {
// 代码将在这里执行
}
}
步骤 3:获取和显示温度数据
float temperatureC = 0;
float humidity = 0;
if (DHT11_ReadData(&temperatureC, &humidity) == DHT11_OK) {
char uartMsg[50];
snprintf(uartMsg, sizeof(uartMsg), "Temperature: %.2f °C, Humidity: %.2f%%\r\n", temperatureC, humidity);
HAL_UART_Transmit(&huart1, (uint8_t *)uartMsg, strlen(uartMsg), HAL_MAX_DELAY);
} else {
HAL_UART_Transmit(&huart1, (uint8_t *)"Error reading DHT11 data\r\n", 27, HAL_MAX_DELAY);
}
DWT_Delay_us(5000000); // 延迟5秒
在这个示例中,我们使用了一个名为"DHT11.h"的库,该库提供了与DHT11传感器通信的函数。通过调用DHT11_Init()初始化传感器,并使用DHT11_ReadData()函数来读取温度和湿度数据。读取成功后,将数据以文本形式通过串口输出到终端。
请注意,你需要自己实现或使用现有的DHT11库来处理与传感器的通信。上述代码只是一个示例,实际情况下可能需要根据库的API进行调用。
DHT11.h的代码
#ifndef DHT11_H
#define DHT11_H
#include "main.h" // 根据你的工程设置
// DHT11传感器初始化
void DHT11_Init(void);
// 从DHT11传感器读取温度和湿度数据
typedef enum {
DHT11_OK,
DHT11_ERROR_TIMEOUT,
DHT11_ERROR_CHECKSUM
} DHT11_StatusTypeDef;
DHT11_StatusTypeDef DHT11_ReadData(float *temperatureC, float *humidity);
#endif /* DHT11_H */
DWT_Delay.h的代码
DWT_Delay.h" 是一个自定义的微秒级延迟函数头文件,用于实现微秒级的延迟操作。以下是一个简单的示例代码,你可以将其放在一个名为 "dwt_delay.h" 的头文件中:
#ifndef DWT_DELAY_H
#define DWT_DELAY_H
#include "stm32f4xx_hal.h" // 根据你的工程设置
// 初始化DWT计时器
void DWT_Delay_Init(void);
// 微秒级延迟函数
void DWT_Delay_us(volatile uint32_t microseconds);
#endif /* DWT_DELAY_H */
然后,在一个名为 "dwt_delay.c" 的源文件中实现这些函数:
#include "dwt_delay.h"
static volatile uint32_t usTicks;
void DWT_Delay_Init(void) {
// 初始化DWT计时器
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
// 计算微秒级延迟所需的时钟周期数
usTicks = HAL_RCC_GetHCLKFreq() / 1000000;
}
void DWT_Delay_us(volatile uint32_t microseconds) {
uint32_t startTick = DWT->CYCCNT;
microseconds *= usTicks;
// 等待所需的时钟周期数
while ((DWT->CYCCNT - startTick) < microseconds);
}
这个 "DWT_Delay.h" 头文件定义了两个函数:DWT_Delay_Init 和 DWT_Delay_us。DWT_Delay_Init 函数初始化了DWT(Data Watchpoint and Trace)计时器,用于测量微秒级延迟。DWT_Delay_us 函数使用DWT计时器实现微秒级延迟。
请注意,实现 DWT_Delay_us 函数需要注意处理计时器溢出的情况,以及确保它在不同的时钟频率下也能正常工作。上述代码只是一个简化的示例,实际上可能需要更多的细节和调试。
(4)硬件连接示意图和解释
当使用STM32单片机与DHT11温度传感器一起开发温度监测系统时,你需要将传感器正确连接到单片机的引脚。以下是一个基本的硬件连接示意图和解释:
连接DHT11传感器到STM32单片机:
- DHT11 的 VCC 引脚(正极)连接到STM32的5V电源引脚或3.3V电源引脚(取决于DHT11工作电压)。
- DHT11 的 GND 引脚(地)连接到STM32的地(GND)引脚。
- DHT11 的 DATA 引脚连接到STM32的数字引脚。例如,你可以将其连接到STM32的GPIO引脚,如PA0。
添加电容(可选):
为了稳定传感器的工作,你可以在DHT11的VCC和GND之间添加一个100nF的电容。
请注意,DHT11传感器的电压供应和数字引脚连接到STM32的引脚会根据具体的硬件设计而有所不同。你需要根据你所使用的STM32型号和引脚来进行正确的连接。
DHT11引脚说明
Pin | 名称 | 注释 |
---|---|---|
1 | VDD | 供电 3-5.5V |
2 | GND | 接地,电源负极 |
3 | DATA | 串行数据,单总线 |
4 | NC | 空脚,请悬空 |
此外,你需要在代码中定义正确的引脚,并确保在初始化函数中设置引脚的方向(输入或输出)。