基于单片机/STM32的房间通风设备监测控制系统设计

系统概述

本项目设计一个房间通风设备监测控制系统,能够对房间进行通风或制冷,并对通风状态进行检测。新风通过过滤器和盘管,利用送风机送入房间通风管路。如果只需要通风,送风机工作,电磁阀关闭,送入房间通风管路。如果需要冷风,送风机工作,电磁阀打开,高压冷水冷却进风,实现输送冷气的目的。需要检测送风机出口温度,范围10~60℃,检测主管路过滤器后新风流量,当风机运行且流量过小(流量值自设),报警指示过滤器阻塞,发出报警。

基本任务

  • 实时显示送风机出口温度
  • 设置按键选择通风和冷气两种状态
  • 显示电磁阀、送风机的工作状态
  • 对电机运行故障进行报警

进阶任务

  • 设置两个温度传感器检测温度
  • 使用 LCD 显示信息
  • 设置系统启动按键
  • 设计其 C 程序

系统设计

1. 硬件设计

  • 基本任务实现

    • MCU选型:STC89C52
    • 温度传感器:DS18B20
    • LCD:1602A
    • 电磁阀:5V
    • 送风机:12V
    • 按键:5V
  • 进阶任务实现

    • MCU选型:STM32F103C8T6
    • 温度传感器:DS18B20
    • LCD:1602A
    • 电磁阀:5V
    • 送风机:12V
    • 按键:5V

2. 系统框图

image-20211101113528721

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;
    }
    

注:以上代码仅供参考,具体实现需根据实际硬件电路和控制要求进行调整。

基于单片机/STM32的房间通风设备监测控制系统设计

原文地址: https://www.cveoy.top/t/topic/oYsr 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录