基于单片机/STM32的房间通风设备监测控制系统设计
基于单片机/STM32的房间通风设备监测控制系统设计
系统概述
本项目设计一个房间通风设备监测控制系统,能够对房间进行通风或制冷,并对通风状态进行检测。新风通过过滤器和盘管,利用送风机送入房间通风管路。如果只需要通风,送风机工作,电磁阀关闭,送入房间通风管路。如果需要冷风,送风机工作,电磁阀打开,高压冷水冷却进风,实现输送冷气的目的。需要检测送风机出口温度,范围10~60℃,检测主管路过滤器后新风流量,当风机运行且流量过小(流量值自设),报警指示过滤器阻塞,发出报警。
基本任务
- 实时显示送风机出口温度
- 设置按键选择通风和冷气两种状态
- 显示电磁阀、送风机的工作状态
- 对电机运行故障进行报警
进阶任务
- 设置两个温度传感器检测温度
- 使用 LCD 显示信息
- 设置系统启动按键
- 设计其 C 程序
系统设计
1. 硬件设计
-
基本任务实现
- MCU选型:STC89C52
- 温度传感器:DS18B20
- LCD:1602A
- 电磁阀:5V
- 送风机:12V
- 按键:5V
-
进阶任务实现
- MCU选型:STM32F103C8T6
- 温度传感器:DS18B20
- LCD:1602A
- 电磁阀:5V
- 送风机:12V
- 按键:5V
2. 系统框图

3. 程序设计
-
基本任务实现
- 初始化
#include <reg52.h> #include <stdio.h> #include <string.h> #include "ds18b20.h" #include "lcd1602.h" sbit key1 = P3^2; sbit key2 = P3^3; sbit valve = P1^0; sbit fan = P1^1; void init();- 键盘扫描
int key_scan() { if (key1 == 0) { while (!key1); return 1; } if (key2 == 0) { while (!key2); return 2; } return 0; }- 温度检测
float get_temp() { unsigned char temp_l, temp_h; float temp; ds18b20_init(); ds18b20_write_byte(0xcc); ds18b20_write_byte(0x44); delay_ms(750); ds18b20_init(); ds18b20_write_byte(0xcc); ds18b20_write_byte(0xbe); temp_l = ds18b20_read_byte(); temp_h = ds18b20_read_byte(); temp = ((temp_h << 8) + temp_l) * 0.0625; return temp; }- LCD 显示
void lcd_display(float temp, int mode) { char str[16] = {0}; memset(str, ' ', sizeof(str)); sprintf(str, 'Temp:%.2fC', temp); lcd1602_display_str(0, 0, str); memset(str, ' ', sizeof(str)); if (mode == 1) { sprintf(str, 'Mode:Ventilation'); } else if (mode == 2) { sprintf(str, 'Mode:Cooling'); } lcd1602_display_str(1, 0, str); }- 报警检测
void check_alarm(float temp, int mode) { if (mode == 1 && temp > 60) { lcd1602_display_str(0, 0, 'Alarm:Overheat! '); } else if (mode == 2 && temp > 10) { lcd1602_display_str(0, 0, 'Alarm:Overcool! '); } }- 主函数
void main() { float temp; int mode = 1; int fan_status = 0; int valve_status = 0; init(); while (1) { temp = get_temp(); lcd_display(temp, mode); check_alarm(temp, mode); switch (mode) { case 1: valve = 0; fan = 1; break; case 2: valve = 1; fan = 1; break; } if (key_scan() == 1) { mode = 1; } else if (key_scan() == 2) { mode = 2; } } } -
进阶任务实现
- 初始化
#include "main.h" #include "ds18b20.h" #include "lcd1602.h" extern TIM_HandleTypeDef htim3; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM3_Init(void); float get_temp(); void lcd_display(float temp, int mode); void check_alarm(float temp, int mode); int key_scan(); int mode = 1; float temp; int fan_status = 0; int valve_status = 0; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM3_Init(); ds18b20_init(&htim3); lcd1602_init(&htim3); while (1) { temp = get_temp(); lcd_display(temp, mode); check_alarm(temp, mode); switch (mode) { case 1: valve_status = 0; fan_status = 1; break; case 2: valve_status = 1; fan_status = 1; break; } HAL_GPIO_WritePin(VALVE_GPIO_Port, VALVE_Pin, valve_status); HAL_GPIO_WritePin(FAN_GPIO_Port, FAN_Pin, fan_status); HAL_Delay(100); if (key_scan() == 1) { mode = 1; } else if (key_scan() == 2) { mode = 2; } } }- 键盘扫描
int key_scan() { if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { while (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET); return 1; } if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { while (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET); return 2; } return 0; }- 温度检测
float get_temp() { unsigned char temp_l, temp_h; float temp; ds18b20_write_byte(&htim3, 0xcc); ds18b20_write_byte(&htim3, 0x44); HAL_Delay(750); ds18b20_write_byte(&htim3, 0xcc); ds18b20_write_byte(&htim3, 0xbe); temp_l = ds18b20_read_byte(&htim3); temp_h = ds18b20_read_byte(&htim3); temp = ((temp_h << 8) + temp_l) * 0.0625; return temp; }- LCD 显示
void lcd_display(float temp, int mode) { char str[16] = {0}; memset(str, ' ', sizeof(str)); sprintf(str, 'Temp:%.2fC', temp); lcd1602_display_str(&htim3, 0, 0, str); memset(str, ' ', sizeof(str)); if (mode == 1) { sprintf(str, 'Mode:Ventilation'); } else if (mode == 2) { sprintf(str, 'Mode:Cooling'); } lcd1602_display_str(&htim3, 1, 0, str); }- 报警检测
void check_alarm(float temp, int mode) { if (mode == 1 && temp > 60) { lcd1602_display_str(&htim3, 0, 0, 'Alarm:Overheat! '); } else if (mode == 2 && temp > 10) { lcd1602_display_str(&htim3, 0, 0, 'Alarm:Overcool! '); } }- 定时器配置
void MX_TIM3_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim3.Instance = TIM3; htim3.Init.Prescaler = 72 - 1; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 5000 - 1; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } }- DS18B20 驱动
#include "ds18b20.h" void ds18b20_init(TIM_HandleTypeDef *htim) { htim->Instance->PSC = 72 - 1; htim->Instance->ARR = 5000 - 1; HAL_TIM_Base_Start(htim); } void ds18b20_write_bit(TIM_HandleTypeDef *htim, unsigned char bit) { HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); HAL_Delay(bit ? 5 : 65); HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); HAL_Delay(bit ? 65 : 5); } unsigned char ds18b20_read_bit(TIM_HandleTypeDef *htim) { unsigned char bit = 0; HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); HAL_Delay(5); HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); HAL_Delay(5); if (HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin) == GPIO_PIN_SET) { bit = 1; } HAL_Delay(60); return bit; } void ds18b20_write_byte(TIM_HandleTypeDef *htim, unsigned char byte) { unsigned char i; for (i = 0; i < 8; i++) { ds18b20_write_bit(htim, (byte >> i) & 0x01); } } unsigned char ds18b20_read_byte(TIM_HandleTypeDef *htim) { unsigned char i, temp = 0; for (i = 0; i < 8; i++) { temp |= ds18b20_read_bit(htim) << i; } return temp; }
注:以上代码仅供参考,具体实现需根据实际硬件电路和控制要求进行调整。
原文地址: https://www.cveoy.top/t/topic/oYsr 著作权归作者所有。请勿转载和采集!