资料齐全:源代码,原理图,PCB和机智云相关教程,参考lun文等!
摘要:本文设计并实现了一种基于STM32F103C8T6单片机的蓝牙智能温控风扇系统。该系统具备OLED显示、自动/手动模式切换、温湿度检测、风扇档位调节、人体红外检测、倒计时以及蓝牙APP远程控制等功能。通过集成多种传感器和执行器,系统能够根据当前温湿度变化自动控制风扇转动,同时支持手机APP远程操作,提高了使用的便捷性和智能化程度。
关键词:STM32F103C8T6;蓝牙;智能温控风扇;自动/手动模式;手机APP远程控制
随着科技的进步和人们生活水平的提高,智能家居设备逐渐走进千家万户。智能温控风扇作为智能家居的重要组成部分,能够根据环境温度和人体需求自动调节风速,为用户提供更加舒适的使用体验。传统的风扇控制方式存在功能单一、操作不便等问题,难以满足现代家庭对智能化、便捷化的需求。因此,设计一种基于STM32单片机的蓝牙智能温控风扇系统具有重要意义。
本系统以STM32F103C8T6单片机为核心控制器,结合温湿度传感器、人体红外传感器、蓝牙模块等,实现了风扇的智能化控制。用户可以通过按键或手机APP设置自动/手动模式,调节风扇档位和定时时间,系统还能根据温湿度变化自动调节风扇转速,为用户提供更加舒适、便捷的使用体验。
本系统主要由STM32F103C8T6单片机、温湿度传感器、人体红外传感器、OLED显示屏、按键模块、风扇驱动模块、蓝牙模块以及手机APP等部分组成。系统架构图如图1所示。
STM32F103C8T6单片机是基于ARMCortex-M3内核的32位微控制器,具有高性能、低功耗、丰富的外设和灵活的功耗管理等特点。在本系统中,STM32F103C8T6单片机作为核心控制器,负责接收传感器数据、处理控制逻辑以及输出控制信号。
OLED显示屏选用0.96寸I2C接口的OLED显示屏。OLED显示屏具有自发光、对比度高、视角广、响应速度快等优点,能够清晰地显示各种信息。通过I2C接口与STM32单片机进行通信,实现温湿度、风扇档数、速度以及模式等信息的显示。
按键模块包括模式切换按键、档位调节按键和定时设置按键。按键通过GPIO引脚与STM32单片机相连,当按键按下时,单片机检测到电平变化,执行相应的操作。
风扇驱动模块采用PWM(脉冲宽度调制)方式控制风扇转速。STM32单片机通过输出不同占空比的PWM信号,调节风扇驱动电路的电压,从而控制风扇的转速。
蓝牙模块选用HC-05蓝牙串口通信模块。HC-05模块能够与手机APP进行蓝牙通信,实现数据的传输和控制指令的接收。通过串口与STM32单片机相连,将单片机处理后的数据发送给手机APP,同时接收手机APP发送的控制指令。
本系统采用Keil uVision作为开发环境。Keil uVision是一款功能强大的单片机开发软件,它支持多种编程语言(如C语言),提供了丰富的库函数和开发工具,方便开发者进行程序编写和调试。
本系统的软件架构主要包括初始化模块、数据采集模块、数据处理模块、控制逻辑模块、显示模块、按键处理模块、蓝牙通信模块以及定时模块等部分。
温湿度数据采集
c复制代码
void DHT11_ReadData(uint8_t *temp, uint8_t *humi) { |
|
uint8_t buffer[5] = {0}; |
|
DHT11_Start(); // 启动DHT11传感器 |
|
if (DHT11_CheckResponse()) { // 检查传感器响应 |
|
buffer[0] = DHT11_ReadByte(); |
|
buffer[1] = DHT11_ReadByte(); |
|
buffer[2] = DHT11_ReadByte(); |
|
buffer[3] = DHT11_ReadByte(); |
|
buffer[4] = DHT11_ReadByte(); |
|
if (buffer[4] == (buffer[0] + buffer[1] + buffer[2] + buffer[3])) { // 校验数据 |
|
*humi = buffer[0]; |
|
*temp = buffer[2]; |
|
} |
|
} |
|
} |
风扇控制
c复制代码
void Fan_Control(uint8_t mode, uint8_t temp, uint8_t temp_threshold, uint8_t *fan_speed) { |
|
if (mode == AUTO_MODE) { |
|
if (Human_Detected() && temp > temp_threshold) { // 人体检测到且温度超过阈值 |
|
if (temp >= 30) { |
|
*fan_speed = 5; // 最高档 |
|
} else if (temp >= 28) { |
|
*fan_speed = 4; |
|
} else if (temp >= 26) { |
|
*fan_speed = 3; |
|
} else if (temp >= 24) { |
|
*fan_speed = 2; |
|
} else { |
|
*fan_speed = 1; |
|
} |
|
Fan_On(*fan_speed); // 开启风扇并设置档位 |
|
} else { |
|
Fan_Off(); // 关闭风扇 |
|
} |
|
} else if (mode == MANUAL_MODE) { |
|
Fan_On(*fan_speed); // 手动模式下根据设置档位开启风扇 |
|
} |
|
} |
蓝牙通信
c复制代码
void Bluetooth_Init(void) { |
|
USART_InitTypeDef USART_InitStruct; |
|
// 初始化USART(用于与蓝牙模块通信) |
|
USART_InitStruct.USART_BaudRate = 9600; |
|
USART_InitStruct.USART_WordLength = USART_WordLength_8b; |
|
USART_InitStruct.USART_StopBits = USART_StopBits_1; |
|
USART_InitStruct.USART_Parity = USART_Parity_No; |
|
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |
|
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; |
|
USART_Init(USART1, &USART_InitStruct); |
|
USART_Cmd(USART1, ENABLE); |
|
} |
|
void Bluetooth_Receive(void) { |
|
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) { |
|
uint8_t data = USART_ReceiveData(USART1); |
|
// 处理接收到的数据,如模式切换、档位调节等指令 |
|
} |
|
} |
定时功能
c复制代码
void Timer_Init(void) { |
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; |
|
// 初始化定时器 |
|
TIM_TimeBaseStruct.TIM_Period = 9999; |
|
TIM_TimeBaseStruct.TIM_Prescaler = 7199; |
|
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; |
|
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; |
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); |
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); |
|
TIM_Cmd(TIM2, ENABLE); |
|
} |
|
void TIM2_IRQHandler(void) { |
|
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { |
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); |
|
if (timer_count > 0) { |
|
timer_count--; |
|
if (timer_count == 0) { |
|
Fan_Off(); // 定时时间到,关闭风扇 |
|
} |
|
} |
|
} |
|
} |
系统测试的主要目的是为了验证智能温控风扇控制系统的设计是否满足预期的功能需求和性能指标。测试内容包括硬件测试和软件测试两个方面。
硬件测试
软件测试
在测试过程中,可能会发现系统的某些部分存在性能瓶颈或不足。针对这些问题,可以对系统进行优化和改进。例如:
本文详细阐述了一种基于STM32F103C8T6单片机的蓝牙智能温控风扇系统的设计与实现。该系统集成了温湿度检测、人体红外检测、OLED显示、按键处理、风扇控制、蓝牙通信以及定时等多种功能,能够根据当前温湿度变化自动控制风扇转动,同时支持手机APP远程操作。通过系统测试和优化,验证了系统的可行性和稳定性。
随着物联网技术的不断发展,智能温控风扇系统有望与家庭物联网系统进行更深入的集成,实现与其他家电的互联互通。未来可以考虑增加更多的智能化功能,如语音控制、智能学习等,进一步提高系统的智能化水平和用户体验。同时,还可以对系统的硬件和软件进行优化和升级,降低系统成本,提高系统的可靠性和稳定性,使其更加适用于家庭、办公室等场所。
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "delay.h"
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
/**********************************************
//IIC Start
**********************************************/
/**********************************************
//IIC Start
**********************************************/
void OLED_IIC_Start()
{
OLED_SCLK_Set() ;
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void OLED_IIC_Stop()
{
OLED_SCLK_Set() ;
// OLED_SCLK_Clr();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
void OLED_IIC_Wait_Ack()
{
//GPIOB->CRH &= 0XFFF0FFFF; //设置PB12为上拉输入模式
//GPIOB->CRH |= 0x00080000;
// OLED_SDA = 1;
// delay_us(1);
//OLED_SCL = 1;
//delay_us(50000);
/* while(1)
{
if(!OLED_SDA) //判断是否接收到OLED 应答信号
{
//GPIOB->CRH &= 0XFFF0FFFF; //设置PB12为通用推免输出模式
//GPIOB->CRH |= 0x00030000;
return;
}
}
*/
OLED_SCLK_Set() ;
OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
// OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
OLED_IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
OLED_IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
OLED_IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
OLED_IIC_Wait_Ack();
OLED_IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
OLED_IIC_Start();
Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
OLED_IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
OLED_IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
OLED_IIC_Wait_Ack();
OLED_IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
Write_IIC_Data(dat);
}
else {
Write_IIC_Command(dat);
}
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
OLED_WR_Byte(0xb0+m,0); //page0-page1
OLED_WR_Byte(0x00,0); //low column start address
OLED_WR_Byte(0x10,0); //high column start address
for(n=0;n<128;n++)
{
OLED_WR_Byte(fill_Data,1);
}
}
}
/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{
unsigned int m;
for(;Del_50ms>0;Del_50ms--)
for(m=6245;m>0;m--);
}
void Delay_1ms(unsigned int Del_1ms)
{
unsigned char j;
while(Del_1ms--)
{
for(j=0;j<123;j++);
}
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
} //更新显示
}
void OLED_On(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
} //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
else {
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_Display_Timer_Data(u8 x, u8 y, u32 Number)
{
u8 Number_String[10][2] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; //注意停止位也要占一个字符
OLED_ShowString(x, y, Number_String [Number / 100 % 10],16);
OLED_ShowString(x +1*8, y , Number_String[ Number / 10 % 10],16);
OLED_ShowString(x + 2*8, y, Number_String[Number % 10],16);
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0) y=y1/8;
else y=y1/8+1;
for(y=y0;y
你可能感兴趣的:(毕业设计1,stm32,智能家居,嵌入式硬件,单片机,物联网)