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

2023-05-16

串口数据处理比较频繁时,不用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 发送数据(略)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F407之基于FreeRTOS的串口数据处理 的相关文章

  • STM32F407+ESP8266连接机智云过程详解

    工程创建 代码调试过程参见 STM32F407 ESP8266 程序源码下载 STM32F407 ESP8266连接机智云程序源码
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS系列

    本文主要介绍如何在任务或中断中向队列发送消息或者从队列中接收消息 使用STM32CubeMX将FreeRTOS移植到工程中 创建两个任务以及两个消息队列 并开启两个中断 两个任务 Keyscan Task 读取按键的键值 并将键值发送到队列
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 【FreeRTOS】任务通知的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • FreeRTOS学习---“定时器”篇

    总目录 FreeRTOS学习 任务 篇 FreeRTOS学习 消息队列 篇 FreeRTOS学习 信号量 篇 FreeRTOS学习 事件组 篇 FreeRTOS学习 定时器 篇 FreeRTOS提供了一种软件定时器 用来快速实现一些周期性的
  • RT-Thread记录(五、RT-Thread 临界区保护与FreeRTOS的比较)

    本文聊聊临界区 以及RT Thread对临界区的处理 通过源码分析一下 RT Thread 对临界区保护的实现以及与 FreeRTOS 处理的不同 目录 前言 一 临界区 1 1 什么是临界区 1 2 RTOS中的临界区 二 RT Thre
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • Micropython开发篇三--基于F411 CE的移植编译

    Micropython开发篇三 基于F411 CE的移植编译 最近在学操作系统 RTOS与Linux 对Micropython有些新的认知 回头又复习了一下Micropython 简直要不要这么优秀 希望通过这篇文章能带给大家不一样的Mic
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • C++ freeRTOS任务,非静态成员函数的无效使用

    哪里有问题 void MyClass task void pvParameter while 1 this gt update void MyClass startTask xTaskCreate this gt task Task 204

