在Keil vision中试设计一个房间通风设备监测控制系统能够对房间通风或制冷对通风状态进行检测。试设计一个房间通风设备监测控制系统能够对房间通风或制冷对通风状态进行检测。新风通过过滤器和盘管利用送风机送入房间通风管路。如果只需要通风送风机工作电磁阀关闭送入房间通风管路。如果需要冷风送风机工作电磁阀打开高压冷水冷却进风实现输送冷气的目的。需要检测送风机出口温度范围10~60℃检测主管路过滤器后新
基本任务实现:
- 硬件设计
(1)MCU选型:STC89C52
(2)温度传感器:DS18B20
(3)LCD:1602A
(4)电磁阀:5V
(5)送风机:12V
(6)按键:5V
- 系统框图

- 程序设计
(1)初始化
#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();
(2)键盘扫描
int key_scan()
{
if (key1 == 0)
{
while (!key1);
return 1;
}
if (key2 == 0)
{
while (!key2);
return 2;
}
return 0;
}
(3)温度检测
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;
}
(4)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);
}
(5)报警检测
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! ");
}
}
(6)主函数
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;
}
}
}
进阶任务实现:
- 硬件设计
(1)MCU选型:STM32F103C8T6
(2)温度传感器:DS18B20
(3)LCD:1602A
(4)电磁阀:5V
(5)送风机:12V
(6)按键:5V
- 系统框图

- 程序设计
(1)初始化
#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;
}
}
}
(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;
}
(3)温度检测
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;
}
(4)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);
}
(5)报警检测
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! ");
}
}
(6)定时器配置
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();
}
}
(7)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/hvCp 著作权归作者所有。请勿转载和采集!