00 簡介
和接收部分相反,UART發(fā)送數(shù)據(jù)部分是CPU將需要發(fā)送的數(shù)據(jù)寫到發(fā)送數(shù)據(jù)寄存器(TX_DATA),發(fā)送模塊進(jìn)行數(shù)據(jù)的發(fā)送。由于系統(tǒng)時(shí)鐘速率一般會(huì)比UART發(fā)送數(shù)據(jù)快,所以發(fā)送數(shù)據(jù)將緩存到發(fā)送數(shù)據(jù)FIFO(TX_FIFO)。當(dāng)TX_FIFO非空時(shí),發(fā)送數(shù)據(jù)模塊會(huì)根據(jù)UART傳輸協(xié)議將數(shù)據(jù)發(fā)送出去,直到TX_FIFO為空。
類似的,發(fā)送模塊也涉及到ARM時(shí)鐘和26MHz功能時(shí)鐘。其中 發(fā)送FIFO讀寫邏輯是ARM時(shí)鐘域,發(fā)送數(shù)據(jù)狀態(tài)機(jī)和同步邏輯等是功能時(shí)鐘域 。
01 模塊接口與描述
02 實(shí)現(xiàn)
UART_TX模塊主要由三部分組成: 配置信息同步 、TX_FIFO讀控制部分和 發(fā)送狀態(tài)機(jī) 。
配置信息是reg_if模塊由APB總線配置寄存器產(chǎn)生,功能時(shí)鐘域做兩級(jí)同步處理。(比如校驗(yàn)位使能、奇偶校驗(yàn)控制、停止位使能等)
發(fā)送數(shù)據(jù)FIFO控制部分將FIFO中的數(shù)據(jù)讀出,通過發(fā)送數(shù)據(jù)狀態(tài)機(jī)將數(shù)據(jù)發(fā)送。
發(fā)送狀態(tài)機(jī)是根據(jù)串口協(xié)議劃分,分為IDLE、IRQ、START_BIT、TX_DATA、CHECK_BIT、STOP和DELAY六種狀態(tài)。
配置信息同步
和接收模塊類似,由于配置信息是由APB時(shí)鐘產(chǎn)生,到接收模塊的功能時(shí)鐘域需要做同步處理。配置信息是電平信號(hào),通常不會(huì)像數(shù)據(jù)一樣變化快,所以只需要兩級(jí)同步。
接收狀態(tài)機(jī)
使用典型的三段式狀態(tài)機(jī)設(shè)計(jì),狀態(tài)轉(zhuǎn)移圖如下:
uart發(fā)送狀態(tài)轉(zhuǎn)移圖
IDLE: 發(fā)送狀態(tài)機(jī)的IDLE狀態(tài)會(huì)產(chǎn)生tx_start的發(fā)送請求信號(hào),F(xiàn)IFO讀邏輯部分會(huì)判斷讀空信號(hào)tx_fifo_rempty和tx_start,如果TX_FIFO非空且發(fā)送請求有效,則產(chǎn)生發(fā)送響應(yīng)tx_ack,并發(fā)出FIFO讀使能。IDLE狀態(tài)機(jī)內(nèi)發(fā)現(xiàn)tx_ack有效,跳轉(zhuǎn)到IRQ狀態(tài)。IRQ: IRQ狀態(tài)目的是等待FIFO數(shù)據(jù)讀出。進(jìn)入IRQ后使能波特率時(shí)鐘,tx_start信號(hào)disable,跳轉(zhuǎn)到START_BIT。
START_BIT: 發(fā)送起始位。拉低utxd_o后跳轉(zhuǎn)到發(fā)送數(shù)據(jù)狀態(tài)TX_DATA。
TX_DATA: 發(fā)送從TX_FIFO讀出的8bit數(shù)據(jù),發(fā)送完8bit數(shù)據(jù)后判斷校驗(yàn)位是否使能(check_syn2),使能則進(jìn)入CHECK_BIT,不使能則進(jìn)入STOP狀態(tài)。
CHECK_BIT: 8bit數(shù)據(jù)按位異或(偶校驗(yàn))或同或(奇校驗(yàn)),計(jì)算出校驗(yàn)位發(fā)送,判斷是否使能停止位(stop_bit_syn2),如使能停止位則進(jìn)入STOP狀態(tài),不使能則進(jìn)入DELAY狀態(tài)。
這里提一下 奇偶校驗(yàn) 。
所謂奇校驗(yàn),就是判斷發(fā)送的數(shù)據(jù)位中1的個(gè)數(shù)是否是奇數(shù),如果數(shù)據(jù)位中1的個(gè)數(shù)是偶數(shù),那就給校驗(yàn)位賦值1;如果數(shù)據(jù)位中1的個(gè)數(shù)是奇數(shù),那就給校驗(yàn)位賦值0。目的是確保發(fā)送的數(shù)據(jù)中1的個(gè)數(shù)是奇數(shù)。
偶校驗(yàn)則相反,判斷發(fā)送的數(shù)據(jù)位中1的個(gè)數(shù)是否是偶數(shù),如果數(shù)據(jù)位中1的個(gè)數(shù)是偶數(shù),那就給校驗(yàn)位賦值0;如果數(shù)據(jù)位中1的個(gè)數(shù)是奇數(shù),那就給校驗(yàn)位賦值1。目的是確保發(fā)送的數(shù)據(jù)中1的個(gè)數(shù)是偶數(shù)。
實(shí)現(xiàn)時(shí),奇偶校驗(yàn)可以用同或和異或操作計(jì)算,相同的8bit數(shù)奇偶校驗(yàn)的值一定是相反的。
STOP: STOP狀態(tài)拉高utxd_o,然后進(jìn)入DELAY狀態(tài)。
DELAY: DELAY狀態(tài)控制相鄰兩次發(fā)送之間的間隔,間隔時(shí)間以波特率時(shí)鐘為單位,受CPU控制(配置字two_tx_delay),默認(rèn)delay兩個(gè)波特率時(shí)鐘周期。延時(shí)后回到IDLE狀態(tài)進(jìn)行等待或下一Byte數(shù)據(jù)傳輸。
前兩段狀態(tài)機(jī),狀態(tài)跳轉(zhuǎn):
// state to nextstate with clk in this block.
always@(posedge clk26m ornegedge rst26m_) begin
if(!rst26m_) begin
state <= IDLE;
end
elsebegin
state <= nextstate;
end
end
// nextstate transform
always@(*) begin
case(state)
IDLE: begin
if(tx_ack_delay2) begin
nextstate = IRQ;
end
elsebegin
nextstate = IDLE;
end
end
IRQ: begin
if(tx_bpsclk) begin
nextstate = START_BIT;
end
elsebegin
nextstate = IRQ;
end
end
START_BIT: begin
if(tx_bpsclk) begin
nextstate = TX_DATA;
end
elsebegin
nextstate = START_BIT;
end
end
TX_DATA: begin
// send 8 bit data
if(data_cnt < 4'd8) begin
nextstate = TX_DATA;
end
elsebegin
if(tx_bpsclk) begin
if(check_syn2) begin
nextstate = CHECK_BIT;
end
elsebegin
nextstate = STOP;
end
end
elsebegin
nextstate = TX_DATA;
end
end
end
CHECK_BIT: begin
if(tx_bpsclk) begin
if(stop_bit_syn2) begin
nextstate = STOP;
end
elsebegin
nextstate = DELAY;
end
end
elsebegin
nextstate = CHECK_BIT;
end
end
STOP: begin
if(tx_bpsclk) begin
nextstate = DELAY;
end
elsebegin
nextstate = STOP;
end
end
DELAY: begin
if(baud_cnt < two_tx_delay_syn2) begin
nextstate = DELAY;
end
elsebegin
nextstate = IDLE;
end
end
default: begin
nextstate = IDLE;
end
endcase
end