吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FIFO隊(duì)列的串口數(shù)據(jù)收發(fā)方法

FPGA之家 ? 來(lái)源:FPGA之家 ? 作者:FPGA之家 ? 2022-07-12 09:16 ? 次閱讀

01

前言

嵌入式軟件的開(kāi)發(fā)中,串口是十分常用且基礎(chǔ)的功能。在需要批量發(fā)送數(shù)據(jù)的場(chǎng)合,可以使用while循環(huán)等待發(fā)送完成標(biāo)志位的方式,但是這種方式會(huì)占據(jù)主循環(huán),影響效率。也可以采用dma的方式,但是dma在發(fā)送數(shù)據(jù)時(shí)非常高效,但是批量接收數(shù)據(jù)時(shí),就很不靈活,特別是一些在串口數(shù)據(jù)中解析某種協(xié)議格式時(shí),很不方便。下面介紹一種利用串口中斷結(jié)合FIFO隊(duì)列的串口數(shù)據(jù)收發(fā)方法,結(jié)合了不阻塞批量發(fā)與靈活接收的優(yōu)點(diǎn),特別適用于串口協(xié)議收發(fā)的使用場(chǎng)景。

02

FIFO隊(duì)列

FIFO是英文First In First Out 的縮寫(xiě),是一種先進(jìn)先出的數(shù)據(jù)緩存器,順序?qū)懭霐?shù)據(jù),順序的讀出數(shù)據(jù),其數(shù)據(jù)地址由內(nèi)部讀寫(xiě)指針自動(dòng)加1完成。相比于一個(gè)同等緩存大小的數(shù)值,F(xiàn)IFO就是多管理了一個(gè)先進(jìn)先出的功能,方便串口數(shù)據(jù)的存入和讀出。

Fifo在帶操作系統(tǒng)嵌入式軟件中都有現(xiàn)成的實(shí)現(xiàn),但是在基礎(chǔ)的嵌入軟件中,我們可以自己實(shí)現(xiàn)一個(gè)。

#define UART1_IN_FIFO_SIZE   100 //接收串口隊(duì)列的深度#define UART1_OUT_FIFO_SIZE 250 //發(fā)送串口隊(duì)列的深度
//頭文件函數(shù)列表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接收隊(duì)列緩存數(shù)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接收隊(duì)列void uart1infifo_Clear(void){  uart1infifo_front = UART1_IN_FIFO_SIZE -1;  uart1infifo_rear = uart1infifo_front;//  uart1infifo_count = 0;}//串口1接收隊(duì)列入數(shù)據(jù)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接收隊(duì)列出數(shù)據(jù)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);  }}

為了節(jié)省篇幅,串口1發(fā)送隊(duì)列就不詳細(xì)描述了,在接收隊(duì)列的基礎(chǔ)上稍加修改即可。

03

中斷收發(fā)串口

//串口發(fā)送函數(shù) void SendDataToUart1(u8 * pData, u16 len){  u8i;  //串口發(fā)送隊(duì)列將慢,等待一下數(shù)據(jù)發(fā)送  while(1){  if(uart1outfifo_GetSpace()>len+5)  {        break;      }      else      {        i = 0;      }    }    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);  //關(guān)閉中斷,防止隊(duì)列的進(jìn)出會(huì)同時(shí)進(jìn)行    while (len --)    {          uart1outfifo_DataIn(*pData);      pData ++;    }      USART_ITConfig(USART1, USART_IT_TXE, ENABLE);}
//串口處理函數(shù)void USART1_IRQHandler(void){  if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE))  {    uart1infifo_DataIn(USART_ReceiveData(USART1));//接收數(shù)據(jù)并放入串口接收隊(duì)列  //串口數(shù)據(jù)處理flag  }  else if (USART_GetFlagStatus(USART1, USART_FLAG_TXE))  {    if (uart1outfifo_count > 0)    {      USART_SendData(USART1, uart1outfifo_DataOut());//發(fā)隊(duì)列取出數(shù)據(jù)放入串口發(fā)送寄存器}else {      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);    }  }}

04

串口數(shù)據(jù)處理

不定長(zhǎng)數(shù)據(jù)包超時(shí)處理

在上節(jié)的“串口數(shù)據(jù)處理flag”處,加入超時(shí)的標(biāo)記g_uartTimeOut = n;并在定時(shí)器中斷中倒計(jì)時(shí)g_uartTimeOut,減到0后,產(chǎn)生數(shù)據(jù)包處理標(biāo)志gb_needDealUartPkg = 1。主循環(huán)掃到gb_needDealUartPkg是1后,讀出uart1infifo中的全部數(shù)據(jù)進(jìn)行解包處理。

不定長(zhǎng)數(shù)據(jù)包按內(nèi)容格式處理

