一、接口介绍
1.1xQueueSendFromISR()
参数:
xQueue:队列句柄;
pvItemToQueue:指向要发送的信息,发送时会将此信息拷贝到队列中;
pxHigherPriorityTaskWoken:NULL。
1.2.xQueueReceive()
参数:
xQueue:队列句柄;
pvBuffer:保存数据的缓冲区,读取队列时会将读取到的数据拷贝到此区中;
xTicksToWait:阻塞时间,当队列空时任务进入阻塞态等待队列有数据的最大时间。若为0,当队列空时立即返回;若为portMAX_DELAY,会一直等待,直到队列有数据。
返回值:
pdTRUE:从队列中读取数据成功。
pdFALSE:从队列中读取数据失败。
二、出入队过程
三、代码编写
3.1从中断中入队
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
if (huart == &huart1) {
for(uint8_t i = 0; i < Size; i++)
{
xQueueSendFromISR(myQueue01Handle, &rxdata[i], NULL);
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxdata, sizeof(rxdata));
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
}
3.2接收任务
其中,参数portMAX_DELAY,代表该队列要一直等待,除非有入队的才会执行下面的代码,如果没有则该任务会一直处于阻塞态。
其中,参数50,如果有超过50ms没有出队,则返回值会变成pdFALSE便退出while循环。
void StartTask03(void const * argument)
{
/* USER CODE BEGIN StartTask03 */
uint8_t Myindex;
/* Infinite loop */
for(;;)
{
Myindex = 0;
if(xQueueReceive(myQueue01Handle, &u8redata[Myindex++], portMAX_DELAY) == pdPASS) {
while(xQueueReceive(myQueue01Handle, &u8redata[Myindex++], 50));
u8redata[Myindex] = '\0';
StringAnalysis(u8redata);
memset(u8redata, 0, 20);
}
}
/* USER CODE END StartTask03 */
}
3.3字符串解析函数
void StringAnalysis(uint8_t * p) {
uint8_t i;
for(i = 0; i < NumLed; i++) {
if(strcmp((char const *)p, (char const *)OpenLed[i]) == 0) {
HAL_GPIO_WritePin(LedPort[i], Led_Pin[i], 0);
return;
}
}
for(i = 0; i < NumLed; i++) {
if(strcmp((char const *)p, (char const *)CloseLed[i]) == 0) {
HAL_GPIO_WritePin(LedPort[i], Led_Pin[i], 1);
return;
}
}
}
3.4封装
/*Cube配置队列长度为20,单位长度为uint8_t的消息队列*/
#define NumLed 2
...
GPIO_TypeDef * LedPort[NumLed] = {
LED0_GPIO_Port,
LED1_GPIO_Port,
};
uint16_t Led_Pin[NumLed] = {
LED0_Pin,
LED1_Pin,
};
uint8_t rxdata[20] = { 0 };//串口用
uint8_t u8redata[20];//出队用
uint8_t * OpenLed[NumLed] = {
"openled0",
"openled1",
};
uint8_t * CloseLed[NumLed] = {
"closeled0",
"closeled1",
};
四、实验现象
当使用串口助手发送openled0,openled1相应的led会点亮;发送closeled0,closeled1相应的led会关闭。