基于stm32的智能风扇设计

该博客详细介绍了基于STM32F103C8T6芯片设计的智能风扇项目,包括手动模式、温控模式和定时模式。在手动模式下,通过触摸键盘控制风扇的开、关和三档风速;温控模式下,结合DHT11温湿度传感器调整阈值,根据环境温度自动调节风扇速度;定时模式下,使用TIM3定时器实现倒计时功能,并可通过触摸键盘设置定时时间。此外,项目还利用OLED显示屏展示各种模式和设置信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

相关程序下载:https://download.youkuaiyun.com/download/ManJuSa/19775016

1 任务要求

题目:基于STM32智能风扇设计

基本要求:通过按键开、关风扇;

通过设定时间,定时关闭风扇;

风扇有普通模式,可以设置为快档,中档,慢档,跟普通风扇一样。

拓展功能:温度控制。OLED显示。

2 系统总体设计

 

DHT11温湿度传感器

STM32F103C8T6

TOUCH触摸键盘

TIM3定时器

OLED15864显示屏

PWM直流电机

此次采用STM32F103C8T6芯片进行设计风扇,该风扇有三种模式,分别是手动模式,温控模式,定时模式。模式切换用触摸键盘KEY_B控制。KEY_A控制手动模式开关和慢、中、快档,温控模式下的阈值选择,定时模式下的阈值选择。KEY_C控制温控和定时模式下的阈值加值。KEY_D控制温控模式下的减值以及定时模式下的定时开启开关。

将以上所有结果显示到OLED显示屏上,每个模式都有一个新的页面,方便、简洁。TIM3定时器用来产生1s中断给倒计时计时。另外,所有档位都有输出PWM脉冲,将PWM脉冲连接到直流电机即可转动不同速度。本次课设将利用继电器模拟电机的启停。

3 单元电路设计

3.1 STM32F103主芯片

STM32F103C8T6是一款基于ARM Cortex-M3内核(ARM公司在ARM11以后改用Cortex命名,并分成A、R和M三类,M系列有M0、M0+、M3、M4、M7)的32位的微控制器,采用LQFP48封装,由意法半导体公司(ST)推出,属于STM32系列(ST公司还有SPC5X系列微控制器)。其程序存储器FLASH容量是64KB (64K x 8bit),RAM容量是20KB(20K x 8bit),2个12bit ADC合计12路通道(外部通道只有PA0到PA7、PB0到PB1,并不是18通道),37个通用I/O口(PA0-PA15、PB0-PB15、PC13-PC15、PD0-PD1),4个16bit通用定时器(TIM1(带死区插入,常用于产生PWM控制电机)、TIM2、TIM3、TIM4),2个看门狗定时器(独立看门狗、窗口看门狗)1个24bit向下计数的滴答定时器(很重要,一般delay都使用这个定时器实现),2*IIC,2*SPI,3*USART,1*CAN,工作电压2V~3.6V,工作温度为-40°C ~ 85°C,系统时钟最高可到72MHz(一般是由8MHz的外部时钟经锁相环9倍频到72MHz)。

3.2 DHT11温湿度传感器

DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。

数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。

DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号,DHT11 不主动进行温湿度采集。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。

3.3 TOUCH触摸键盘

触摸按键与传统的机械按键相比,不仅美观而且耐用、寿命长,它颠覆了传统意义上的机械按键控制,只要轻轻触摸,就可以实现按键开关的控制、量化调节甚至方向控制。触摸按键已广泛应用于手机、DVD、洗衣机等消费类电子产品中。本文我们就介绍一种简单的触摸按键:电容式触摸按键。开发板上的电容触摸按键其实就是一小块覆铜区域, 也称之为触摸感应区,通常我们会将四周的铜片与电路板地信号连通,触摸感应区设计成方便手指触摸大小,并将其连接在输入捕获通道上。触摸感应区与四周的铜片区域就形成了一个电容,通过检测电容充放电时间即可判断是否有触摸。

此次设计功能如下:

KEY_A控制手动模式下关闭、满档、中档和快挡;控制温控模式下的两个阈值选择;控制定时模式下的三个时间阈值选择。

KEY_B控制界面的选择。默认界面为手动模式,下一页为温控模式,再下一页为定时模式。

KEY_C控制温控模式下的阈值加法以及定时模式下的阈值加法。

KEY_D控制温控模式下的阈值减法以及定时模式下的阈值减法,另外双击它还可以控制定时模式倒计时开关。

3.4 OLED12864显示屏

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。OLED显示技术具有自发光的特性,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角度大,并且能够节省电能。OLED显示技术具有自发光的特性,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角度大,并且能够节省电能,从2003年开始这种显示设备在MP3播放器上得到了应用。

三种模式下都显示“模式”、“风速”,而且不同风速会显示“关”、“慢”、“中”、“快”;在温控模式下还显示了“温湿度”、阈值,定时模式显示倒计时。

3.5 PWM直流电机

脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

直流无刷电机调速的原理就是在驱动电机转动的基础上,将驱动电流由PWM信号来控制,改变PWM信号的脉冲宽度,即通过调节MOSFET通断的时间来调节提供给电机三相的电流大小,从而对电机进行调速控制。STM32部的普通的定时器TIM3和TIM4,每个可以产生四路PWM发生器。

本次设计满档500,中档1000,快挡1500。

说明电路工作原理

此次采用STM32F103C8T6芯片进行设计风扇,该风扇有三种模式,分别是手动模式,温控模式,定时模式。模式切换用触摸键盘KEY_B控制。KEY_A控制手动模式开关和慢、中、快档,温控模式下的阈值选择,定时模式下的阈值选择。KEY_C控制温控和定时模式下的阈值加值。KEY_D控制温控模式下的减值以及定时模式下的定时开启开关。将以上所有结果显示到OLED显示屏上,每个模式都有一个新的页面,方便、简洁。TIM3定时器用来产生1s中断给倒计时计时。另外,所有档位都有输出PWM脉冲,将PWM脉冲连接到直流电机即可转动不同速度。

KEY_A控制手动模式下关闭、满档、中档和快挡;控制温控模式下的两个阈值选择;控制定时模式下的三个时间阈值选择。

KEY_B控制界面的选择。默认界面为手动模式,下一页为温控模式,再下一页为定时模式。

KEY_C控制温控模式下的阈值加法以及定时模式下的阈值加法。

KEY_D控制温控模式下的阈值减法以及定时模式下的阈值减法,另外双击它还可以控制定时模式倒计时开关。

三种模式下显示“模式”、“风速”,而且不同风速会显示“关”、“慢”、“中”、“快”;在温控模式下还显示了“温湿度”、阈值,定时模式显示倒计时。

本次设计满档500,中档1000,快挡1500。

困难问题

我遇到的困难是第一次我选用LM75A温度传感器,在OLED显示出温度值后百分百会卡死,后来改用DHUT11温湿度传感器后没有出现问题。

