项目情况
1、使用软件定时器,每个一秒钟,通过任务通知,让任务采集一次温湿度传感器数据,再把数据进行一个显示
2、多个按键在一起弄一个事件组(也就是三个按键都按下过,就会执行事件组),然后做一个任务通知,通知另外一个任务进行蜂鸣器报警以及串口打印
3、485接口与上位机通讯,通过modbus协议通讯,控制继电器和蜂鸣器,传输温湿度
4、将数据通过串口输出出去
任务介绍
LED1用来做运行指示灯间隔一秒闪烁一次,优先级最低osPriorityLow
KEY任务中按键1用来打印信息,按键2、3、4组合事件组,进行事件组的触发
Display就是数码管的显示,通过软件定时器,每隔一秒钟通知这个任务来刷新显示
Event_Sync就是事件组同步的任务了,就是当按键2、3、4事件都发生了,就会通知这个任务,执行下一步操作
Modbus:单片机通过485接口,使用串口空闲中断加DMA的功能,通过二值信号量通知Modbus,然后Modbus任务进行协议的解析
Queue_Receive:Modbus解析完协议,会将里面的内容放在队列当中,这个任务去读取队列,然后执行读取出的命令,比如操作继电器,操作蜂鸣器
这个项目中基本都是用了前面学到的东西:
1、队列
2、二值信号量
3、事件组
4、任务通知
5、软件定时器
实现功能:软件定时器+任务通知
软件定时器间隔1s获取SHT30数据,任务通知数码管同步显示
1、创建软件定时器
2、配置启动定时器
3、创建显示任务

4、自动生成创建软件定时器以及回调函数、display任务以及任务函数
//创建软件定时器
/* Create the timer(s) */
/* definition and creation of MyTimer01 */
osTimerDef(MyTimer01, vMyTimerCallback);
MyTimer01Handle = osTimerCreate(osTimer(MyTimer01), osTimerPeriodic, NULL);
//软件定时器回调函数
/* vMyTimerCallback function */
void vMyTimerCallback(void const * argument)
{
/* USER CODE BEGIN vMyTimerCallback */
/* USER CODE END vMyTimerCallback */
}
//创建Display任务
/* definition and creation of Display */
osThreadDef(Display, Display_Task, osPriorityBelowNormal, 0, 128);
DisplayHandle = osThreadCreate(osThread(Display), NULL);
//Display任务函数
/* USER CODE END Header_Display_Task */
void Display_Task(void const * argument)
{
/* USER CODE BEGIN Display_Task */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END Display_Task */
}
5、然后就是在软件定时器中发送任务通知,在Display任务中接收任务通知后采集温湿度传感器并显示出来
(1)前面虽然创建了定时器以及回调函数,但是并没有启动定时器,而且没有设置定时器的时间
那么就先启动定时器并设置周期时间,否则就会按照默认的1ms作为周期
/* start timers, add new ones, ... */
if(MyTimer01Handle != NULL)
{
printf("创建软件定时器1成功\r\n");
printf("软件定时器1的周期调整为1000ms\r\n");
xTimerChangePeriod(MyTimer01Handle,1000,0); //修改周期为1000ms
if(xTimerStart(MyTimer01Handle,0) == pdPASS) //启动定时器
{
printf("启动软件定时器1成功\r\n\r\n");
}
}
(2)在定时器回调函数中发送任务通知
/* vMyTimerCallback function */
void vMyTimerCallback(void const * argument)
{
/* USER CODE BEGIN vMyTimerCallback */
//校验形参,可有可无
configASSERT(argument);
//发送任务通知,更新数码管显示
xTaskNotifyGive(DisplayHandle); //DisplayHandle就是Display任务的句柄,说明向这个任务发送通知
/* USER CODE END vMyTimerCallback */
}
(3)在任务中获取通知
/* USER CODE END Header_Display_Task */
void Display_Task(void const * argument)
{
/* USER CODE BEGIN Display_Task */
for(;;)
{
//获取任务通知,在没有获取成功的时间内,会在此阻塞
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
}
/* USER CODE END Display_Task */
}
(4)任务获取通知成功后进行采集数据和显示
/* USER CODE END Header_Display_Task */
void Display_Task(void const * argument)
{
/* U


4万+

被折叠的 条评论
为什么被折叠?



