首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于STM32的空调温湿度控制系统设计(proteus8.17,Keil标准库)

基于STM32的空调温湿度控制系统设计(proteus8.17,Keil标准库)

作者头像
紫昭
发布2025-11-29 08:13:15
发布2025-11-29 08:13:15
160
举报

proteus仿真效果

模拟电热丝(三挡LED)

heat.c

代码语言:javascript
复制
#include "heat.h"
#include "stm32f10x.h"

// 定义 PB0 - PB2 引脚
#define LED_PIN_0 GPIO_Pin_0
#define LED_PIN_1 GPIO_Pin_1
#define LED_PIN_2 GPIO_Pin_2
#define LED_PORT GPIOB

// 初始化 PB0 - PB2 为输出模式
void LED_GPIO_Init() {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = LED_PIN_0 | LED_PIN_1 | LED_PIN_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT, &GPIO_InitStructure);
}

// 点亮一个 LED(这里以 PB0 为例)
void lightOneLED() {
    GPIO_SetBits(LED_PORT, LED_PIN_0);
	GPIO_ResetBits(LED_PORT, LED_PIN_1 | LED_PIN_2);
}

// 点亮两个 LED(这里以 PB0 和 PB1 为例)
void lightTwoLEDs() {
    GPIO_SetBits(LED_PORT,LED_PIN_0|LED_PIN_1);
	  GPIO_ResetBits(LED_PORT, LED_PIN_2);
}

// 点亮三个 LED
void lightThreeLEDs() {
    GPIO_SetBits(LED_PORT, LED_PIN_0|LED_PIN_1|LED_PIN_2);
}

// 关闭所有 LED
void turnOffAllLEDs() {
    GPIO_ResetBits(LED_PORT, LED_PIN_0 | LED_PIN_1 | LED_PIN_2);
}

heat.h

代码语言:javascript
复制
#ifndef __HEAT_H__
#define __HEAT_H__

// 初始化 PB0 - PB2 为输出模式
void LED_GPIO_Init();
// 点亮一个 LED(这里以 PB0 为例)
void lightOneLED();
// 点亮两个 LED(这里以 PB0 和 PB1 为例)
void lightTwoLEDs();
// 点亮三个 LED
void lightThreeLEDs();
// 关闭所有 LED
void turnOffAllLEDs();

#endif

直流电机模拟风扇

pwm.c

代码语言:javascript
复制
#include "PWM.h" 

void PWM_Init(void) //PWM初始化
{
	//GPIO的结构体定义,定义一个GPIO类型的结构体,名字为GPIO_InitStructure
	GPIO_InitTypeDef GPIO_InitStructure;
	//TIM_TimeBase的结构体定义,定义一个TIM_TimeBase类型的结构体,名字为TIM_TimeBaseInitStructure
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//TIM_OC的结构体定义,定义一个TIM_OC类型的结构体,名字为TIM_OCInitStructure
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	//开启定时器3的时钟,注意是APB1(GPIO的是APB2)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	//开启GPIO的时钟,注意是APB2
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//GPIO引脚的重映射,TIM3_CH1重映射引脚到PB4
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM3, ENABLE);
	//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;		//GPIO_Pin_4;TIM3_CH1重映射引脚到PB4
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); //GPIO_Init(GPIOB, &GPIO_InitStructure); //PB4
	
	//选择定时器的内部时钟源  TIM3
	TIM_InternalClockConfig(TIM3);
	
	//配置定时器时基单元:TIM_TimeBase
	//选择时钟分频,可以选择1分频、2分频和4分频
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1:1分频
	//选择定时器计数方式,可选择向上计数、向下计数、中心对齐计数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM_CounterMode_Up:向上计数
	//设置ARR,即定时器周期:TIM_Period,取值0-65535
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
	//设置PSC,即定时器预分频器的值:TIM_Prescaler,取值0-65535
	TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;		//PSC
	//高级定时器才用的到,重复计算器,先用不上赋值为0
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//TIM_TimeBase初始化
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//初始化配置定时器输出比较单元:TIM_OC
	//设置输出比较的模式:TIM_OCMode_PWM1,PWM1模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	//设置输出比较的极性:TIM_OCPolarity_High;高极性:有效电平为高电平
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	//设置输出使能
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//设置捕获比较寄存器 CCR 的值
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	//初始化定时器3通道1
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);
	
	//使能定时器3
	TIM_Cmd(TIM3, ENABLE);
}

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM3, Compare); //设置捕获比较寄存器 CCR 的值
}