主程序代码:

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "tim.h"
#include "touch_key.h"
#include "dht11.h"
u8 key=0,mode=0,mode_shoudong=0,speed=0;
u8 time_flag=0,set_time=0;
u8 temp_flag=0,temp_low=25,temp_high=30;
u8 set_hour=0,set_min=0,set_sec=10;
u8 temp_read=0,time_read=0;
int main (void){//主程序
	u8 b[2];
	delay_ms(500);
	RCC_Configuration(); //时钟设置
	RELAY_Init();//继电器初始化
	I2C_Configuration();//I2C初始化
	DHT11_Init();
	OLED0561_Init(); //OLED初始化
	TOUCH_KEY_Init();//按键初始化
	TIM3_NVIC_Init ();//开启TIM3中断向量
	TIM3_Init(9999,7199);//定时器初始化,定时1秒(9999,7199)
	TIM3_PWM_Init(59999,23);//PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms)
	DHT11_ReadData(b);
	delay_ms(1000);//DHT11初始化后必要的延时(不得小于1秒)
	while(1){
		switch(key=key_scan())
		{
			case 1:
				if(mode==0)//手动模式
				{
					
					speed++;
					if(speed==4)
						speed=0;
				}
				if(mode==1)//温控
				{
					temp_flag++;//温控阈值更改标志位
					if(temp_flag==2)
						temp_flag=0;
				}
				if(mode==2)//定时
				{
					time_flag++;//定时更改标志位
					if(time_flag==3)
						time_flag=0;
				}
			break;
			case 2:
				mode++;// mode=0:手动  1:温控自动  2:定时
			OLED_DISPLAY_CLEAR();
			if(mode==3)
				mode=0;
			break;
			case 3:
				if(mode==1)
				{
					if(temp_flag==0)
					{
						if(temp_low<40)
							temp_low++;	
					}
						
					if(temp_flag==1)
					{
						if(temp_high<45)
						temp_high++;
					}
				}
				if(mode==2)
				{
					if(time_flag==0)
					{
						if(set_hour<23)
						set_hour++;
					}
					if(time_flag==1)
					{
						if(set_min<59)
						set_min++;
					}
					if(time_flag==2)
					{
						if(set_sec<59)
						set_sec++;
					}
				}
				break;
			case 4:
				if(mode==1)
				{
					if(temp_flag==0)
					{
						if(temp_low>20)
							temp_low--;	
					}
						
					if(temp_flag==1)
					{
						if(temp_high>25)
						temp_high--;
					}
				}
				if(mode==2)
				{
					if(time_flag==0)
					{
						if(set_hour>0)
						set_hour--;
					}
					if(time_flag==1)
					{
						if(set_min>0)
						set_min--;
					}
					if(time_flag==2)
					{
						if(set_sec>0)
						set_sec--;
					}
				}
				break;
			case 5:
				if(mode==2)
				{
					set_time++;//定时模式开关
					if(set_time==2)
						set_time=0;
				}
			}
		if(mode==0)//手动控制
		{	
			OLED_DISPLAY_16x16(0,0*16,0);//模
			OLED_DISPLAY_16x16(0,1*16,1);//式
			OLED_DISPLAY_8x16(0,5*8,58);//:
			OLED_DISPLAY_16x16(0,4*16,2);//手
			OLED_DISPLAY_16x16(0,5*16,3);//动
							if(speed==0)
			{
				RELAY_1(0);//继电器关闭
				TIM_SetCompare1(TIM3,0);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,14);//关
			}
			if(speed==1)
			{
				RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,500);
					OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,11);//慢
			}
			if(speed==2)
			{
				RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,1000);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,12);//中
			}
			if(speed==3)
			{
				RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,1500);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,13);//快
			}
			
		}
		if(mode==1)//温控
		{		
			DHT11_ReadData(b);
			OLED_DISPLAY_16x16(6,0*16,4);//温
			OLED_DISPLAY_16x16(6,1*16,17);//湿
			OLED_DISPLAY_16x16(6,2*16,6);//度
			OLED_DISPLAY_8x16(6,6*8,':');//
		OLED_DISPLAY_8x16(6,7*8,b[1]/10+0x30);//显示温度值
		OLED_DISPLAY_8x16(6,8*8,b[1]%10+0x30);//
			OLED_DISPLAY_8x16(6,10*8,'C');//
			OLED_DISPLAY_8x16(6,12*8,b[0]%10+0x30);//湿度值
			OLED_DISPLAY_8x16(6,13*8,b[0]%10+0x30);//
			OLED_DISPLAY_8x16(6,15*8,'%');//
			OLED_DISPLAY_16x16(0,0*16,0);//模
			OLED_DISPLAY_16x16(0,1*16,1);//式
			OLED_DISPLAY_8x16(0,5*8,58);//:
			OLED_DISPLAY_16x16(0,4*16,4);//温
			OLED_DISPLAY_16x16(0,5*16,5);//控
			OLED_DISPLAY_16x16(4,0*16,15);//阈
			OLED_DISPLAY_16x16(4,1*16,16);//值
			OLED_DISPLAY_8x16(4,5*8,58);//:
			OLED_DISPLAY_8x16(4,6*8,temp_low/10+0x30);//显示温度低值
			OLED_DISPLAY_8x16(4,7*8,temp_low%10+0x30);
			OLED_DISPLAY_8x16(4,9*8,temp_high/10+0x30);//显示温度高值
			OLED_DISPLAY_8x16(4,10*8,temp_high%10+0x30);			
			if(b[1]<temp_low)
			{
				RELAY_1(0);//继电器关闭
				TIM_SetCompare1(TIM3,0);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,14);//关
			}
			else if(b[1]>=temp_low&b[1]<temp_high)
			{			
				RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,1000);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,12);//中
			}
			else if(b[1]>=temp_high)
			{	
				RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,1500);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,13);//快
			}
		}
		if(mode==2)//定时
		{
			OLED_DISPLAY_16x16(0,0*16,0);//模
			OLED_DISPLAY_16x16(0,1*16,1);//式
			OLED_DISPLAY_8x16(0,5*8,58);//:
			OLED_DISPLAY_16x16(0,4*16,7);//定
			OLED_DISPLAY_16x16(0,5*16,8);//时
			OLED_DISPLAY_16x16(4,0*16,15);//阈
			OLED_DISPLAY_16x16(4,1*16,16);//值
			OLED_DISPLAY_8x16(4,5*8,58);//:
			OLED_DISPLAY_8x16(4,6*8,set_hour/10+0x30);//显示小时阈值
			OLED_DISPLAY_8x16(4,7*8,set_hour%10+0x30);
			OLED_DISPLAY_8x16(4,8*8,58);//:
			OLED_DISPLAY_8x16(4,9*8,set_min/10+0x30);//显示分钟阈值
			OLED_DISPLAY_8x16(4,10*8,set_min%10+0x30);
			OLED_DISPLAY_8x16(4,11*8,58);//:
			OLED_DISPLAY_8x16(4,12*8,set_sec/10+0x30);//显示秒钟阈值
			OLED_DISPLAY_8x16(4,13*8,set_sec%10+0x30);
			if(set_time==1){
				if(set_hour==0&set_min==0&set_sec==0)
				{
					RELAY_1(0);//继电器关闭
				TIM_SetCompare1(TIM3,0);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,14);//关
					set_time=0;
				}
				else
				{
					RELAY_1(1);//继电器打开
				TIM_SetCompare1(TIM3,1500);
				OLED_DISPLAY_16x16(2,0*16,9);//风
				OLED_DISPLAY_16x16(2,1*16,10);//速
				OLED_DISPLAY_8x16(2,5*8,58);//:
				OLED_DISPLAY_16x16(2,5*16,13);//快
				}
			}
			
		}
}
}

