1、准备开发板
这里我选用了一块网红开发板:”小熊派“,这款板子的人气比较高,还是全国大学生物联网设计竞赛(华为杯)的华为竞赛开发板,我个人也比较喜欢用这款板子,这款板子在放在纸箱吃灰半年之后,被我重新拿了起来,并想借此写博客的机会,整理一下自己的代码。
开发板功能区分布图
开发板俯视图
前面我们一共学到了LED、按键、串口收发、ADC、定时器、蜂鸣器、LCD
现在我们将这些外设利用起来做一个综合例程,学到这里你就算是基础入门了,现在你缺少的就是实际的应用,你可以跟着把我的代码敲一遍,这更有利于你的学习。并且我预留了一个功能没有实现,那就是通过按键修改阈值,你可以试着按照自己的想法,试着修改我的代码来进行开发。如果你觉得有点难度,那你就直接点开我博客的第九个例程,学习一下我的开发思路,然后再跟着敲一遍。
难点主要是在:只有两个按键,但是要实现画面切换,并且修改阈值的操作。
2、应用场景
因为我在家煮饭做菜的时候经常会搞得厨房乌烟瘴气,而且做菜的时候总是忘记打开抽油烟机。所以粗心大意的我决定做这套系统,来提醒我打开抽油烟机,还厨房一个干净的环境。
3、市场前景
啥?!做个东西都要市场前景?没前景俺还不做了?!
4、商业价值
我觉得还是有一点点价值的吧,毕竟一个家就有一个厨房。(好吧,我瞎编凑字数的【/狗头】)
5、在MDK中编写代码
什么?要我从头写完所有代码?不可能的,兄弟。代码和文件是我直接复制粘贴过来的,除了main.c,其他文件我压根都没动过,自己回头看我前面几篇教程去!!!
在main.c中编写以下代码
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "key.h"
#include "lcd.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 0 */
float Smoke_UT = 100;//防止开机时阈值比烟雾浓度值小,导致蜂鸣器发声
//阈值修改函数
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);
}
}
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
unsigned char key;
float smoke_value;
char LCD_Str[15];
/* 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, "Wecome!");//显示字符串,字体大小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; //转化为电压值
sprintf(LCD_Str,"smoke:%0.2f",smoke_value);
LCD_ShowString(40, 50+24+32, 240, 32, 32, LCD_Str); //LCD显示烟雾浓度
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
}
else if(key == 2) //如果按键2按下
{
LED_Set(LED_OFF)//熄灭LED
}
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 */
}
6、实验现象
实现的功能 |
---|
1、给单片机上电会显示欢迎界面然后进入烟雾浓度显示界面 |
2、按下按键1控制LED点亮,按下按键2控制LED熄灭 |
3、ADC采集烟雾传感器浓度,并显示到LCD屏幕上 |
4、通过串口助手向单片机发送阈值设置指令,设置阈值成功后会给串口助手返回修改成功信息 |
5、烟雾浓度超过所设置的阈值时,触发蜂鸣器报警 |