14.1.3 消息队列应用:传感器数据融合设计

1.任务要求
有两个传感器数据采集任务:一个光照度采集任务,一个温度采集任务。一个数据处理任务:当采集的光照度小于30 lx时,LED0指示灯亮,反之熄灭;当采集的温度小于15℃时,LED1指示灯亮,反之熄灭。将处理信息通过串口传输到计算机。请利用消息队

图14.5 硬件电路图
2.硬件设计
硬件电路图如图14.5所示。电路由STM32F1系列MCU、CH340串口转USB芯片、LED 0和LED 1指示灯、数据采集模块构成,ADC数据采集可参考第9章相关内容。
3.软件设计
该应用项目采用消息队列的方式传输两个任务的数据,此处数据采集部分的程序省略,读者可自行添加。设消息队列长度为2,单个数据大小为4个字节。
两个发送任务的优先级设成一样,轮流发送(若是有条件发送,则可设置成不同的优先级)。
接收的数据分别通过串口显示出来,并根据数值的不同进行相应的控制。
参考程序如下。(https://www.daowen.com)



4.仿真与调试
在Keil-MDK中进行仿真,也可以下载到硬件,通过串口调试助手观察,队列运行效果如图14.6所示。

图14.6 队列运行效果
Task1_Adc任务是最高优先级任务,它先执行,向队列xQueue写入两个数据“40”,把队列写满了。Task1_Adc任务再发起第3次写xQueue操作时,进入阻塞态。
FreeRTOS调度器进行调度,此时Task2_Temp任务是最高优先级的就绪态任务,它开始执行。但此时队列已满,因此进入阻塞态。
FreeRTOS调度器又开始调度,此时Task3_Receiver任务为最高优先级的就绪态任务,它从队列中读取一个数据“40”。此时队列未满,任务Task1_Adc和Task2_Temp均处于等待状态,FreeRTOS规定优先级高的任务先执行,如果优先级一样,那么等待时间越久的任务越先执行。这时Task2_Temp任务已经阻塞很久了,向队列xQueue写数据“70”,然后队列又满了,进入阻塞态。
Task3_Receiver任务变为最高优先级的就绪态任务,它从队列中读取一个数据。此时Task1_Adc任务等待时间较久,因此它向队列写入一个数据,由于队列又满了,所以进入阻塞态,Task3_Receiver任务又运行,就这样实现任务通信。
在接收任务中,若接收到的数据大于设定的阈值,则对相应的LED进行操作。