定时器tim中断代码

void TIM3_IRQHandler(void){ //TIM3中断处理函数
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){	//判断是否是TIM3中断
			if(mode==2)//定时模式
			{	
					if(set_time)
					{
						set_time_count++;
						if(set_time_count>=50)
						{
							set_time_count=0;										
				if(set_sec>0)
				set_sec--;
				else if(set_min>0)
					{
						set_min--;
						set_sec=59;
					}
				else if(set_hour>0)
						{
							set_hour--;
							set_min=59;
							set_sec=59;
						}
				}
			}
    }
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}

键盘处理程序代码

u8 key_scan(void){
u8 keya=0,keyb=0,keyc=0,keyd=0,keye=0,keyf=0,key_count=0;
	if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A)){ //读触摸按键的电平
		delay_ms(10);
		if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A))
			keya=1;
		while(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A));
	}
	if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B)){ //读触摸按键的电平
		delay_ms(10);
		if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B))
			keyb=1;
		while(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B));
	}
	if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C)){ //读触摸按键的电平
		delay_ms(10);
		if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C))
			keyc=1;
		while(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C));
	}
	if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){ //读触摸按键的电平
			delay_ms(10); //延时去抖动
			if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){//判断长短键
				while((!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D))&&c<KEYD_SPEED1){ //循环判断长按,到时跳转
					c++;delay_ms(10); //长按判断的计时
				}
				if(c>=KEYD_SPEED1){ //长键处理
					//长按后执行的程序放到此处
					keye=1;
					while(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D));
				}else{ //单击处理
					for(b=0;b<KEYD_SPEED2;b++){//检测双击
						delay_ms(10);
						if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){
							a=1;
							//双击后执行的程序放到此处
							keyf=1;
							while(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D));
						}
					}
					if(a==0){ //判断单击
						//单击后执行的程序放到此处
						keyd=1;
						
					}
				}
				a=0;c=0; //参数清0
			}
	}
	if(keya==1)//key_a单击
		key_count=1;
	else if(keyb==1)//key_b单击
		key_count=2;
	else if(keyc==1)//key_c单击
		key_count=3;
	else if(keyd==1)//key_d单击
		key_count=4;
	else if(keye==1)//key_d长按
		key_count=6;
	else if(keyf==1)//key_d双击
		key_count=5;
	return key_count;
}