?在上節(jié)的“串口數(shù)據(jù)處理flag”處,加入比對(duì)數(shù)據(jù)包格式的函數(shù),當(dāng)格式滿足要求時(shí),將整個(gè)數(shù)據(jù)包存入數(shù)據(jù)包隊(duì)列(參照前面的串口數(shù)據(jù)接收函數(shù),寫(xiě)一個(gè)接收隊(duì)列,接收的數(shù)據(jù)為數(shù)據(jù)包結(jié)構(gòu)體)。主循環(huán)掃描數(shù)據(jù)包隊(duì)列的緩存數(shù),有就去處理。

定長(zhǎng)數(shù)據(jù)包處理

主循環(huán)中掃描uart1infifo_count,當(dāng)達(dá)到定長(zhǎng)后,讀出uart1infifo中的定長(zhǎng)數(shù)據(jù)進(jìn)行解包處理。

原文標(biāo)題:嵌入式軟件中的串口收發(fā)隊(duì)列設(shè)計(jì)方法

文章出處:【微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    6896

    瀏覽量

    123753
  • fifo
    +關(guān)注

    關(guān)注

    3

    文章

    389

    瀏覽量

    43863
  • 串口數(shù)據(jù)
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    13923

原文標(biāo)題:嵌入式軟件中的串口收發(fā)隊(duì)列設(shè)計(jì)方法