随机推荐

  • 那些提升效率的tips(不定期更新中...)

    电脑插了网线可以上网却显示无internet 打开设备管理器 xff08 找不到在控制面板中搜索 设备管理器 xff09 找到网络适配器 选择网卡驱动程序 xff0c 先禁用设备再开启设备 xff08 重启 xff09 用MarkDownl
  • cmake的一个编译报错

    在一台新搭建的服务器上执行cmake的时候 xff0c 报了如下错误 xff1a cmake The C compiler identification is unknown The CXX compiler identification
  • 名词解释专用链接

    算法相关 xff1a 主元素 设T 1 n 是一个含有n个元素的数组 当 i T i 61 x gt n 2 xff0c 时称元素x是数组T的主元素 例如 xff0c T 61 1 1 1 2 5 5 1 1 1 1 xff0c T中有10
  • 微服务讲堂--【4】风洞系统

    一 系统特性 风洞是以人工的方式产生并且控制气流 xff0c 用来模拟飞行器周围气体的流动情况 xff0c 并可测量气流对飞行器的作用效果以及观察物理现象的实验设备 这个定义来自百度百科 xff0c 微服务和飞行器压根就搭不上边 xff0c
  • 微服务讲堂--【5】系统自举

    这里的 系统自举 借用了操作系统的概念 在操作系统启动之前 xff0c 计算机要先加载自举程序 xff0c 再由自举程序加载操作系统的启动程序 整个详细过程不在这里描述 xff0c 可以在网络查阅相关资料 为什么要在微服务系统中特别提及系统
  • 微服务讲堂--【6】系统稳定性

    稳定性 xff0c 通常是以可靠性来衡量 xff0c 即我们常说的几个9 xff0c 这个主题在之前各个系列文章中已经提到过 xff0c 本来没有打算单独写一篇 前几天一个老同事在群里发出一个灵魂之问 xff0c 如何解决生产环境更新系统后
  • 状态和无状态--2种服务器架构之间的比较

    对服务器程序来说 xff0c 有两个基本假设十分重要 xff0c 究竟服务器是基于状态请求还是无状态请求 状态化的判断是指两个来自相同发起者的请求在服务器端是否具备上下文关系 如果是状态化请求 xff0c 那么服务器端一般都要保存请求的相关
  • 日志系统设计

    一 重要性 日志系统在整个系统架构中的重要性可以称得上基础的基础 xff0c 但是这一点 xff0c 都容易被大多数人所忽视 因为日志在很多人看来只是printf 在系统运行期间 xff0c 是很难step by step的 xff0c 所
  • 提高链表随机访问效率的一种方案

    一 问题的描述 链表由于各个元素之间是通过指针方式连接在一起 xff0c 所以增加删除都非常方便 xff0c 但是在随机访问却远不如数组 数组的下标是可以通过算法直接定位的 xff0c 但链表却不行 二 问题的方案 我们定义一种组织方式 x
  • 如何识别验证码

    http www jianblog com 2009 02 09 574 周俭 Blog 基于OpenCV的PHP图像人脸识别技术 二月 9 2009 at 10 13 上午 由 catch Filed under PHP 编程 今天无意中
  • 银联基于OpenStack的金融私有云建设实践

    银联基于OpenStack的金融私有云建设实践 摘要 xff1a 中国银联基于OpenStack的私有云已经稳定运行1000多天 xff0c 累计11960vCPU 33280G内存和600TB企业级存储计算力 xff0c 初步建成了包括云
  • PING的最大长度

    我们知道MTU基本上是1492长度 我现在上海电信 xff0c 想测试下PING的包 xff0c 最大允许多大 那么从选择一个域名 xff0c 比如www baidu com 使用ping l size www baidu com 如果si
  • 【Linux】Centos安装OpenGL依赖库

    yum install y mesa yum install y freeglut yum install y GLEW
  • UEFI模式安装Win10和Linux双系统

    最近心血来潮 xff0c 想装一个Linux Windows双系统 xff0c 吸取上次安装的经验 xff0c 这次一定都要使用UEFI模式启动 xff0c 需要注意的是必须是支持此种启动模式的系统 xff08 一般解压之后都有efi文件夹
  • ActiveMQ性能调优

    转自 xff1a http setting iteye com blog 1484498 amq自己带了一个性能test xff1a http activemq apache org activemq performance module
  • 关系型数据库及oracle数据库简介

    一 关系型数据库简介 1 关系模型 xff08 1 xff09 1970年美国IBM公司研究员E F Codd首次提出了数据库系统的关系模型 xff0c 开创了数据库的关系方法和关系数据理论的研究 xff0c 为数据库技术奠定了理论基础 由
  • 游玩Linux(02)- zsh安装配置与游玩

    背景 xff1a 说实话 xff0c bash真有点反人类 xff0c 听说zsh是终极答案 xff0c 于是就搞一搞 xff0c 感觉还不错 参考资料 xff1a Oh My Zsh 安装 amp 配置 zsh 安装与配置 xff1a 9
  • 【转】添加层的方法,sphereFace代码添加层笔记

    转自https blog csdn net cuixing001 article details 79207109 在此基础上 xff0c 加入了自己的理解和修改 本教程是在窗户微软版朱古力环境配置好基础上添加sphereFace的新层Ma
  • putty+xming树莓派远程显示图片/图形界面

    之前通过putty用终端登录树莓派的时候想要查看图片只会用winscp先传输图片文件到本地再查看 后来配置了一下发现可以直接在本地终端调用图形界面远程查看 效果 xff1a 下载安装xming并配置putty xff1a 参考 xff1a
  • STM32F407之基于FreeRTOS的串口数据处理

    串口数据处理比较频繁时 xff0c 不用RTOS处理数据容易丢包 串口数据处理可以用FreeRTOS进行管理 xff0c 用于支持串口的CMD指令收发 除了串口任务的创建 xff0c 定时器创建外 xff0c 单纯串口数据处理需要进行下面几