写一个串口中断上位机发给单片机,借鉴正点原子串口中断程序,但是我需要FreeRTOS,复盘一下。
先附上代码为敬
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) /* 如果是串口1 */
{
BaseType_t xResult;
printf("进入中断");
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xResult=xSemaphoreGiveFromISR(irqSemaphore,&xHigherPriorityTaskWoken);
printf("释放中断标志函数");
//释放信号量
}
}
void Write_Queue(void)
{
// uint8_t res;
BaseType_t xResult;
for(;;)
{
if(uxSemaphoreGetCount(irqSemaphore) == 1) //串口完成了一次接收
{
xSemaphoreTake(irqSemaphore, portMAX_DELAY);//获取信号量
for(int i=0;i<=sizeof(g_rx_buffer)/sizeof(g_rx_buffer[0]);i++)
{
int a;
a=g_rx_buffer[i];
xQueueSend(g_xQueueUSART1,&a,NULL);
// xQueueSendFromISR(g_xQueueUSART1,&a,NULL); //将数据放入消息队列
}
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xResult=xSemaphoreGive(uartSemaphore); //释放信号量
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
}
}
}
void StartCMDAnalysisTask(void)
{
char Rx_Buffer[20];
// int index=0;
memset(Rx_Buffer,'\0',20);
BaseType_t xStatus;
for(;;)
{
uint8_t res = uxSemaphoreGetCount(uartSemaphore);
if(res == 1) //串口完成了一次接收
{
xSemaphoreTake(uartSemaphore, portMAX_DELAY);//获取信号量
/* 获取消息队列中的数据到Buffer中直至获取到\r */
while(xQueueReceive(g_xQueueUSART1,&Rx_Buffer,( TickType_t ) 10)==pdPASS)
{
printf("\n\r解析数组g_xQueueUSART1 = %s\n\r",Rx_Buffer);
}
memset(Rx_Buffer,'\0',20);
}
osDelay(10);
}
}
问题1: 进入中断就卡死了,收不到数据
**原因:**因为我声明的在中断函数使用的二值量还没定义就进入中断了,
想一下流程:main函数里面初始化GPIO,初始化UASRT,可能还没运行到MX_FREERTOS_Init然后你就去发送数据了进入中断了,中断面对函数里面的二值信号量不知所措,就卡死了。
**问题2:**只能收到一次数据就卡住
原因:
HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
我是使用这个函数来进行数据读取的当然这个读取有个很大问题就是RXBUFFERSIZE满了他才会去中断。言归正传,进入中断以后将数据放入消息队列 ,然后将中断空闲标志位清零,注意,重点:不要忘了再次打开中断。
**问题3:**为什么我用
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET)
判断标志位是否被清除无效?
因为HAL_UART_Receive_IT进入中断回调函数后很有可能UART_FLAG_RXNE标志位置0了,因为不论怎么测试都i没反应,但是我又找不到清除证据,暂且这么理解。
(RXNE中断和IDLE中断的区别?
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。)
**问题4:**因为失误在非中断函数使用xQueueSendFromISR竟然没出现问题不知道怎么回事,有无知道的uu~