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连接机智云程序源码
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • FreeRTOS系列

    本文主要介绍如何在任务或中断中向队列发送消息或者从队列中接收消息 使用STM32CubeMX将FreeRTOS移植到工程中 创建两个任务以及两个消息队列 并开启两个中断 两个任务 Keyscan Task 读取按键的键值 并将键值发送到队列
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • freertos---软定时器

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

    转自 http bbs armfly com read php tid 7140 1 在FreeRTOS的demo文件夹中拷贝对应的FreeRTOSConfig h文件后 需要加入一行 define configUSE MUTEXES 1
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • MS5607使用中的问题,温度低于20℃,数值不对

    MS5607使用中的问题 温度低于20 马后炮 因为是网上找的代码 懒得看手册 导致后面低于20摄氏度还会有问题 只好认真的看了手册 发现我的代码是ms5611的 照着手册重新改写后就木有问题了 不能省的地方就别省了 公司使用MS5607设
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • 单片机串口实现字符串命令解析---使用函数指针(类似哈希表)

    通常情况下串口通信用的大多数都是用十六进制数据来传输指令 比如最常见的modbus的通信 如读保持寄存器指令 01 03 00 00 00 01 84 0A 这种十六进制的指令在这里就不讨论了 想要详细了解可以看往期的文章 串口相关文章链接
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • FreeRTOS笔记(二)

    FreeRTOS笔记 二 静态任务 文章目录 FreeRTOS笔记 二 静态任务 一 任务定义 二 任务创建 2 1 定义任务栈 2 2 定义任务函数 2 3 定义任务控制块 2 4 实现任务创建函数 三 实现就绪列表 3 1 定义就绪列表
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥

随机推荐

  • 那些提升效率的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 单纯串口数据处理需要进行下面几