日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式案例Show
[導(dǎo)讀]點(diǎn)擊上方藍(lán)字關(guān)注我哦~ 01 前言 在嵌入式軟件的開發(fā)中,串口是十分常用且基礎(chǔ)的功能。在需要批量發(fā)送數(shù)據(jù)的場(chǎng)合,可以使用while循環(huán)等待發(fā)送完成標(biāo)志位的方式,但是這種方式會(huì)占據(jù)主循環(huán),影響效率。也可以采用dma的方式,但是dma在發(fā)送數(shù)據(jù)時(shí)非常高效,但是

點(diǎn)擊上方藍(lán)字關(guān)注我哦~

01

前言


嵌入式軟件的開發(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 的縮寫,是一種先進(jìn)先出的數(shù)據(jù)緩存器,順序?qū)懭霐?shù)據(jù),順序的讀出數(shù)據(jù),其數(shù)據(jù)地址由內(nèi)部讀寫指針自動(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){  u8 i;  //串口發(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ù),寫一個(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)行解包處理。

/ The End /

本文由【嵌入式案例Show】原創(chuàng)出品,未經(jīng)許可,請(qǐng)勿轉(zhuǎn)載

掃碼關(guān)注我們

看更多嵌入式案例

喜歡本篇內(nèi)容請(qǐng)給我們點(diǎn)個(gè)在看

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