0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分享关于嵌入式软件中的串口收发队列设计方法

FPGA之家 来源:嵌入式案例Show 作者:嵌入式案例Show 2021-05-08 09:11 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

01前言

嵌入式软件的开发中,串口是十分常用且基础的功能。在需要批量发送数据的场合,可以使用while循环等待发送完成标志位的方式,但是这种方式会占据主循环,影响效率。也可以采用dma的方式,但是dma在发送数据时非常高效,但是批量接收数据时,就很不灵活,特别是一些在串口数据中解析某种协议格式时,很不方便。下面介绍一种利用串口中断结合FIFO队列的串口数据收发方法,结合了不阻塞批量发与灵活接收的优点,特别适用于串口协议收发的使用场景。

02FIFO队列

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成。相比于一个同等缓存大小的数值,FIFO就是多管理了一个先进先出的功能,方便串口数据的存入和读出。

Fifo在带操作系统嵌入式软件中都有现成的实现,但是在基础的嵌入软件中,我们可以自己实现一个。

#define UART1_IN_FIFO_SIZE 100 //接收串口队列的深度#define UART1_OUT_FIFO_SIZE 250 //发送串口队列的深度

//头文件函数列表FIFO_EXT u8 uart1infifo_data[UART1_IN_FIFO_SIZE];#define uart1infifo_count (uart1infifo_GetCount())FIFO_EXT u16 uart1infifo_front;FIFO_EXT u16 uart1infifo_rear;FIFO_EXT void uart1infifo_Clear(void);FIFO_EXT void uart1infifo_DataIn(u8 d);FIFO_EXT u8 uart1infifo_DataOut(void);FIFO_EXT u16 uart1infifo_GetSpace(void);FIFO_EXT u16 uart1infifo_GetCount(void);

//获取串口1接收队列缓存数u16 uart1infifo_GetCount(void){ u16 countR,countF; countR = uart1infifo_rear; countF = uart1infifo_front; if (countR 》= countF) { return(countR - countF); } else { return(UART1_IN_FIFO_SIZE + countR - countF); }}//清空串口1接收队列void uart1infifo_Clear(void){ uart1infifo_front = UART1_IN_FIFO_SIZE -1; uart1infifo_rear = uart1infifo_front;// uart1infifo_count = 0;}//串口1接收队列入数据void uart1infifo_DataIn(u8 d){ if (uart1infifo_count 《 UART1_IN_FIFO_SIZE) { uart1infifo_rear = (uart1infifo_rear +1) % UART1_IN_FIFO_SIZE; uart1infifo_data[uart1infifo_rear] = d; }}//串口1接收队列出数据u8 uart1infifo_DataOut(void){ if (uart1infifo_rear != uart1infifo_front) { uart1infifo_front = (uart1infifo_front +1) % UART1_IN_FIFO_SIZE; return(uart1infifo_data[uart1infifo_front]); } else { return(0xff); }}

为了节省篇幅,串口1发送队列就不详细描述了,在接收队列的基础上稍加修改即可。

03中断收发串口

//串口发送函数 void SendDataToUart1(u8 * pData, u16 len){ u8 i; //串口发送队列将慢,等待一下数据发送 while (1) { if (uart1outfifo_GetSpace() 》 len+5) { break; } else { i = 0; } } USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //关闭中断,防止队列的进出会同时进行 while (len --) { uart1outfifo_DataIn(*pData); pData ++; } USART_ITConfig(USART1, USART_IT_TXE, ENABLE);}

//串口处理函数void USART1_IRQHandler(void){ if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) { uart1infifo_DataIn(USART_ReceiveData(USART1));//接收数据并放入串口接收队列 //串口数据处理flag } else if (USART_GetFlagStatus(USART1, USART_FLAG_TXE)) { if (uart1outfifo_count 》 0) { USART_SendData(USART1, uart1outfifo_DataOut());//发队列取出数据放入串口发送寄存器 } else { USART_ITConfig(USART1, USART_IT_TXE, DISABLE); } }}

04串口数据处理

不定长数据包超时处理

在上节的“串口数据处理flag”处,加入超时的标记g_uartTimeOut = n;并在定时器中断中倒计时g_uartTimeOut,减到0后,产生数据包处理标志gb_needDealUartPkg = 1。主循环扫到gb_needDealUartPkg是1后,读出uart1infifo中的全部数据进行解包处理。

不定长数据包按内容格式处理

在上节的“串口数据处理flag”处,加入比对数据包格式的函数,当格式满足要求时,将整个数据包存入数据包队列(参照前面的串口数据接收函数,写一个接收队列,接收的数据为数据包结构体)。主循环扫描数据包队列的缓存数,有就去处理。

定长数据包处理

主循环中扫描uart1infifo_count,当达到定长后,读出uart1infifo中的定长数据进行解包处理。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5213

    文章

    20855

    浏览量

    339570
  • 函数
    +关注

    关注

    3

    文章

    4424

    浏览量

    68208
  • 数据包
    +关注

    关注

    0

    文章

    270

    浏览量

    25720
  • 串口数据
    +关注

    关注

    1

    文章

    35

    浏览量

    14318
  • 缓存器
    +关注

    关注

    0

    文章

    63

    浏览量

    12116