OLED汉字代码:


#ifndef __CHS_16x16_H
#define __CHS_16x16_H	 

uc8 GB_16[] = {         // 数据表
//"模", 0
			0x10,0x10,0xD0,0xFF,0x94,0x14,0xE4,0xBF,
      0xA4,0xA4,0xA4,0xBF,0xF4,0x26,0x04,0x00,
      0x04,0x03,0x00,0xFF,0x08,0x89,0x8B,0x4A,
      0x2A,0x1E,0x2A,0x2A,0x4B,0xC8,0x48,0x00,

//"式", 1
			0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,
      0xFF,0x10,0x12,0x14,0x10,0x18,0x10,0x00,
      0x00,0x20,0x60,0x20,0x1F,0x10,0x10,0x08,
      0x01,0x06,0x18,0x20,0x40,0x80,0x70,0x00,

//"手", 2
			0x00,0x04,0x24,0x24,0x24,0x24,0x24,0xFC,
      0x22,0x22,0x22,0x33,0x22,0x00,0x00,0x00,
      0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,
      0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x00,

//"动", 3
			0x20,0x24,0x24,0xE4,0x26,0x34,0x20,0x10,
      0x10,0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,
      0x08,0x1C,0x0B,0x08,0x08,0x8A,0x4C,0x30,
      0x0C,0x03,0x40,0x80,0x40,0x3F,0x00,0x00,

//"温", 4
			0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92,
      0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
      0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,
      0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,

//"控", 5
			0x10,0x10,0x10,0xFF,0x90,0x50,0x0C,0x44,
      0x24,0x15,0x06,0x14,0x24,0x54,0x0C,0x00,
      0x02,0x42,0x81,0x7F,0x00,0x40,0x42,0x42,
      0x42,0x42,0x7E,0x42,0x43,0x62,0x40,0x00,

//"度", 6
			0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5,
      0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00,
      0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,
      0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00,

//"定", 7
			0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0xE6,
      0x24,0x24,0x34,0x24,0x04,0x14,0x0C,0x00,
      0x80,0x40,0x20,0x1F,0x20,0x40,0x40,0x7F,
      0x42,0x42,0x43,0x42,0x40,0x60,0x20,0x00,

//"时", 8
			0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,
      0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
      0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,
      0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00,
			
//"风", 9
			0x00,0x00,0xFE,0x02,0x0A,0x12,0x62,0x82,
      0x62,0x1A,0x02,0xFF,0x02,0x00,0x00,0x00,
      0x80,0x40,0x3F,0x20,0x10,0x08,0x06,0x01,
      0x06,0x18,0x00,0x3F,0x40,0x80,0xE0,0x00,

//"速", 10
			0x40,0x42,0x44,0xCC,0x00,0xF4,0x94,0x94,
      0x94,0xFF,0x94,0x94,0x94,0xF6,0x04,0x00,
      0x00,0x40,0x20,0x1F,0x20,0x51,0x48,0x44,
      0x42,0x7F,0x42,0x44,0x4C,0x61,0x20,0x00,

//"慢", 11
			0x40,0x38,0x00,0xFF,0x08,0xD0,0x5F,0x55,
      0xD5,0x55,0xD5,0x55,0x5F,0xE0,0x40,0x00,
      0x00,0x00,0x00,0xFF,0x00,0x83,0x8A,0x5A,
      0x2B,0x2A,0x2B,0x5A,0x4A,0x83,0x80,0x00,

//"中", 12
			0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xFF,
      0x08,0x08,0x08,0x08,0x08,0xFC,0x08,0x00,
      0x00,0x03,0x01,0x01,0x01,0x01,0x01,0xFF,
      0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,

//"快", 13
			0x80,0x70,0x00,0xFF,0x10,0x20,0x10,0x10,
      0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,0x00,
      0x00,0x00,0x00,0xFF,0x82,0x42,0x22,0x1A,
      0x07,0x0A,0x12,0x22,0x43,0xC2,0x42,0x00,
			
//"关", 14
			0x00,0x10,0x10,0x11,0x12,0x1C,0x10,0xF0,
      0x10,0x18,0x14,0x13,0x1A,0x90,0x00,0x00,
      0x81,0x81,0x41,0x41,0x21,0x11,0x0D,0x03,
      0x0D,0x11,0x21,0x21,0x41,0xC1,0x41,0x00,
			
//"阈", 15
			0x00,0xFC,0x11,0xD2,0x50,0x52,0xD2,0x12,
      0xFE,0x12,0x16,0x9A,0x12,0xFF,0x02,0x00,
      0x00,0xFF,0x10,0x17,0x14,0x14,0x57,0x20,
      0x10,0x0F,0x12,0x39,0x80,0xFF,0x00,0x00,

//"值", 16
			0x80,0x40,0x20,0xF8,0x07,0x04,0xE4,0xA4,
      0xA4,0xBF,0xA4,0xA4,0xF6,0x24,0x00,0x00,
      0x00,0x00,0x00,0xFF,0x40,0x40,0x7F,0x4A,
      0x4A,0x4A,0x4A,0x4A,0x7F,0x40,0x40,0x00,
			
//"湿", 17
			0x10,0x22,0x64,0x0C,0x80,0xFE,0x92,0x92,
      0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
      0x04,0x04,0xFE,0x41,0x44,0x48,0x50,0x7F,
      0x40,0x40,0x7F,0x50,0x48,0x64,0x40,0x00,
};

 

