最近帮学生写了点毕设--基于stm32智能家居项目,比较简单的一个项目作为初学stm32入门也是不错的一个项目,有想要的可以评论,免费。
后续将持续更新本项目,新增功能或者优化程序结构
1. 模块
注意事项 : 任何模块 vcc gnd 不能接反 模块一旦接反基本上就不能不能使用了 串口收发不能接反
GY39 串口2
DR ---- PA2
CT ---- PA1
vcc --- 5V
GND --- GND
MQ2 ADC1_IN4
VCC ---- 3V3
GND ---- GND
AO ---- PA4
火源探测器 GPIO
VCC ---- 3V3
GND ---- GND
DO ---- PF1
LED控制继电器 GPIO
VCC ---- 3V3
GND ---- GND
蓝牙 串口1
VCC ---- 5V
GND ---- GND
TXD ---- PA10
RXD ---- PA9
2. 硬件框图
3. 程序逻辑
3.1 初始化
初始化 主要是进行各种外设、模块、数据的初始化的
例如:stm32 GPIO外设初始化、LCD屏幕模块初始化、GY39参数设置等
/*
1. 设备初始化
a 温湿度 GY39 uart2
b 火源检测 IO
c 烟雾检测 AO
d 灯光开关 2 IO --- LED KEY
e 远程控制 蓝牙、 红外、 wifi 模块
uart1 IO+外部中断+TIMER uart2
f LCD显示
g 报警 --- 蜂鸣器 --- IO
*/
// 系统时基单元 1ms 一次中断
SysTick_MyConfig();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
// GY39初始化
GY39Config();
// 蓝牙初始化
BLEConfig();
// 火源检测 IO 初始化 读取 PF1 引脚状态
FireConfig();
// 烟雾检测 ADC 初始化
MQ2ADCConfig();
// 灯光 IO 初始化 PF0
LEDConfig();
// 按键 IO 初始化 PE3
KEYConfig();
// 蜂鸣器 IO 初始化
BeepConfig();
// LCD初始化
LCD_FSMC_Init();
LCD_Init();
LCD_Clear(0xFFFF);
3.2 业务逻辑
业务逻辑部分即为整个程序功能的运行,主要包括 数据更新、按键检测、界面刷新、报警检测、蓝牙数据解析
本部分主要包括对 main.c 中 程序逻辑进行说明 只是相应功能代码进行解析
3.2.1 数据更新
/* GETSYSTIME() 该函数为当前系统时间获取 系统时间以上电时间计时开始 ms为单位
* DetecTime 上一次更新时间 DETECTIME 更新间隔 默认设置为 5000ms
* 例如 上次更新时间 12ms DetecTime == 12 下一次更新时间应为 5012ms时
* 如果当前系统时间为 2356ms 即 GETSYSTIME() === 2536 则不进行数据更新
*/
if ( GETSYSTIME() > (DetecTime + DETECTIME) )
{
// 获取温湿度 5s获取一次 GY39
GetGY39Data();
// 火源检测 5s获取一次
GetFireSta();
// 烟雾检测 5s获取一次
SmokeConversion();
DetecTime = GETSYSTIME();
// 屏幕显示
LCDShow();
// 数据上传蓝牙
BLESendData(BLEMsgBuf);
}
// 控制灯的状态
LEDCtr();
// 解析温度湿度数据
GY39TempAndHumi();
3.2.2 按键检测
// 按键开关灯
if ( GetKeyStat() == 0 )
{
LEDSetSta( !LEDGetSta() );
// 等待按键松开
while( GetKeyStat() == 0 );
}
3.2.3 报警检测
// 报警判断
WarnDectec();
uint8_t tempH = 28;
int8_t tempL = -1;
uint8_t humiH = 80;
uint8_t humiL = 10;
uint8_t smokeH = 60;
// 检测温度 湿度 火源 烟雾数据 是否有异常
void WarnDectec(void)
{
// 测试值
if ( Temp > tempH || Temp < tempL || Humi > humiH || Humi < humiL || Smoke > smokeH || fireSta )
BeepCtr(1);
else
BeepCtr(0);
}
3.2.4 蓝牙数据解析
// main 函数
// 解析蓝牙数据
BLERecvCtr();
/*
蓝牙数据包支持的的数据格式
thu thd tlu tld hhu hhd hlu hld su sd lo lc
每个字符的含义:
首字母 t temp
h humi
s smoke
l led
三字节数据 第二个字母
h 上限
l 下限
双字节数据 第二个字母
u 加
d 减
o 打开
c 关闭
第三个字母
u 加
d 减
*/
void BLERecvCtr()
{
// 如果接收数据成功
if ( BLEGetSta() )
{
uint8_t *t = BLEGetMsg();
switch ( t[0] )
{
case 't' :
tempMsgCtr(t);
break;
case 'h' :
humiMsgCtr(t);
break;
case 's' :
smokeMsgCtr(t);
break;
case 'l' :
LedMsgCtr(t);
break;
default : break;
}
BLESetSta(0);
}
}
void tempMsgCtr(uint8_t *msg)
{
switch( msg[1] )
{
case 'h' :
if ( msg[2] == 'u' )
tempH++;
else if ( msg[2] == 'd' )
tempH--;
break;
case 'l' :
if ( msg[2] == 'u' )
tempL++;
else if ( msg[2] == 'd' )
tempL--;
break;
default :
break;
}
}
void humiMsgCtr(uint8_t *msg)
{
switch( msg[1] )
{
case 'h' :
if ( msg[2] == 'u' )
humiH++;
else if ( msg[2] == 'd' )
humiH--;
break;
case 'l' :
if ( msg[2] == 'u' )
humiL++;
else if ( msg[2] == 'd' )
humiL--;
break;
default :
break;
}
}
void smokeMsgCtr(uint8_t *msg)
{
if ( msg[1] == 'u' )
smokeH++;
else if ( msg[1] == 'd' )
smokeH--;
}
void LedMsgCtr(uint8_t *msg)
{
if ( msg[1] == 'o' )
LEDSetSta(1);
else if ( msg[1] == 'c' )
LEDSetSta(0);
}
3.2.5 界面刷新
// 屏幕显示
LCDShow();
void LCDShow()
{
if ( machineSta )
{
char dataBuf[20];
LCD_Clear(0xffff);
GetTempAndHumi(&Temp, &Humi);
sprintf(dataBuf, "temp:%d", Temp);
LCD_DisPlayStr(0, 0, (u8 *)dataBuf, 0x0000, 0xffff);
sprintf(dataBuf, "humi:%d %%", Humi);
LCD_DisPlayStr(0, 18, (u8 *)dataBuf, 0x0000, 0xffff);
if ( fireSta == 0 )
LCD_DisPlayStr(0, 36, (u8 *)"fireSta: Normal", 0x0000, 0xffff);
else
LCD_DisPlayStr(0, 36, (u8 *)"fireSta: Abnormal", 0x0000, 0xffff);
Smoke = GetSmokeData() * 100 / 4095;
sprintf(dataBuf, "smoke:%d %%", Smoke);
LCD_DisPlayStr(0, 54, (u8 *)dataBuf, 0x0000, 0xffff);
if ( ledSta )
LCD_DisPlayStr(0, 72, (u8 *)"LEDSta: ON", 0x0000, 0xffff);
else
LCD_DisPlayStr(0, 72, (u8 *)"LEDSta: OFF", 0x0000, 0xffff);
sprintf(BLEMsgBuf, "T:%d Th:%d Tl:%d H:%d Hh:%d Hl:%d f:%d s:%d sH:%d l:%d", Temp, tempH, tempL, Humi, humiH, humiL, fireSta, Smoke, smokeH, ledSta);
}
else
{
char dataBuf[20];
LCD_Clear(0xffff);
sprintf(dataBuf, "temp:%d", Temp);
LCD_DisPlayStr(0, 0, (u8 *)dataBuf, 0x0000, 0xffff);
sprintf(dataBuf, "humi:%d %%", Humi);
LCD_DisPlayStr(0, 18, (u8 *)dataBuf, 0x0000, 0xffff);
if ( fireSta == 0 )
LCD_DisPlayStr(0, 36, (u8 *)"fireSta: Normal", 0x0000, 0xffff);
else
LCD_DisPlayStr(0, 36, (u8 *)"fireSta: Abnormal", 0x0000, 0xffff);
sprintf(dataBuf, "smoke:%d %%", Smoke);
LCD_DisPlayStr(0, 54, (u8 *)dataBuf, 0x0000, 0xffff);
if ( ledSta )
LCD_DisPlayStr(0, 72, (u8 *)"LEDSta: ON", 0x0000, 0xffff);
else
LCD_DisPlayStr(0, 72, (u8 *)"LEDSta: OFF", 0x0000, 0xffff);
sprintf(BLEMsgBuf, "T:%d Th:%d Tl:%d H:%d Hh:%d Hl:%d f:%d s:%d sH:%d l:%d", Temp, tempH, tempL, Humi, humiH, humiL, fireSta, Smoke, smokeH, ledSta);
machineSta = 1;
}
}