原文标题:嵌入式软件中的串口收发队列设计方法

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    2025嵌入式开发教程|远航哥

    https://www.bilibili.com/opus/1178756596191199237 嵌入式通信协议三剑客:串口、I2C与SPI的深度解析 在嵌入式系统开发,通信协议是
    的头像 发表于 03-20 17:35 1572次阅读
    2025<b class='flag-5'>嵌入式</b>开发教程|远航哥

    什么是嵌入式应用开发?

    设计、实现和部署,还包括硬件选择、软件设计、测试、集成和维护等流程‌。 定义和背景 嵌入式应用开发是指将软件部署到嵌入式系统,这些系统
    发表于 01-12 16:13

    嵌入式软件测试找bug的常见方法和秘诀

    嵌入式软件开发过程中,一般来说,花在测试比花在编码的时间要多很多,通常为3:1(甚至更多)。这个比例随着你的编程和测试水平的提高而不断下降,但不论怎样,软件测试对一般人来讲很重要。 很多年前,一位
    发表于 01-12 07:07

    软件到硬件的转场:一场由OceanOS-CM0启发的嵌入式思考

    软件开发者而言,这种理解方式尤为重要。我们在多线程编程早已熟悉这些概念,现在需要做的,只是理解它们在资源受限的嵌入式环境下的具体实现和约束。 2. ****互斥锁与临界区的深层思考 第八章
    发表于 01-04 15:52

    C语言单元测试在嵌入式软件开发的作用及专业工具的应用

    方面: ‌早期缺陷发现****‌:单元测试可以在开发早期发现代码的逻辑错误和边界条件问题,降低后期修复成本 ‌硬件交互验证****‌:嵌入式软件通常需要直接与硬件交互,单元测试可以验证底层驱动和硬件
    发表于 12-18 11:46

    一个面向单片机、事件驱动的嵌入式开发平台介绍

    要求较高的嵌入式场景。 EventOS主张的编程思想 1、事件驱动与事件总线 事件驱动和事件总线,是EventOS的核心,也是EventOS的核心。事件机制,与RTOS事件概念完全不同,它更像
    发表于 12-05 06:26

    分享一个嵌入式开发学习路线

    法,这些语法在嵌入式开发至关重要。 2. 技能进阶期(2-3个月) 从51单片机过渡到主流的ARM Cortex-M系列(嵌入式就业核心平台),学会使用STM32单片机,掌握嵌入式
    发表于 12-04 11:01

    CW32嵌入式软件开发的必备知识

    设计的原则和方法,能够设计出高效、可维护的软件系统。 了解嵌入式系统的实时性要求,能够设计出满足实时性要求的软件系统。 8、 测试与验证 掌握单元测试、集成测试和系统测试的
    发表于 11-28 07:48

    C语言在嵌入式开发的应用

    C 语言在汽车电子控制系统开发的主导地位。 2、设备驱动程序 设备驱动程序是嵌入式系统连接硬件和软件的桥梁,它负责实现嵌入式系统与
    发表于 11-21 08:09

    基于环形队列的UART收发回显实验

    问题。在本实验,我们使用环形队列来实现实验1的串口收发回显,将串口接收到的数据暂存在队列
    的头像 发表于 10-27 13:51 2293次阅读
    基于环形<b class='flag-5'>队列</b>的UART<b class='flag-5'>收发</b>回显实验

    RT-Thread 2025嵌入式软件大赛重磅来袭

    为激发开发者潜能、促进技术交流,RT-Thread 正式启动2025年度嵌入式软件大赛! 本赛道为嵌入式软件大赛,聚焦嵌入式
    的头像 发表于 09-22 16:40 3879次阅读
    RT-Thread 2025<b class='flag-5'>嵌入式</b><b class='flag-5'>软件</b>大赛重磅来袭

    RT-Thread 2025嵌入式软件大赛重磅来袭

    为激发开发者潜能、促进技术交流,RT-Thread正式启动2025年度嵌入式软件大赛!本赛道为嵌入式软件大赛,聚焦嵌入式
    的头像 发表于 09-20 10:06 2109次阅读
    RT-Thread 2025<b class='flag-5'>嵌入式</b><b class='flag-5'>软件</b>大赛重磅来袭

    新一代嵌入式开发平台 AMD嵌入式软件和工具2025.1版现已推出

    AMD 2025.1 版嵌入式软件和工具是面向新一代嵌入式系统开发而打造的综合平台,全面加速概念构想到部署落地。 2025.1 版嵌入式软件
    的头像 发表于 08-20 09:15 4396次阅读

    AMD 2025.1版嵌入式软件和工具的新增功能

    AMD 2025.1 版嵌入式软件和工具是面向新一代嵌入式系统开发而打造的综合平台,全面加速概念构想到部署落地。
    的头像 发表于 08-15 15:32 1572次阅读

    嵌入式软件开发常用的软件有哪些?

    对于初学嵌入式的朋友们,会想要了解嵌入式软件开发常用的软件有些,有什么用。那么看以下常用的软件介绍。 1.Visual Studio Cod
    发表于 07-03 17:06