STM32CubeMX基础例程(小熊派):09.厨房烟雾监测系统加强版
Posted AIoT-韶华分明
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32CubeMX基础例程(小熊派):09.厨房烟雾监测系统加强版相关的知识,希望对你有一定的参考价值。
1、准备开发板
这里我选用了一块网红开发板:”小熊派“,这款板子的人气比较高,还是全国大学生物联网设计竞赛(华为杯)的华为竞赛开发板,我个人也比较喜欢用这款板子,这款板子在放在纸箱吃灰半年之后,被我重新拿了起来,并想借此写博客的机会,整理一下自己的代码。
开发板功能区分布图
开发板俯视图
我们前面实现了一个厨房烟雾监测系统,还有一点点的欠缺,就是不能通过按键进行烟雾浓度阈值的修改,现在我们把这部分功能进行完善。到了这里我们该怎么做呢,方法就是用标志位
。难点主要是在:只有两个按键,但是要实现画面切换,并且修改阈值的操作。解决方法:按键按下的时候,进入阈值设置模式,当再按下上次按键的时候,进行阈值的加或者减,当按下另一个按键的时候,就会回到主菜单,这样就可以巧秒的利用两个按键了。
2、在MDK中编写代码
在main.c中编写以下代码
/* USER CODE BEGIN 0 */
float smoke_value; //烟雾浓度值
float Smoke_UT = 5;//防止开机时阈值比烟雾浓度值小,导致蜂鸣器发声
char LCD_Str[30];
unsigned char F1btn_back_flag; //按键1返回主菜单标志位
unsigned char F2btn_back_flag; //按键2返回主菜单标志位
unsigned char display_mode;//设置显示的模式
typedef enum
{
NORMAL, //正常模式
SETUP //设置模式
}ENUM_DISPLAY_MODE;
//设置当前显示模式
void setDisplayMode(ENUM_DISPLAY_MODE mode)
{
display_mode = mode;
}
//获取当前显示模式
ENUM_DISPLAY_MODE getDisplayMode(void)
{
return display_mode;
}
//阈值修改函数
void Info_Alter(char *info)
{
char *uwRet;
uwRet = strstr(info, "UT");
if (uwRet != NULL)
{
uwRet = strchr(uwRet, ':');
if (uwRet != NULL)
{
uwRet++;
printf("设定烟雾浓度阈值为:%s\\r\\n",uwRet);
Smoke_UT = atof(uwRet);
// printf("烟雾浓度阈值为:%f\\r\\n",Smoke_UT);
}
}
}
//LCD显示函数
void LCD_Display(void)
{
if(getDisplayMode() == NORMAL)
{
sprintf(LCD_Str,"smoke:%0.2f",smoke_value);
LCD_ShowString(40, 50+24+32, 240, 32, 32, LCD_Str); //LCD显示烟雾浓度
}
else
{
sprintf(LCD_Str,"upthv:%0.2f",Smoke_UT);
LCD_ShowString(40, 50+24+32, 240, 32, 32, LCD_Str); //LCD显示烟雾浓度报警阈值
}
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
unsigned char key; //按键值
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
uint32_t smoke_time = 0; //烟雾定时采集
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_SPI2_Init();
MX_TIM2_Init();
MX_TIM16_Init();
/* USER CODE BEGIN 2 */
USART_Interupt_Enable(); //使能串口接收中断和空闲中断
TIM_Interupt_Enable(); //使能定时器更新中断并启动定时器
LCD_Init(); //LCD初始化
LCD_Clear(BLUE);//清屏为蓝色
LCD_ShowString(65, 50+24+32, 240, 32, 32, "Welcome");//显示字符串,字体大小32*32
LCD_Draw_Circle(120, 120, 60);//画圆 半径r=60
LCD_Draw_Circle(120, 120, 80);//画圆 半径r=80
LCD_Draw_Circle(120, 120, 100);//画圆 半径r=100
LCD_Draw_Circle(120, 120, 120);//画圆 半径r=120
HAL_Delay(500); //欢迎页面动画时间
LCD_Clear(BLACK);//清屏为黑色
LCD_ShowString(10, 10, 240, 24, 24, "Monitoring system");//显示字符串,字体大小24*24
LCD_Draw_Circle(120, 120, 85);//画圆 半径r=80
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(time2Count - smoke_time >= 1000) //( 1ms * 1000 )计时一秒
{
smoke_time = time2Count; //记下当前定时器的值
smoke_value = (float)ADC_GetValue()/4096*3.3; //转化为电压值
printf("smoke_value:%f\\r\\n",smoke_value);
if(smoke_value > Smoke_UT) //如果烟雾浓度超过阈值
{
printf("报警中...");
BEEP_ON;//蜂鸣器发声
}
else
{
BEEP_OFF;//蜂鸣器关闭
}
}
key = KEY_Scan(0); //按键扫描函数(在这里不能使用连按)
if(key == 1) //如果按键1按下
{
LED_Set(LED_ON)//点亮LED
F2btn_back_flag = 1; //设置按键2返回主页面使能(再按下按键2返回主界面)
Smoke_UT += 0.1; //将阈值加0.1
if(F1btn_back_flag == 1) //如果按键1返回主页面使能(这时候按下按键1返回主页面)
{
F1btn_back_flag = 0; //将按键1返回主页面失能
setDisplayMode(NORMAL); //设置显示模式为正常模式
continue;
}
setDisplayMode(SETUP); //设置显示模式为设置模式
}
else if(key == 2) //如果按键2按下
{
LED_Set(LED_OFF)//熄灭LED
F1btn_back_flag = 1; //设置按键1返回主页面使能(再按下按键1返回主界面)
Smoke_UT -= 0.1; //将阈值减0.1
if(Smoke_UT<=0) //防止阈值为负数
Smoke_UT = 0;
if(F2btn_back_flag == 1) //如果按键2返回主页面使能(这时候按下按键2返回主页面)
{
F2btn_back_flag = 0; //将按键1返回主页面失能
setDisplayMode(NORMAL); //设置显示模式为正常模式
continue;
}
setDisplayMode(SETUP); //设置显示模式为设置模式
}
LCD_Display(); //在显示LCD上显示画面
if(usart1Info.InfBit.finishFlag == REC_OK) //如果串口数据接收成功
{
usart1Info.rxBuf[usart1Info.InfBit.dataLen++] = '\\0'; //在数组最后添加\\0,这样可以截断字符串
printf("usart1Info.rxBuf:%s\\r\\n",usart1Info.rxBuf); //打印字符串
Info_Alter((char*)usart1Info.rxBuf); //进行阈值的修改
usart1Info.InfBit.finishFlag = REC_WAIT; //将标志位设置成等待接收状态
usart1Info.InfBit.dataLen = 0; //将接收的数据长度设置为0
}
}
/* USER CODE END 3 */
}
3、实验现象
实现的功能 |
---|
1、给单片机上电会显示欢迎界面然后进入烟雾浓度显示界面 |
2、按下按键1控制LED点亮,按下按键2控制LED熄灭 |
3、ADC采集烟雾传感器浓度,并显示到LCD屏幕上 |
4、通过串口助手向单片机发送阈值设置指令,设置阈值成功后会给串口助手返回修改成功信息 |
5、烟雾浓度超过所设置的阈值时,触发蜂鸣器报警 |
6、按下按键1时,就会进入阈值设置画面,再按下按键1,烟雾浓度阈值就会加0.1,当按下按键2的时候就会回到主页面 按下按键2时,就会进入阈值设置画面,再按下按键2,烟雾浓度阈值就会减0.1,当按下按键1的时候就会回到主页面 |
[外链图片转存中…(img-seB2Y1W2-1626783255189)]
以上是关于STM32CubeMX基础例程(小熊派):09.厨房烟雾监测系统加强版的主要内容,如果未能解决你的问题,请参考以下文章
三实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方
STM32CubeMX | | 使用小熊派玩转颜色识别传感器(纯手工打造E53传感器模块)
STM32CubeMX | | 使用小熊派玩转颜色识别传感器(纯手工打造E53传感器模块)
三实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方