文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    JavaWeb消息隊(duì)列使用指南

    用程序的通信方法,允許異步傳輸消息,并且具有存儲(chǔ)和轉(zhuǎn)發(fā)消息的能力。它主要解決以下問(wèn)題: 異步處理 :允許系統(tǒng)組件異步處理任務(wù),提高響應(yīng)速度。 解耦系統(tǒng) :不同系統(tǒng)組件之間通過(guò)消息隊(duì)列通信,降低耦合度。 流量削峰 :在高流量情況下,消息隊(duì)
    的頭像 發(fā)表于 11-25 09:27 ?193次閱讀

    【代碼分享】基于樂(lè)鑫ESP32的串口不定長(zhǎng)數(shù)據(jù)接收方法

    【代碼分享】基于樂(lè)鑫ESP32的串口不定長(zhǎng)數(shù)據(jù)接收方法
    的頭像 發(fā)表于 11-15 01:02 ?813次閱讀
    【代碼分享】基于樂(lè)鑫ESP32的<b class='flag-5'>串口</b>不定長(zhǎng)<b class='flag-5'>數(shù)據(jù)</b>接收<b class='flag-5'>方法</b>

    FIFO Generator的Xilinx官方手冊(cè)

    FIFO作為FPGA崗位求職過(guò)程中最常被問(wèn)到的基礎(chǔ)知識(shí)點(diǎn),也是項(xiàng)目中最常被使用到的IP,其意義是非常重要的。本文基于對(duì)FIFO Generator的Xilinx官方手冊(cè)的閱讀與總結(jié),匯總主要知識(shí)點(diǎn)
    的頭像 發(fā)表于 11-12 10:46 ?713次閱讀
    <b class='flag-5'>FIFO</b> Generator的Xilinx官方手冊(cè)

    tlv320aic3016配置好以后然后打開(kāi)中斷允許,沒(méi)有錄音數(shù)據(jù)的輸入,到隊(duì)列fifo的數(shù)是0嗎?

    配置好以后然后打開(kāi)中斷允許如果沒(méi)有錄音數(shù)據(jù)的輸入,那么到隊(duì)列fifo的數(shù)是0嗎,level的值會(huì)變化嗎?
    發(fā)表于 10-28 07:11

    FIFO的深度應(yīng)該怎么計(jì)算

    FIFO是FPGA/IC設(shè)計(jì)中經(jīng)常使用到的模塊,它經(jīng)常被用在兩個(gè)模塊之間進(jìn)行數(shù)據(jù)的緩存,以避免數(shù)據(jù)在傳輸過(guò)程中丟失。同時(shí)FIFO也經(jīng)常被用在跨時(shí)鐘域處理中。
    的頭像 發(fā)表于 10-25 15:20 ?433次閱讀
    <b class='flag-5'>FIFO</b>的深度應(yīng)該怎么計(jì)算

    嵌入式環(huán)形隊(duì)列與消息隊(duì)列的實(shí)現(xiàn)原理

    嵌入式環(huán)形隊(duì)列,也稱(chēng)為環(huán)形緩沖區(qū)或循環(huán)隊(duì)列,是一種先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu),用于在固定大小的存儲(chǔ)區(qū)域中高效地存儲(chǔ)和訪問(wèn)數(shù)據(jù)。其主要特點(diǎn)
    的頭像 發(fā)表于 09-02 15:29 ?660次閱讀

    玩轉(zhuǎn)RT-Thread之消息隊(duì)列的應(yīng)用

    在嵌入式系統(tǒng)開(kāi)發(fā)中,實(shí)時(shí)處理串口和ADC數(shù)據(jù)是一項(xiàng)重要的任務(wù)。本文將介紹如何在RT-Thread實(shí)時(shí)操作系統(tǒng)中,利用消息隊(duì)列來(lái)同時(shí)處理來(lái)自串口和ADC的
    的頭像 發(fā)表于 07-23 08:11 ?664次閱讀
    玩轉(zhuǎn)RT-Thread之消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用

    EPS32-C3使用USB串口收發(fā)數(shù)據(jù),在發(fā)送長(zhǎng)度為64的數(shù)據(jù)時(shí),上位機(jī)串口工具無(wú)法接收到數(shù)據(jù)怎么解決?

    EPS32-C3 使用USB串口收發(fā)數(shù)據(jù) 結(jié)果發(fā)現(xiàn)使用int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t
    發(fā)表于 06-06 06:12

    同步FIFO和異步FIFO區(qū)別介紹

    1. FIFO簡(jiǎn)介 FIFO是一種先進(jìn)先出數(shù)據(jù)緩存器,它與普通存儲(chǔ)器的區(qū)別是沒(méi)有外部讀寫(xiě)地址線,使用起來(lái)非常簡(jiǎn)單,缺點(diǎn)是只能順序讀寫(xiě),而不能隨機(jī)讀寫(xiě)。 2. 使用場(chǎng)景 數(shù)據(jù)緩沖:也就是
    的頭像 發(fā)表于 06-04 14:27 ?1808次閱讀
    同步<b class='flag-5'>FIFO</b>和異步<b class='flag-5'>FIFO</b>區(qū)別介紹

    STM32串口1同時(shí)收發(fā)數(shù)據(jù)卡在回調(diào)函數(shù)中怎么解決?

    只能正常收發(fā)幾次,卡住后進(jìn)入不了user_main_program 同時(shí)使用了串口2連接esp8266進(jìn)行數(shù)據(jù)收發(fā)
    發(fā)表于 05-29 06:34

    STM32F103VC使用simulation和虛擬串口進(jìn)行串口數(shù)據(jù)收發(fā)時(shí),進(jìn)不了IDLE中斷的原因?

    單片機(jī):STM32F103VC,keil版本:5.18; 在使用simulation和虛擬串口進(jìn)行串口數(shù)據(jù)收發(fā)時(shí),數(shù)據(jù)能夠正常發(fā)送,但是接收
    發(fā)表于 04-26 07:09

    freertos串口接收數(shù)據(jù)后如何發(fā)送給任務(wù)?

    正在學(xué)freertos。串口中斷接收一幀數(shù)據(jù)后,放到數(shù)組里,如何將數(shù)據(jù)發(fā)送給任務(wù)呢? 如果用消息隊(duì)列,是否建立的消息隊(duì)列需要是數(shù)組類(lèi)型的?
    發(fā)表于 04-18 06:36

    串口屏的安裝方式方法

    串口屏的安裝方式方法
    的頭像 發(fā)表于 04-02 16:25 ?1567次閱讀

    STM32G071串口1無(wú)法使用DMA收發(fā)是為什么?

    首先說(shuō)一下過(guò)程,之前在F1,F0上使用DMA串口發(fā)送和接收數(shù)據(jù),開(kāi)啟空閑中斷接收不定長(zhǎng)數(shù)據(jù),都沒(méi)有任何問(wèn)題。后來(lái)用上了G030,使用串口1做的DMA
    發(fā)表于 04-01 07:46

    STM32G491使用串口DMA收發(fā)數(shù)據(jù),一直進(jìn)中斷卡死其他任務(wù)是為什么?

    STM32G491使用串口DMA收發(fā)數(shù)據(jù),一直進(jìn)中斷卡死其他任務(wù),具體原因是出現(xiàn)在哪里?
    發(fā)表于 03-18 07:49
    大发888娱乐场 zb8| 悦榕庄百家乐官网的玩法技巧和规则 | 哪里有百家乐代理| 试玩百家乐代理| 威尼斯人娱乐城上不了| 六十甲子24山吉凶| 超级百家乐2龙虎斗| 大发888最佳状态| 喜来登百家乐的玩法技巧和规则| 名仕百家乐的玩法技巧和规则 | 百家乐有方法赚反水| 百家乐官网赢钱秘籍鹰| 235棋牌游戏| 百家乐官网视频挖坑| 大发888官方授权网| 丰禾娱乐城开户| 合胜娱乐城| 百家乐官网技术交流群| 百家乐官网庄闲作千| 大发888微信公众号2| 娱乐城网址| 战神国际娱乐| tt百家乐官网的玩法技巧和规则| 百家乐官网长t恤 | 百家乐破解仪| 有百家乐官网的游戏平台| 博彩百家乐心得| 娱乐城开户送金| 赌神网百家乐的玩法技巧和规则 | 澳门档百家乐官网的玩法技巧和规则 | 哪家百家乐优惠最好且信誉不错| 大发888网页多少| 百家乐官网好多假网站| 百家乐官网有无规律可循| 百家乐官网破解仪恒达| 澳门档百家乐官网的玩法技巧和规则 | 澳门百家乐官网战法| 百家乐官网高手论| 太阳城ktv| 迪威百家乐现场| 大发888官方下载删除|