<think>好的,我现在需要帮用户解决关于基于STM32智能温控风扇设计方案的问题。首先,用户明确提到了需要设计方案或实现方法,包括温度控制、硬件连接、代码示例等。我需要结合提供的四个引用内容,整理出一个结构清晰的回答。 首先,引用3和4提到了系统的主要组成部分,比如主控芯片、传感器模块、风扇驱动等。硬件部分应该包括STM32主控、温度传感器(比如DS18B20,引用1提到)、PWM控制风扇转速、显示模块(如OLED或LCD,引用4提到)以及用户输入部分(按键)。需要详细说明每个模块的作用和连接方式,比如DS18B20的数据线接哪个GPIO,PWM输出引脚接哪里,按键如何连接等。 然后,温度控制策略是关键部分。引用4提到手动和自动模式,自动模式下根据温度阈值调整转速。可能需要分段控制,比如温度低于阈值关闭,达到阈值后分几个档位,使用PID算法或者线性调整PWM占空比。这里需要参考引用1的代码示例,可能涉及读取温度、比较阈值、计算PWM值等步骤。 软件设计部分需要包括主程序流程、温度采集、PWM生成、模式切换处理。代码示例需要展示初始化、读取温度、控制逻辑,可能用C语言,比如使用HAL库。要注意引用1中的示例代码结构,比如初始化传感器,读取温度,设置PWM占空比,处理按键中断等。 接下来是相关问题的生成。用户可能需要了解如何优化温度采集的精度,如何处理多个传感器,或者如何添加其他功能比如无线控制。问题要围绕设计中的关键点,比如硬件选型、控制算法、模式切换的实现等。 需要注意引用标注,比如在提到温度传感器时引用1和4,主控部分引用2和3,模式切换引用4。确保每个引用在适当的地方被提及,末尾加上标识。 最后,检查回答是否符合系统级指令:行内公式用$,独立公式用$$,中文回答,结构清晰,引用正确。同时,代码块要使用正确的语法,比如Python示例可能换成C,但用户提供的引用中有Python代码示例,可能需要调整。不过用户的问题是关于STM32的,所以应该用C代码示例,比如使用HAL库的函数。 可能还需要考虑硬件连接的具体引脚配置,比如DS18B20使用单总线协议,连接至PA0,PWM输出在PA1,按键接PA2、PA3等。显示模块使用I2C或SPI接口。代码示例需要包括这些初始化和操作步骤。 总结步骤:硬件设计部分分模块说明,软件设计分流程和代码示例,控制策略详细说明自动和手动模式,最后相关问题围绕扩展功能、优化、故障处理等。</think>### 基于STM32智能温控风扇设计方案 #### 一、系统组成 1. **硬件架构** - **主控芯片**:STM32F103C8T6(具备PWM输出、ADC采集、GPIO控制能力)[^2][^3] - **温度传感器**:DS18B20(单总线数字传感器,精度±0.5℃)[^1][^4] - **风扇驱动**:MOS管+电机(通过PWM调节转速) - **显示模块**:0.96寸OLED(显示温度、模式、档位)[^4] - **用户输入**:按键(切换手动/自动模式、调节阈值) 2. **硬件连接** ``` DS18B20_DATA → PA0(单总线通信) OLED_SCL → PB6(I2C时钟) OLED_SDA → PB7(I2C数据) PWM_OUT → PA1(TIM2_CH2控制风扇转速) 按键1 → PA2(模式切换) 按键2 → PA3(阈值调节) ``` #### 二、温度控制策略 1. **自动模式** - 温度阈值分段控制(示例): $$ \text{PWM占空比} = \begin{cases} 0\% & T < 25^\circ C \\ 30\% & 25^\circ C \leq T < 30^\circ C \\ 60\% & 30^\circ C \leq T < 35^\circ C \\ 100\% & T \geq 35^\circ C \end{cases} $$ - 支持PID算法优化动态响应(引用提到"智能化算法运算") 2. **手动模式** 用户通过按键调节4档固定转速(25%/50%/75%/100%)[^4] #### 三、软件设计 ```c // 代码框架示例(基于HAL库) int main(void) { HAL_Init(); DS18B20_Init(); // 温度传感器初始化[^1] PWM_Init(TIM2, 1000); // 1kHz PWM频率[^2] OLED_Init(); while (1) { float temp = DS18B20_ReadTemp(); // 读取温度[^1] OLED_Display(temp, mode); // 显示信息 if (mode == AUTO) { uint8_t duty = Calculate_PWM(temp); // 根据温度计算占空比 PWM_SetDuty(TIM2, duty); } Handle_ButtonPress(); // 处理按键事件 } } ``` #### 四、关键实现细节 1. **温度采集优化** - 采用均值滤波:连续采样5次取平均 - 单总线时序严格校准(DS18B20对时序敏感) 2. **PWM平滑控制** - 使用定时器硬件PWM输出(避免软件延时) - 占空比渐变算法防止突变: $$ duty_{new} = duty_{old} + k \cdot (target - duty_{old}) $$ 其中$k=0.2$为平滑系数[^3] #### 五、测试验证 - 温度控制精度:±1℃(引用测试结果) - 响应时间:<3秒(25℃→35℃全速运转) - 待机功耗:<0.5W(STM32低功耗模式)[^2]
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值