以下文章來(lái)源于嵌入式客棧 ,作者逸珺。 部分修改, 串口分類(串口是啥)數(shù)據(jù)格式 線上空閑、無(wú)數(shù)據(jù)狀態(tài)為常高電平,故邏輯低定義為起始位。
常見(jiàn)的波特率有哪些呢?如下圖: 注意: 一個(gè)有效字節(jié)的傳輸時(shí)間算法 計(jì)算公式 比如 9600 下,1 位起始位,8 位數(shù)據(jù)位,奇校驗(yàn),1 位停止位,則 校驗(yàn)位有用嗎? 當(dāng)你的傳輸介質(zhì)處于一個(gè)有干擾的場(chǎng)景下,校驗(yàn)位就可以從物理層檢測(cè)出錯(cuò)誤。 理解數(shù)據(jù)編碼方式有啥意義呢? 比如在調(diào)試中你可以利用邏輯分析直接去解析收發(fā)線上的數(shù)據(jù)報(bào)文。 啥是UART?啥是USART?UART 兩邊分別代表兩個(gè)通信的設(shè)備,單從 UART 編程的角度講收發(fā)不需要物理同步握手,想發(fā)就發(fā)。圖中箭頭代表數(shù)據(jù)信息流向。RX 表示接收數(shù)據(jù),TX 表示發(fā)送數(shù)據(jù)。數(shù)據(jù)總是從發(fā)送端傳遞到接收端,這就是為啥 RX 連接 TX,TX 連 RX 的原因。 同步簡(jiǎn)單說(shuō),收發(fā)不可自如,不可以想發(fā)就發(fā),收發(fā)需要利用硬件 IO 口進(jìn)行握手,RTS/CTS 就是用于同步的握手信號(hào):
這個(gè)對(duì)于普通應(yīng)用而言并不常見(jiàn),這里不做詳細(xì)展開(kāi),需要用到的時(shí)候只需要對(duì)應(yīng)收發(fā)時(shí)控制握手信號(hào)即可。 編程策略對(duì)于不同的單片機(jī),其硬件體系各異,寄存器也差異很大,但是從收發(fā)編程策略角度而言,常見(jiàn)有下面三種方式:
查詢發(fā)送/中斷接收模式:這里以偽代碼方式描述一下: /*查詢發(fā)送字節(jié)*/void uart_send_byte( uint8 ch ){ /*如果當(dāng)前串口狀態(tài)寄存器非空閑,則一直等待*/ /*注意while循環(huán)后的分號(hào),表示循環(huán)體為空操作*/ while( !UART_IS_IDLE() ); /*此時(shí)將發(fā)送字節(jié)寫(xiě)入發(fā)送寄存器*/ UART_TX_REG = ch;}/*發(fā)送一個(gè)緩沖區(qū)*/void uart_send_buffer( uint8 *pBuf,uint8 size ){ uint8 i = 0; /* 異常參數(shù)處理*/ if( pBuf == NULL ) return; for( i=0; i<size;i++ ) { send_byte( pBuf[i] ); }} 對(duì)于接收而言,如采用查詢模式則幾乎是沒(méi)有任何應(yīng)用價(jià)值,因?yàn)橥獠繑?shù)據(jù)不知道什么時(shí)候會(huì)到來(lái),所以查詢接收就不描述了,這里描述一下中斷接收。
中斷接收需要考慮的幾個(gè)要點(diǎn):
收發(fā)中斷模式#define FRAME_SIZE (128u)static uint8 tx_buffer[FRAME_SIZE];static uint8 tx_index = 0;static uint8 tx_length = 0;static uint8 rx_buffer[FRAME_SIZE];static uint8 rx_index = 0;static bool rx_frame_done = false;void prepare_frame( uint8 * pBuf, uint8 size ){ /*將待傳的報(bào)文按照協(xié)議封裝*/ /*可能需要處理的事情,比如幀頭、幀尾、校驗(yàn)等*/}bool uart_start_sending( uint8 * pBuf, uint8 size ){ if( pBuf == NULL ) return false; memcpy( tx_buffer,pBuf,size ); tx_index = 0; tx_length = size; /*使能發(fā)送中斷,向發(fā)送寄存器寫(xiě)入一個(gè)字節(jié),進(jìn)入連續(xù)發(fā)送模式*/ ENABLE_TX_INT = 1; UART_TX_REG = tx_buffer[tx_index++];}void uart_tx_isr( void ){ if( tx_index<tx_length ) { UART_TX_REG = tx_buffer[tx_index++]; } else { /*發(fā)送完畢,關(guān)閉發(fā)送中斷*/ DISABLE_TX_INT = 1; }}void uart_rx_isr( void ){ /*處理接收,待接收到完整的幀就設(shè)置幀完成標(biāo)記*/ /*由于應(yīng)用各有不同,這里就無(wú)法描述實(shí)現(xiàn)了*/} 還需要考慮的是,對(duì)于 UART 硬件層面的出錯(cuò)處置,以 STM32 為例,就可能有下面的錯(cuò)誤可能發(fā)生:
另外不同的單片機(jī)其底層硬件實(shí)現(xiàn)差異也不較大,比如有的硬件發(fā)送緩沖是單字節(jié)的緩沖,有的則具有 FIFO,這些在選型編程時(shí)都需要綜合考慮。 DMA 模式DMA 發(fā)送模式而言,大致分這樣幾步:
DMA 接收模式而言,大致分這樣幾步:
|
|
來(lái)自: 啟云_9137 > 《儀器儀表用智能電子電器設(shè)備》