计划在 FreeRTOS 中添加指令识别和处理的功能,使用uart1作为打印串口 uart2作为指令输入串口
测试时发现只有在2400波特率下能够完整接收到串口发送过来的数据,高于这个波特率如4800、9600等就无法完整接收
主程序如下:
#include "debug.h"
#include "ch32x035_conf.h"
//#include "FLASH.h"
/* Freertos includes */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Standard includes */
#include
#include
#include
#include
/* 使用消息队列实现串口接收数据的处理 */
/* Global define */
#define TASK1_TASK_PRIO???? 5
#define TASK1_STK_SIZE????? 256
#define TASK2_TASK_PRIO???? 5
#define TASK2_STK_SIZE????? 256
#define MAX_MSG_LENGTH????? 100
/* Global variables */
TaskHandle_t Task1Task_Handler;
TaskHandle_t Task2Task_Handler;
QueueHandle_t MsgQueue_Handle;
QueueHandle_t Usart2TxQueue_Handle; // USART2 发送队列句柄
static uint8_t msg[MAX_MSG_LENGTH] = {0};
static uint32_t msg_length = 0;
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
///* USART2 receive interrupt handler */
void USART2_IRQHandler(void)
{
??? BaseType_t xHigherPriorityTaskWoken = pdFALSE; // 初始化为 pdFALSE
??? if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
??? {
??????? msg[msg_length] = USART_ReceiveData(USART2);
??????? printf("ch :%d\r\n", msg[msg_length]);
??????? printf("msg_length :%d\r\n", msg_length);
??????? if (msg[msg_length] != 10)
??????? {
??????????? msg_length++;
??????? }
??????? /* End of message */
??????? if (msg[msg_length-1] == 13)
??????? {
??????????? printf("Send message to the queue\r\n");
??????????? /* Send message to the queue */
??????????? xQueueSendToBackFromISR(MsgQueue_Handle, msg, &xHigherPriorityTaskWoken);
??????????? /* Clear the message buffer */
??????????? memset(msg, 0, sizeof(msg));
??????????? msg_length = 0;
??????? }
??? }
//??? /* Clear interrupt flag */
??? USART_ClearITPendingBit(USART2, USART_IT_RXNE);
//??? /* Check if notification is needed */
??? if (xHigherPriorityTaskWoken != pdFALSE)
?? {
?????? portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
?? }
}
/* USART2 configuration */
void USART2_Config(void)
{
??? GPIO_InitTypeDef? GPIO_InitStructure = {0};
??? USART_InitTypeDef USART_InitStructure = {0};
??? NVIC_InitTypeDef? NVIC_InitStructure = {0};
??? /* Enable clock for USART2 and GPIOA */
??? RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
??? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
??? /* Configure USART2 TX-->PA.2?? RX-->PA.3 */
??? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
??? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
??? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
??? GPIO_Init(GPIOA, &GPIO_InitStructure);
??? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
??? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
??? GPIO_Init(GPIOA, &GPIO_InitStructure);
??? /* Configure USART2 */
??? USART_InitStructure.USART_BaudRate = 2400;
??? USART_InitStructure.USART_WordLength = USART_WordLength_8b;
??? USART_InitStructure.USART_StopBits = USART_StopBits_1;
??? USART_InitStructure.USART_Parity = USART_Parity_No;
??? USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
??? USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
??? USART_Init(USART2, &USART_InitStructure);
??? USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
??? /* Configure NVIC for USART2 */
??? NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
??? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
??? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
??? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
??? NVIC_Init(&NVIC_InitStructure);
??? USART_Cmd(USART2, ENABLE);
}
/* Task1 */
void task1_task(void *pvParameters)
{
??? while(1)
??? {
??????? printf("task1_task\r\n");
??????? // TODO: do some work here
??????? vTaskDelay(pdMS_TO_TICKS(3000));
??? }
}
/* Task2 */
void task2_task(void *pvParameters)
{
??? uint8_t msg[MAX_MSG_LENGTH] = {0};
??? uint32_t msg_length = 0;
??? while(1)
??? {
??????? /* Wait for message from the queue */
??????? if (xQueueReceive(MsgQueue_Handle, msg, portMAX_DELAY) == pdTRUE)
??????? {
??????????? printf("Received message: %s\r\n", msg);?????? //
??????????? msg_length = strlen((char *)msg);
??????????? /* TODO: process the received data */
??????????? /* Send response back to USART */
??????????? for (int i = 0; i < msg_length; i++)
??????????? {
??????????????? xQueueSendToBack(Usart2TxQueue_Handle, &msg[i], portMAX_DELAY);
??????????? }
??????? }
??? }
}
int main(void)
{
??? /* Initialize hardware */
??? NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
??? Delay_Init();
??? USART_Printf_Init(115200);
??? USART2_Config();
??? printf("main\r\n");
??? /* Create message queue */
??? MsgQueue_Handle = xQueueCreate(10, MAX_MSG_LENGTH);
??? /* Create USART2 Tx queue */
??? Usart2TxQueue_Handle = xQueueCreate(10, sizeof(uint8_t));
??? printf("Usart2TxQueue_Handle\r\n");
??? /* Create Task1 */
??? xTaskCreate(task1_task,
??????????????? "Task1",
??????????????? TASK1_STK_SIZE,
??????????????? NULL,
??????????????? TASK1_TASK_PRIO,
??????????????? &Task1Task_Handler);
??? /* Create Task2 */
??? xTaskCreate(task2_task,
??????????????? "Task2",
??????????????? TASK2_STK_SIZE,
??????????????? NULL,
??????????????? TASK2_TASK_PRIO,
??????????????? &Task2Task_Handler);
??? /* Start the scheduler */
??? vTaskStartScheduler();
??? /* Should never reach here */
??? while (1)
??? {
??????? // TODO: do something here
??? }
}
测试结果:
2400
串口2
发→◇AABBCCDD
串口1
收←◆ch :65
msg_length :0
ch :65
msg_length :1
ch :66
msg_length :2
ch :66
msg_length :3
ch :67
msg_length :4
ch :67
msg_length :5
ch :68
msg_length :6
ch :68
msg_length :7
ch :13
msg_length :8
Send message to the queue
Received message: AABBCCDD
4800
串口2
发→◇AABBCCDD
串口1
收←◆ch :65
msg_length :0
ch :66
msg_length :1
ch :67
msg_length :2
ch :68
msg_length :3
ch :13
msg_length :4
Send message to the queue
Received message: ABCD