智能温湿度计是一种可以测量环境温度和湿度的设备,本文将使用STM32微控制器制作一个智能温湿度计。我们将使用STM32CubeMX和Keil MDK来配置和编写代码。以下是实现这个项目的详细步骤。
-
硬件准备 首先,我们需要准备以下硬件组件:
- STM32微控制器开发板(例如:STM32F103C8T6)
- 温湿度传感器(例如:DHT11)
- LCD显示屏(例如:16x2字符LCD)
- 杜邦线和面包板
-
硬件连接 将温湿度传感器和LCD显示屏连接到STM32开发板。以下是连接的示意图:
STM32开发板 温湿度传感器 LCD显示屏 ---------------------------------------------------- GND ------------ GND ----------------- GND 5V ------------- VCC ----------------- VCC PB6 ------------ DATA ----------------- ---------------------------------------------------- GND ----------------------------------- GND 5V ------------------------------------ VCC PA6 ----------------------------------- RS PA7 ----------------------------------- E PB0 ----------------------------------- D4 PB1 ----------------------------------- D5 PB10 ---------------------------------- D6 PB11 ---------------------------------- D7
-
STM32CubeMX配置 使用STM32CubeMX工具配置STM32开发板的引脚和时钟。以下是配置步骤:
- 打开STM32CubeMX并创建一个新项目。
- 选择正确的STM32微控制器型号。
- 在Pinout & Configuration选项卡中配置引脚功能。
- 将PB6设置为GPIO_Output,并将其命名为DHT11_DATA。
- 将PA6、PA7、PB0、PB1、PB10、PB11设置为GPIO_Output,并将其命名为LCD_RS、LCD_E、LCD_D4、LCD_D5、LCD_D6、LCD_D7。
- 在Configuration选项卡中配置时钟。
- 根据需求调整系统时钟和外设时钟。
-
生成代码 在STM32CubeMX中生成代码。这将会自动生成一个基本的代码框架和初始化函数。
-
编写温湿度传感器驱动程序 在生成的代码中,打开main.c文件并添加以下函数来读取温湿度传感器的数据:
// 引用必要的头文件 #include "stm32f1xx_hal.h" // 定义DHT11_DATA引脚 #define DHT11_DATA_PIN GPIO_PIN_6 #define DHT11_DATA_PORT GPIOB // DHT11传感器数据结构 typedef struct { uint8_t humidity; uint8_t temperature; uint8_t checksum; } DHT11_Data; // DHT11传感器初始化 void DHT11_Init(void) { HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_SET); HAL_Delay(1000); } // 读取DHT11传感器数据 DHT11_Data DHT11_ReadData(void) { uint8_t data[5] = {0}; DHT11_Data result; // 发送开始信号 HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_RESET); HAL_Delay(18); HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_SET); HAL_Delay(40); // 等待DHT11响应 while (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_SET); // 接收传感器数据 for (int i = 0; i < 40; i++) { // 等待下一个位 while (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_RESET); // 延迟50us以接收位数据 HAL_Delay(50); // 如果高电平持续时间大于50us,则认为是高位 if (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_SET) { // 设置当前位为1 data[i / 8] |= (1 << (7 - (i % 8))); } } // 检查校验和 if (data[4] == (data[0] + data[1] + data[2] + data[3])) { result.humidity = data[0]; result.temperature = data[2]; result.checksum = data[4]; } else { // 校验和错误,返回无效数据 result.humidity = 0; result.temperature = 0; result.checksum = 0; } return result; }
-
编写LCD显示屏驱动程序 在生成的代码中,打开main.c文件并添加以下函数来控制LCD显示屏:
// 引用必要的头文件 #include "stm32f1xx_hal.h" // 定义LCD引脚 #define LCD_RS_PIN GPIO_PIN_6 #define LCD_RS_PORT GPIOA #define LCD_E_PIN GPIO_PIN_7 #define LCD_E_PORT GPIOA #define LCD_D4_PIN GPIO_PIN_0 #define LCD_D4_PORT GPIOB #define LCD_D5_PIN GPIO_PIN_1 #define LCD_D5_PORT GPIOB #define LCD_D6_PIN GPIO_PIN_10 #define LCD_D6_PORT GPIOB #define LCD_D7_PIN GPIO_PIN_11 #define LCD_D7_PORT GPIOB // 控制LCD显示屏 void LCD_WriteCommand(uint8_t command) { // 设置LCD_RS引脚为低电平以选择命令模式 HAL_GPIO_WritePin(LCD_RS_PORT, LCD_RS_PIN, GPIO_PIN_RESET); // 发送高4位 HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, (command >> 4) & 0x01); HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (command >> 5) & 0x01); HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (command >> 6) & 0x01); HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (command >> 7) & 0x01); // 发送使能脉冲 HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_RESET); HAL_Delay(1); // 发送低4位 HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, command & 0x01); HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (command >> 1) & 0x01); HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (command >> 2) & 0x01); HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (command >> 3) & 0x01); // 发送使能脉冲 HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_RESET); HAL_Delay(1); } // 控制LCD显示屏 void LCD_WriteData(uint8_t data) { // 设置LCD_RS引脚为高电平以选择数据模式 HAL_GPIO_WritePin(LCD_RS_PORT, LCD_RS_PIN, GPIO_PIN_SET); // 发送高4位 HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, (data >> 4) & 0x01); HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (data >> 5) & 0x01); HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (data >> 6) & 0x01); HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (data >> 7) & 0x01); // 发送使能脉冲 HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(LCD_E_PORT