pwm.h

代码语言:javascript
复制
#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"                  // Device header

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);

#endif

motor.c

代码语言:javascript
复制
#include "motor.h"

void Motor_Init(void) //电机引脚初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; //PA4和PA5
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	PWM_Init();
}

void Motor_SetSpeed(int8_t Speed)
{
	if (Speed >= 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_4);
		GPIO_ResetBits(GPIOA, GPIO_Pin_5);
		PWM_SetCompare1(Speed);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_4);
		GPIO_SetBits(GPIOA, GPIO_Pin_5);
		PWM_SetCompare1(-Speed);
	}
}

motor.h

代码语言:javascript
复制
#ifndef __MOTOR_H
#define __MOTOR_H

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);

#endif

继电器模拟水阀作为加湿器

pw.c

代码语言:javascript
复制
#include "pw.h"
#include "stm32f10x.h"

// 定义 PB4 引脚
#define PB4_PIN GPIO_Pin_4
#define PB4_PORT GPIOB

// 初始化 PB4 为输出模式
void PB4_Init() {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 开启 GPIOB 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = PB4_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(PB4_PORT, &GPIO_InitStructure);
}

// 使 PB4 输出高电平
void PB4_On() {
    GPIO_SetBits(PB4_PORT, PB4_PIN);
}

// 使 PB4 输出低电平
void PB4_Off() {
    GPIO_ResetBits(PB4_PORT, PB4_PIN);
}

pw.h

代码语言:javascript
复制
#ifndef __PW_H__
#define __PW_H__


// 初始化 PB4 为输出模式
void PB4_Init();
// 使 PB4 输出高电平
void PB4_On();
// 使 PB4 输出低电平
void PB4_Off();

#endif 

按键控制阈值

keys.c

代码语言:javascript
复制
#include "keys.h"
#include "stm32f10x.h"

// 定义按钮引脚
#define BUTTON_PIN_12 GPIO_Pin_12
#define BUTTON_PIN_13 GPIO_Pin_13
#define BUTTON_PIN_14 GPIO_Pin_14
#define BUTTON_PORT GPIOB

// 初始化 PB12 - PB14 为输入模式(上拉或浮空等根据实际硬件连接确定)
void Button_GPIO_Init() {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = BUTTON_PIN_12 | BUTTON_PIN_13 | BUTTON_PIN_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 这里假设使用上拉输入模式,可根据实际修改
    GPIO_Init(BUTTON_PORT, &GPIO_InitStructure);
}

// 读取按钮状态,如果按下 PB12 返回 1,按下 PB13 返回 2,按下 PB14 返回 3,否则返回 0
uint8_t readButton() {
    if (GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN_12) == 0) {
        return 1;
    } else if (GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN_13) == 0) {
        return 2;
    } else if (GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN_14) == 0) {
        return 3;
    }
    return 0;
}

keys.h

代码语言:javascript
复制
#ifndef __KEYS_H__
#define __KEYS_H__
#include "stm32f10x.h"
// 初始化 PB12 - PB14 为输入模式(上拉或浮空等根据实际硬件连接确定)
void Button_GPIO_Init();
// 读取按钮状态,如果按下 PB12 返回 1,按下 PB13 返回 2,按下 PB14 返回 3,否则返回 0
uint8_t readButton();



#endif

主程序代码

main.c

代码语言:javascript
复制
#include "stm32f10x.h"
#include "stdio.h"
#include  "OLED.h"  //OLED显示屏 
#include "PWM.h"    //PWM输出
#include "motor.h"  //直流电机
#include "Delay.h"
#include "DHT11.h"
#include "stdio.h"
#include "heat.h"//模拟加热
#include "keys.h"//调节阈值
#include "pw.h"//继电器模拟湿度的开启关闭

char dis1[16];
char T_HUD[20];
char T_H_MODE[20];
DHT11_Sensor_Data_TypeDef DHT11_Data;

int8_t Speed = 0;

//阈值相关
	uint8_t tem_up_down=0;
	uint8_t hum_up_down=0;
	uint8_t turn_temp_hum=0;//0:调节温度 1:调节湿度
	uint8_t button_temp;

