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

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

    关注

    4981

    文章

    18274

    浏览量

    288342
  • 函数
    +关注

    关注

    3

    文章

    3866

    浏览量

    61307
  • 数据包
    +关注

    关注

    0

    文章

    229

    浏览量

    24091
  • 串口数据
    +关注

    关注

    0

    文章

    30

    浏览量

    13795
  • 缓存器
    +关注

    关注

    0

    文章

    63

    浏览量

    11579

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

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

收藏 人收藏

    评论

    相关推荐

    嵌入式软件开发应该掌握哪些知识?

    嵌入式软件开发应该掌握哪些知识? 一、 什么是嵌入式软件嵌入式软件通常是指
    发表于 02-19 11:23

    嵌入式学习步骤

    硬件组件。 (4).开发固件:编写嵌入式系统的固件,这是嵌入式系统的软件部分。固件负责控制硬件并执行特定任务。 (5).调试和测试:在将嵌入式系统部署到实际环境
    发表于 02-02 15:24

    裸机中环形队列与RTOS中消息队列有何区别呢?

    “环形队列”和“消息队列”在嵌入式领域有应用非常广泛,相信有经验的嵌入式软件工程师对它们都不陌生。
    的头像 发表于 01-26 09:38 245次阅读
    裸机中环形<b class='flag-5'>队列</b>与RTOS中消息<b class='flag-5'>队列</b>有何区别呢?

    嵌入式硬件和软件哪个好?

    这类技术都是看经验的,经验越高,那他的身价也相应变高。据统计,65%的电子产品开发企业嵌入式软件开发工程师团队,往往只占全公司人数的5%,但是却创造了全公司超过70%的效益。 嵌入式
    发表于 12-05 15:17

    嵌入式软件的问题分析

    个消息处理完(函数调用返回)时,才会处理另一个消息。参考《嵌入式软件的设计模式(上)》的 第3.3节 “队列模式”。 3.4.2 超时或消息丢失引发的问题一个任务、线程给另一个任务、
    发表于 11-17 09:29

    嵌入式软件设计和单片机软件设计的区别是什么?

    嵌入式软件设计和单片机软件设计目前的应用很多,这两者有什么区别? 嵌入式主要说的什么?结构是啥!
    发表于 11-10 07:46

    什么是嵌入式Linux?

    之有运行程序的能力与作用。在很多智能家电开发,智能产品的研究上有着主导的作用。(对个人、团队开发产品有兴趣的朋友一定要看看嵌入式!) linux的嵌入式系统开发,涵盖了从硬件到软件设计的多个领域,并且
    发表于 10-11 13:47

    从事嵌入式工作有哪些优势?

    随着物联网和人工智能的发展,嵌入式技术越来越值钱,学嵌入式的人也越来越多,现在开始入行嵌入式。根据一些权威部门统计,我国目前嵌入式软件人才缺
    发表于 10-08 15:05

    嵌入式编程和微控制器应用

    对AtmelAVRRISC处理器的介绍,读者会立即进入嵌入式C语言教程之中。在本书中,读者将学习C语言的变量和常量、运算符和表达式、控制语句、指针和数组、存储器类型、预处理指令、实时方法等等。u3000u3000本书第4
    发表于 09-20 07:52

    嵌入式软件好还是硬件好?

    越高,那他的身价也相应变高。据统计,65%的电子产品开发企业嵌入式软件开发工程师团队,往往只占全公司人数的5%,但是却创造了全公司超过70%的效益。 嵌入式
    发表于 09-18 15:31

    嵌入式新手应该怎么学?

    要学哪个了,你要知道,嵌入式也就是软件,硬件,编程这些方面的,最基础的也就是C语言了,那刚开始接触,你就需要先从C语言入手。 1、C语言,关于C语言要知道基本的语法,什么是结构体,什么是共同体,有的
    发表于 09-08 10:22

    嵌入式开发中消息队列的实现

    嵌入式开发中经常会看到消息队列的身影,队列的应用是很广泛的,它可以应用的场景有很多,比如缓存通信消息,暂存执行内容,数据顺序转发等的操作。
    发表于 08-22 11:19 526次阅读
    <b class='flag-5'>嵌入式</b>开发中消息<b class='flag-5'>队列</b>的实现

    嵌入式编程为什么使用qemu?qemu的实际应用

    与分析的效率。 用软件模拟硬件的操作行为,本质上来说和实际的硬件操作区别不大,因为在嵌入式编程,最底层的指令集的行为已经在qemu实现的很好了,硬件模拟方面,qemu也大致能够模拟
    发表于 08-16 06:44

    嵌入式学习路线你知道吗?

    嵌入式学习路线你知道吗? 1打好嵌入式软件编程的基础 这一阶段重点打好嵌入式软件编程的基础,包括学习Linux系统的基本应用,Linux的常
    发表于 06-14 16:00

    嵌入式环形队列和消息队列是如何去实现的?

    嵌入式环形队列和消息队列是实现数据缓存和通信的常见数据结构,广泛应用于嵌入式系统中的通信协议和领域。
    发表于 05-20 14:55 670次阅读