🤞🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是学习环境控制。
设备的详细功能见网盘中的文章《21、基于STM32的学习环境控制系统设计》:
链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132
提取码:5132
目录
1、系统功能
2、演示视频和实物
3、系统设计框图
4、软件设计流程图
5、原理图
6、主程序
7、总结
1、系统功能
本次的项目是智能学习环境自动调节系统。
1、元器件采用了STM32F103C8T6作为主控,
2、光敏电阻用来检测环境的光照强度,声音传感器模块用来检测环境的噪声。
3、LED灯用来模拟台灯,通过PWM控制实现亮度的调节。
4、超声波传感器用来检测坐姿。
5、语音识别模块用来识别用户的指令,实现语音控制。
6、hc-05蓝牙模块实现在家远程控制。
7、按键模块实现模式控制和亮度调节。
8、蜂鸣器报警模块,当环境噪声大于设定阈值蜂鸣器报警。
9、OLED液晶显示屏用来显示传感器数据。
控制模式有:手动控制,语音控制,蓝牙控制,自动控制。
2、演示视频和实物
基于STM32的智能学习环境设计(版本1)
3、系统设计框图
4、软件设计流程图
5、原理图
6、主程序
#include "sys.h" //有定制和购买的,可以联系VX:lwfw123456789
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
/***********************************************************************************************
同学好!我们是5132单片机设计,定制单片机设计,实物和说明书均可定制,欢迎大家咨询。VX:lwfw123456789
其他项目演示视频和说明请大家移步哔哩哔哩、CSDN和公众号等。
哔哩哔哩:5132单片机设计
CSDN: 5132单片机设计
公众号: 5132单片机设计
抖音 : 5132单片机设计
小红书: 5132单片机设计
咸鱼: 5132单片机设计
************************************************************************************************/
u8 hour_h, min_m, sec_s, msec_ms; //秒表---时、分、秒、毫秒
u8 state, state2, state2_1, state3, state4; //按键状态标志
u8 t = 0; //传感器读取时间间隔
u8 flag; //远程控制标志
u8 flag2 = 0, flag1, flag3;
uint16_t RTC_Time[] = {0, 0, 0};
uint16_t RTC_Time1[] = {7, 0, 0}; //定时时间---开
uint16_t RTC_Time2[] = {19, 0, 0}; //定时时间---关
u8 T_state, T_state1, qingping = 1, state_dingshi_yu_guan, state_dingshi_yu_kai, state_dingshi_yu_switch, state3_1;
uint32_t GuangYu1 = 10,GuangYu2 = 30,GuangYu3 = 50,GuangYu4 = 70;
extern void TimeSet(void);
extern void TimeRead(void);
extern void DingShiMoShi(void);
extern void YuYin(void);
extern void ChuangGan(void);
extern void msec_time(void);
extern void msec_Calcu(void);
void MY_Gizwits_Init(void) //机智云初始化函数
{
TIM3_Int_Init(9, 7199); //1MS系统定时
usart3_init(9600);//WIFI初始化
memset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t)); //设备状态结构体初始化
gizwitsInit();//环形缓冲区初始化
gizwitsSetMode(2); //设置模式
userInit();
}
void shoudong()
{
TimeRead();
if (KeyNum == 2) //按键PB0控制窗户开关
{
delay_ms(20);
if (KeyNum == 2)
{
state2++;
if (state2 > 5)
{
state2 = 0;
}
}
}
switch (state2)
{
case 0:
PWM_SetCompare1(0);
break;
case 1:
PWM_SetCompare1(10);
break;
case 2:
PWM_SetCompare1(30);
break;
case 3:
PWM_SetCompare1(50);
break;
case 4:
PWM_SetCompare1(70);
break;
default:
break;
}
}
void zhidong()
{
switch (state4)
{
case 1:
PWM_SetCompare1(0);
break;
case 2:
PWM_SetCompare1(33);
break;
case 3:
PWM_SetCompare1(66);
break;
case 4:
break;
default:
break;
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
delay_init(); //延时函数初始化
Buzzer_Init(); //下面为外设初始化
OLED_Init();
Key_Init();
AD_Init();
MyRTC_Init();
PWM_Init();
MY_Gizwits_Init(); //机智云初始化
Serial2_Init(); //串口2初始化(语音识别模块)
TIM4_Int_Init(99, 7199);
while (1)
{
userHandle(); //数据上传
gizwitsHandle((dataPoint_t *)¤tDataPoint); //后台处理,必须放在while里
if (t % 10 == 0)
{
AD0 = AD_GetValue(ADC_Channel_1); //光照传感器 PA0
if (AD0 > 4000)AD0 = 4000;
bufe[0] = (u8)(100 - (AD0 / 40));
if(bufe[0]<GuangYu1) state4=4;
else if(bufe[0]<GuangYu2) state4=3;
else if(bufe[0]<GuangYu3) state4=2;
else if(bufe[0]<GuangYu4) state4=1;
}
t++;
KeyNum = Key_GetNum();
if (KeyNum == 1)
{
qingping = 0;
state2 = 0,
delay_ms(20);
if (KeyNum == 1)
{
state++;
if (state > 3)
{
state = 0;
}
}
}
if (state == 0) //远程模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
TimeRead();
ChuangGan();
OLED_ShowChinese(1, 7, 49);
OLED_ShowChinese(1, 8, 50);
}
if (state == 2) //自动模式
{
OLED_ShowChinese(1, 7, 51);
OLED_ShowChinese(1, 8, 52);
TimeRead();
zhidong();
ChuangGan();
msec_time();
}
if (state == 1) //手动模式
{
OLED_ShowChinese(1, 7, 18);
OLED_ShowChinese(1, 8, 52);
ChuangGan();
shoudong();
}
if (state == 3) //语音模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(1, 7, 57);
OLED_ShowChinese(1, 8, 58);
TimeRead();
ChuangGan();
YuYin();
}
}
}
void TimeSet() //设置时间
{
if (KeyNum == 2) //PB10
{
delay_ms(20);
if (KeyNum == 2)
{
T_state++;
if (T_state > 2)
{
T_state = 0;
}
}
}
if (T_state == 0) //时间显示模式
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); //时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); //分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); //秒
RTC_Time[0] = MyRTC_Time[3];
RTC_Time[1] = MyRTC_Time[4];
RTC_Time[2] = MyRTC_Time[5];
}
if (T_state == 1) //修改时间
{
if (KeyNum == 5)
{
delay_ms(20);
if (KeyNum == 5)
{
T_state1++;
if (T_state1 > 2)
{
T_state1 = 0;
}
}
}
if (T_state1 == 0) //修改时
{
if (KeyNum == 4)RTC_Time[0]++;
if (KeyNum == 3)RTC_Time[0]--;
if (RTC_Time[0] > 23 & RTC_Time[0] < 100)RTC_Time[0] = 0;
if (RTC_Time[0] > 100)RTC_Time[0] = 23;
OLED_ShowNum(1, 5, RTC_Time[0], 2); //时
}
if (T_state1 == 1) //修改分
{
if (KeyNum == 4)RTC_Time[1]++;
if (KeyNum == 3)RTC_Time[1]--;
if (RTC_Time[1] > 59 & RTC_Time[1] < 100)RTC_Time[1] = 0;
if (RTC_Time[1] > 100)RTC_Time[1] = 59;
OLED_ShowNum(1, 8, RTC_Time[1], 2); //时
}
if (T_state1 == 2) //修改秒
{
if (KeyNum == 4)RTC_Time[2]++;
if (KeyNum == 3)RTC_Time[2]--;
if (RTC_Time[2] > 59)RTC_Time[2] = 0;
if (RTC_Time[2] > 59 & RTC_Time[2] < 100)RTC_Time[2] = 0;
if (RTC_Time[2] > 100)RTC_Time[2] = 59;
OLED_ShowNum(1, 11, RTC_Time[2], 2); //时
}
}
if (T_state == 2)
{
MyRTC_Time[3] = RTC_Time[0];
MyRTC_Time[4] = RTC_Time[1];
MyRTC_Time[5] = RTC_Time[2];
MyRTC_SetTime();
T_state = 0;
}
}
void TimeRead()
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); //时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); //分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); //秒
}
void DingShiMoShi()
{
TimeRead();
//...............................定时模式..................................../
if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2]))
{
//外设操作
}
if ((MyRTC_Time[3] == RTC_Time2[0]) && (MyRTC_Time[4] == RTC_Time2[1]) && (MyRTC_Time[5] == RTC_Time2[2]))
{
//外设操作
}
//...............................修改定时时间..................................../
OLED_ShowChinese(3, 1, 31);
OLED_ShowString(3, 3, ":");
OLED_ShowNum(3, 5, RTC_Time1[0], 2);
OLED_ShowString(3, 7, ":");
OLED_ShowNum(3, 8, RTC_Time1[1], 2);
OLED_ShowString(3, 10, ":");
OLED_ShowNum(3, 11, RTC_Time1[2], 2);
OLED_ShowChinese(4, 1, 32);
OLED_ShowString(4, 3, ":");
OLED_ShowNum(4, 5, RTC_Time2[0], 2);
OLED_ShowString(4, 7, ":");
OLED_ShowNum(4, 8, RTC_Time2[1], 2);
OLED_ShowString(4, 10, ":");
OLED_ShowNum(4, 11, RTC_Time2[2], 2);
if (KeyNum == 5)
{
delay_ms(20);
if (KeyNum == 5)
{
state_dingshi_yu_switch++;
if (state_dingshi_yu_switch > 2)
{
state_dingshi_yu_switch = 0;
}
}
}
if (state_dingshi_yu_switch == 1) //设置阈值开的时间
{
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state_dingshi_yu_kai++;
if (state_dingshi_yu_kai > 2)
{
state_dingshi_yu_kai = 0;
}
}
}
if (state_dingshi_yu_kai == 0) //时
{
if (KeyNum == 3) RTC_Time2[0]++;
if (KeyNum == 4) RTC_Time2[0]--;
}
if (state_dingshi_yu_kai == 1)//分
{
if (KeyNum == 3) RTC_Time2[1]++;
if (KeyNum == 4) RTC_Time2[1]--;
}
if (state_dingshi_yu_kai == 2)//秒
{
if (KeyNum == 3) RTC_Time2[2]++;
if (KeyNum == 4) RTC_Time2[2]--;
}
}
else
{
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state_dingshi_yu_guan++;
if (state_dingshi_yu_guan > 2)
{
state_dingshi_yu_guan = 0;
}
}
}
if (state_dingshi_yu_guan == 0) //时
{
if (KeyNum == 3) RTC_Time1[0]++;
if (KeyNum == 4) RTC_Time1[0]--;
}
if (state_dingshi_yu_guan == 1)//分
{
if (KeyNum == 3) RTC_Time1[1]++;
if (KeyNum == 4) RTC_Time1[1]--;
}
if (state_dingshi_yu_guan == 2)//秒
{
if (KeyNum == 3) RTC_Time1[2]++;
if (KeyNum == 4) RTC_Time1[2]--;
}
}
if (state3_1 == 0) //时
{
if (KeyNum == 5) RTC_Time1[0]++;
if (KeyNum == 6) RTC_Time1[0]--;
}
if (state3_1 == 1)//分
{
if (KeyNum == 5) RTC_Time1[1]++;
if (KeyNum == 6) RTC_Time1[1]--;
}
if (state3_1 == 2)//秒
{
if (KeyNum == 5) RTC_Time1[2]++;
if (KeyNum == 6) RTC_Time1[2]--;
}
}
void YuYin()
{
if (Serial2_RxFlag == 1) //串口接收到数据包的标志位,若是收到数据包,会置1
{
if (strcmp(Serial2_RxPacket, "LED_ON") == 0)
{
PWM_SetCompare1(66);;
}
else if (strcmp(Serial2_RxPacket, "LED_OFF") == 0)
{
PWM_SetCompare1(0);;
}
Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
}
}
void ChuangGan()
{
char time_ms[8] = {0}; //时间缓冲区
sprintf(time_ms, "%02d:%02d:%02d:%02d", hour_h, min_m, sec_s, msec_ms);
OLED_ShowString(4, 3, time_ms); //oled显示时间
delay_ms(10);
OLED_ShowChinese(2, 1, 53);
OLED_ShowChinese(2, 2, 54);
OLED_ShowString(2, 5, ":");
OLED_ShowNum(2, 6, bufe[0], 2);
OLED_ShowString(2, 8, "%");
OLED_ShowString(3, 1, "LED_DU:");
OLED_ShowNum(3, 8, state2, 1);
}
void msec_time(void)
{
switch (KeyNum)
{
case 2:
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE); //关闭更新中断
TIM_Cmd(TIM4, DISABLE); //关闭时钟
break;
case 3:
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE); //关闭更新中断
TIM_Cmd(TIM4, DISABLE); //关闭时钟
hour_h = 0;
min_m = 0;
sec_s = 0;
msec_ms = 0;
break;
case 4:
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //使能时钟,允许更新中断
TIM_Cmd(TIM4, ENABLE); //使能时钟
break;
default:
break;
}
}
void msec_Calcu(void)
{
msec_ms++;
if (msec_ms == 100)
{
msec_ms = 0;
sec_s++;
if (sec_s == 60)
{
sec_s = 0;
min_m++;
if (min_m == 60)
{
min_m = 0;
hour_h++;
if (hour_h == 60)
{
OLED_Clear(); //OLED清屏
OLED_ShowString(2, 2, "overflow");
}
}
}
}
}
7、总结
该系统以主控芯片为核心,集环境监测、模式控制与外设驱动于一体。通过光照等传感器采集数据,支持远程、手动、自动、语音四种模式。可切换模式控制 LED 亮度,具备秒表功能,利用 WIFI 与机智云交互,语音模块可实现语音控制。