int main(void)
{ 
	//初始化
	uint8_t tem1;
	uint8_t hum1;
	OLED_Init();
	Motor_Init();
	DHT11_Sensor_GPIO_Configuration();
	Button_GPIO_Init();
	LED_GPIO_Init();
	PB4_Init();
	
	OLED_ShowString(1, 1, "Speed:");
	OLED_ShowString(2, 1, "T:");
	OLED_ShowString(2, 8, "H:");
	while(1){ 
		//阈值控制
		button_temp=readButton();
		if(button_temp==3)
		{
			if(turn_temp_hum==0)
			{
				turn_temp_hum=1;
			}else
			{
				turn_temp_hum=0;
			}
		}else if(button_temp==1)
		{
			if(turn_temp_hum==0)
			{
				tem_up_down++;
			}else
			{
				hum_up_down++;
			}
		}else if(button_temp==2)
		{
			if(turn_temp_hum==0)
			{
				if(tem_up_down==0){}
           else{tem_up_down--;}
			}else
			{
				if(hum_up_down==0){}
           else{hum_up_down--;}
			}
		}
		
		Motor_SetSpeed(Speed);
		OLED_ShowSignedNum(1, 7, Speed, 3);
		if(DHT11_ReadSensorData(&DHT11_Data) == SUCCESS)
		{
			OLED_ShowNum(2, 3, DHT11_Data.temperature_integer, 2);
			OLED_ShowString(2, 5, ".");
			OLED_ShowNum(2,6, DHT11_Data.temperature_decimal, 2);
			
			OLED_ShowNum(2,10, DHT11_Data.humidity_integer, 2);
			OLED_ShowString(2, 12, ".");
			OLED_ShowNum(2, 13, DHT11_Data.humidity_decimal, 2);
		}
		//温度阈值控制
		if((DHT11_Data.temperature_integer>(30+tem_up_down))&&(DHT11_Data.temperature_integer<(35+tem_up_down)))
		{
			Speed=25;
		}else if((DHT11_Data.temperature_integer>=(35+tem_up_down))&&(DHT11_Data.temperature_integer<(40+tem_up_down)))
		{
			Speed=50;
		}
		else if((DHT11_Data.temperature_integer>(40+tem_up_down))&&(DHT11_Data.temperature_integer<(50+tem_up_down)))
		{
			Speed=100;
		}else if((DHT11_Data.temperature_integer<=(30+tem_up_down))&&(DHT11_Data.temperature_integer>=20))
		{
			Speed=0;
		}
		//加热控制
		if(((DHT11_Data.temperature_integer<25)&&(DHT11_Data.temperature_integer>20))||((DHT11_Data.humidity_integer>(30+hum_up_down))&&(DHT11_Data.humidity_integer<(35+hum_up_down))))
		{
			lightOneLED();
		}else if(((DHT11_Data.temperature_integer<=20)&&(DHT11_Data.temperature_integer>15))||((DHT11_Data.humidity_integer>=(35+hum_up_down))&&(DHT11_Data.humidity_integer<(40+hum_up_down))))
		{
			lightTwoLEDs();
		}else if((DHT11_Data.temperature_integer<=15)||((DHT11_Data.humidity_integer>(40+hum_up_down))))
		{
			lightThreeLEDs();
		}else{
			turnOffAllLEDs();
		}
		
		//湿度控制
		if(DHT11_Data.humidity_integer<(25+hum_up_down))
		{
			PB4_On();
		}else 
		{
			PB4_Off();
		}
		
		
		//打印当前的阈值控制
		sprintf(T_HUD,"TUD:%d HUD:%d",tem_up_down,hum_up_down);
		OLED_ShowString(3,1,T_HUD);
		//打印当前调节模式
		sprintf(T_H_MODE,"MODE:%d",turn_temp_hum);
		OLED_ShowString(4,1,T_H_MODE);
		
		 }
}

有什么问题请大家留言斧正,会日常进行这类毕设/课设的更新的

希望大家多多关注,一键三连!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • proteus仿真效果
  • 模拟电热丝(三挡LED)
  • 直流电机模拟风扇
  • 继电器模拟水阀作为加湿器
  • 按键控制阈值
  • 主程序代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档