ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32F407之基于FreeRTOS的串口数据处理

2021-09-17 17:01:01  阅读:295  来源: 互联网

标签:FreeRTOS USART 串口 RX pUSART GPIO STM32F407 Buf USART1


串口数据处理比较频繁时,不用RTOS处理数据容易丢包。

串口数据处理可以用FreeRTOS进行管理,用于支持串口的CMD指令收发。

除了串口任务的创建,定时器创建外,单纯串口数据处理需要进行下面几个步骤。

1 串口初始化与参数初始化

定义串口数据机构体

#define SH _BUFSIZE        512

#define UART_BUFSIZE            1024

typedef struct UART_Buffer

{

         /* @brief Receive buffer. */

         volatile uint8_t RX[SH _BUFSIZE];

         /* @brief Transmit buffer. */

         volatile uint8_t TX[2];

         /* @brief Receive buffer head. */

         volatile uint16_t RX_Head;

         /* @brief Receive buffer tail. */

         volatile uint16_t RX_Tail;

         /* @brief Transmit buffer head. */

         volatile uint16_t TX_Head;

         /* @brief Transmit buffer tail. */

         volatile uint16_t TX_Tail;

         /* @brief RX buffer counting semaphore */  

         volatile xQueueHandle RXBuf_Sem;

         /* @brief TX buffer counting semaphore*/   

         volatile xQueueHandle TXBuf_Sem;

} uart_Buffer_t;

static uart_Buffer_t  SH_Uart_Buf;

配置串口1

void USART1_Config(void)

{       

                   GPIO_InitTypeDef GPIO_InitStructure;  

                   USART_InitTypeDef USART_InitStructure;  //定义串口初始化结构

                   /* 开启GPIO_A  USART1的时钟 */

                   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

                   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

        

                   /*USART1_RX ->PA10*/

                   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;

                   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

                   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

                   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

                   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;

                   GPIO_Init(GPIOA, &GPIO_InitStructure);

                   /*USART1_TX ->PA9*/    

                   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;

                   GPIO_Init(GPIOA, &GPIO_InitStructure);

        

                   GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);

                   GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);

        

                   /*串口通讯参数设置*/

                   USART_InitStructure.USART_BaudRate = 115200; //波特率

                   USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位

                   USART_InitStructure.USART_StopBits = USART_StopBits_1;         //停止位1位

                   USART_InitStructure.USART_Parity = USART_Parity_No;                //校验位 无

                   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制

                   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //使能接收和发送引脚

                   USART_Init(USART1, &USART_InitStructure);

                  

                   USART_ClearFlag(USART1,USART_FLAG_TC);

                   USART_Cmd(USART1, ENABLE);//开启USART1,注意与上面RCC_APB2PeriphClockCmd()设置的区别

}

初始化串口1 buffer

void uart1_init(void)

{

                          /* Init Ring Buffer */

                            SH_Uart_Buf.RX_Tail = 0;

                            SH_Uart_Buf.RX_Head = 0;

                            SH_Uart_Buf.TX_Tail = 0;

                            SH_Uart_Buf.TX_Head = 0;

                            vSemaphoreCreateBinary(SH_Uart_Buf.RXBuf_Sem);

                            SH_Uart_Buf.TXBuf_Sem = NULL ;

                           

                            /* Enable  receive interrupt */

                        USART_ITConfig (USART1, USART_IT_RXNE, ENABLE ); 

                            USART_ITConfig(USART1, USART_IT_TXE, DISABLE ) ;

                           USART_ITConfig(USART1, USART_IT_TC, DISABLE ) ;

                           USART_ITConfig(USART1, USART_IT_IDLE, DISABLE ) ;

                           USART_ITConfig(USART1, USART_IT_LBD, DISABLE ) ;

                           USART_ITConfig(USART1, USART_IT_CTS, DISABLE ) ;

                            USART_ITConfig(USART1, USART_IT_ERR, DISABLE ) ;

                            USART_ITConfig(USART1, USART_IT_ORE, DISABLE ) ;

                            USART_ITConfig(USART1, USART_IT_FE, DISABLE ) ;

                                                                                                                                              

                            /* Enable                       */

                            USART_Cmd(USART1,  ENABLE);         

}

2 串口中断数据处理

void USART1_IRQHandler(void) {

         SH_IRQHandler();

}

