实验二内容:创建两个动态任务,任务一控制LED的闪烁,任务二用于检测按键。当按键KEY0按下时,任务一被挂起;当按键KEY1被按下时,任务一被取消挂起。
实验三是在实验二的基础上进行修改,增加一个消息队列和两个任务进程;任务二按键检测,当按键被按下时,会发生消息;任务三和任务四负责接收消息。
消息大小为16,消息格式为无符号的16位
#include "stdio.h"
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);//hurat1为串口号,根据自己情况进行选择
return ch;
}
void StartKEY_Task(void const * argument)
{
/* USER CODE BEGIN StartKEY_Task */
/* Infinite loop */
uint16_t ProducerValue = 1;
for(;;)
{
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
{
osDelay(10);//消抖
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
{
if(osMessagePut(myQueue01Handle,ProducerValue,0) != osOK)//0表示发送完等待时间
{
osThreadSuspendAll();
printf("发送失败\r\n");
osThreadResumeAll();
}
else
{
osThreadSuspendAll();
printf("发送成功\r\n");
ProducerValue++;
osThreadResumeAll();
}
}
}
while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)//等待按键释放,防止连续发送
{
osDelay(10);
}
osDelay(1);
}
/* USER CODE END StartKEY_Task */
}
void StartTask03(void const * argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
osEvent event;
for(;;)
{
event = osMessageGet(myQueue01Handle,osWaitForever);//一直等待消息
if(event.status == osEventMessage)
{
printf("任务3数据:%d\r\n",event.value.v);
}
osDelay(1);
}
/* USER CODE END StartTask03 */
}
void StartTask04(void const * argument)
{
/* USER CODE BEGIN StartTask04 */
/* Infinite loop */
osEvent event;
for(;;)
{
event = osMessageGet(myQueue01Handle,osWaitForever);//一直等待消息
if(event.status == osEventMessage)
{
printf("任务4数据:%d\r\n",event.value.v);
}
osDelay(1);
osDelay(1);
}
/* USER CODE END StartTask04 */
}
任务3和任务4争抢时间片接收消息
因为任务3的优先级较高,当任务3是采用osMessageGet()函数接收消息,在其接到之后会删除消息内容,然后任务4不会接收到消息。
将任务3的osMessageGet()更换为osMessagePeek()接收函数
同时在库函数中添加
event.value.v = 0;
因为这个函数是处理32位的数据,而本次实验采用的数据为16位,该函数处理数据时会将这16位数据存在在32位数据的低16位,而将高的十六位用1补充,这会导致输出结果错误(输出-65535),所以添加这句能够使该函数在处理16位数据时,将32位的高16位置为0.
由于osMessagePeek()函数接收消息后,不会删除消息,那么任务4就可以接收到消息。
发送消息
osMessagePut(myQueue01Handle,ProducerValue,0)
删除消息的接收消息
event = osMessageGet(myQueue01Handle,osWaitForever);
不删除消息的接收消息
event = osMessagePeek(myQueue01Handle,osWaitForever);