void SH _IRQHandler(void) {

         static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

       USART_TypeDef *USART_ID =    USART1 ;

       SHELL_Buffer_t *pUSART_Buf =     & SH_Uart_Buf ;

       unsigned long uxSavedStatusValue ;

       uxSavedStatusValue = portSET_INTERRUPT_MASK_FROM_ISR() ;

         if(USART_GetITStatus(USART_ID, USART_IT_RXNE) != RESET)

         {

                   /* Advance buffer head. */

                   uint16_t tempRX_Head = (pUSART_Buf->RX_Head + 1) & (SH _BUFSIZE -1);

                   /* Check for overflow. */

                   uint16_t tempRX_Tail = pUSART_Buf->RX_Tail;

                   uint8_t data =  USART_ReceiveData(USART_ID);

                   if (tempRX_Head == tempRX_Tail) {

          USART_ITConfig(USART_ID, USART_IT_RXNE, DISABLE);

                   }else{

                            pUSART_Buf->RX[pUSART_Buf->RX_Head] = data;

                            pUSART_Buf->RX_Head = tempRX_Head;

                     USART_ClearITPendingBit(USART_ID, USART_IT_RXNE) ;

                            if(pUSART_Buf->RXBuf_Sem != NULL) {            

                                     xSemaphoreGive(pUSART_Buf->RXBuf_Sem);

                            }

                       portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);   

                   }

         }

         if(USART_GetITStatus(USART_ID, USART_IT_TXE) != RESET)

         {

                   /* Check if all data is transmitted. */

                   uint16_t tempTX_Tail = (pUSART_Buf)->TX_Tail;

                   if (pUSART_Buf->TX_Head == tempTX_Tail){

                            /* Overflow MAX size Situation */

                            /* Disable the USART Transmit interrupt */

                            USART_ITConfig(USART_ID, USART_IT_TXE, DISABLE);

                    

                   }else{

                            uint8_t data = pUSART_Buf->TX[pUSART_Buf->TX_Tail];

                            USART_ID->DR = data;

                     USART_ClearITPendingBit(USART_ID, USART_IT_RXNE) ;

                            (pUSART_Buf)->TX_Tail = (pUSART_Buf->TX_Tail + 1) & (UART_BUFSIZE-1);

                            if (pUSART_Buf->TXBuf_Sem != NULL)

                                     xSemaphoreGiveFromISR( pUSART_Buf->TXBuf_Sem, &xHigherPriorityTaskWoken );

                       portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);   

                   }

         }

       portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue);

}

3 某一个任务重处理接收数据:

uint8_t debug_uart_getch(uint32_t timeout_ms)

{

         SHELL_Buffer_t *pUSART_Buf;

         USART_TypeDef* UART;

         uint8_t ans ;

         pUSART_Buf = & SH_Uart_Buf;

         UART = USART1;

        

#if (UART_HANDLING == UART_INTERRUPT_MODE)

      vPortEnterCritical() ;

   

         if( pUSART_Buf->RX_Head == pUSART_Buf->RX_Tail)

         {

                   vPortExitCritical() ; 

              if (pUSART_Buf->RXBuf_Sem != NULL)

                       xSemaphoreTake(pUSART_Buf->RXBuf_Sem, timeout_ms);

                   return 0;

         }

         ans = (pUSART_Buf->RX[pUSART_Buf->RX_Tail]);

         pUSART_Buf->RX_Tail = (pUSART_Buf->RX_Tail + 1) & (SH _BUFSIZE -1);     

       vPortExitCritical() ;

       USART_ITConfig(UART, USART_IT_RXNE, ENABLE);

         return ans ;

#else

         while (!(UART->SR & USART_FLAG_RXNE));

         return (uint8_t)(UART->DR);

#endif

}

void vSHTaskHandler(void *params)

{       

         uint8_t c;

         USART1_Config()

         uart_init();

         vTaskDelay(10);

         while (1) {         

                   c = uart1_getch(1000 / portTICK_RATE_MS);                  

                   if (c != 0x0) {             

                            处理数据环节;

……

                   }

}

4 发送数据(略)

标签:FreeRTOS,USART,串口,RX,pUSART,GPIO,STM32F407,Buf,USART1
来源: https://blog.csdn.net/rosir_zhong/article/details/120352447

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有