日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UART原理

發(fā)布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UART原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

UART原理

? ? ? ?通用異步收發(fā)傳輸器(Universal Asynchronous Receiver / Transmitter),通常稱作UART,是一種異步收發(fā)傳輸器,是電腦硬件的一部分。將資料由串行通信與并行通信間作傳輸轉(zhuǎn)換,作為并行輸入成為串行輸出的芯片,通常集成于其他通訊接口的連結(jié)上。

1、UART發(fā)送

? ? ? ?數(shù)據(jù)的發(fā)送實際上就是按照幀格式將寄存器中的并行數(shù)據(jù)轉(zhuǎn)為串行數(shù)據(jù),為其加上起始位和停止位,以一定的波特率進(jìn)行傳輸。波特率可以有多種選擇,如9600bits/s,14400bits/s,19200bits/s,38400bits/s等

2、UART接收

? ? ? ?由于傳輸中有可能會產(chǎn)生毛刺,接收端極有可能將毛刺誤認(rèn)為是起始位,所以要對檢測到的下降沿進(jìn)行判別。一般采用如下的方法:取接收端的時鐘頻率是發(fā)送頻率的16倍頻,當(dāng)檢測到一個下降沿后,在接下來的16個周期內(nèi)檢測數(shù)據(jù)線上“0”的個數(shù),若“0”的個數(shù)超過8個或者10(根據(jù)具體情況設(shè)置),則認(rèn)為是起始位到來,否則認(rèn)為起始位沒有到來,繼續(xù)檢測傳輸線,等待起始位。

3、發(fā)送主要代碼

//============================================================================== //開始發(fā)送使能 //============================================================================== reg start_trig_reg1 ;//延遲一拍觸發(fā)信號 reg start_en ;//開始發(fā)送使能信號 always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)start_trig_reg1 <=1'b0;elsestart_trig_reg1 <= i_start_trig ;always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)start_en <= 1'b0 ;else if(!start_trig_reg1&&i_start_trig)//檢測觸發(fā)信號上升沿start_en <= 1'b1 ;elsestart_en <= 1'b0 ;//============================================================================== //波特率計算 //==============================================================================always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)time_cnt <= 10'h0 ;else if(crt_state==IDLE)time_cnt <= 10'b0 ;else if(time_cnt==10'd867) // 波特率率為115200 ,每一位的周期是8.68us=868個周期time_cnt <= 10'b0 ;elsetime_cnt <=time_cnt + 1'b1 ;//=============================================================================== //并串轉(zhuǎn)換,數(shù)據(jù)移位 //=============================================================================== always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)shift_data <= 10'h3ff;else if((time_cnt == 9'h0) && (next_state == SEND_START))shift_data <= {1'b1,i_tx_data[7:0],1'b0}; //time_cnt 每一次為0時,就需要移出一位數(shù)據(jù)到TX線上else if(time_cnt == 9'h0)shift_data <= {1'b1,shift_data[9:1]};elseshift_data <= shift_data;//============================================================================== // 奇偶校驗 //============================================================================== // 奇偶校驗位的產(chǎn)生,parity_cnt 為1 時,數(shù)據(jù)中1的個數(shù)為奇數(shù),該位將在發(fā)送校驗位時 // 發(fā)送出去。計算過程是獨立的,屬于并行的流水線架構(gòu)。 always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)parity_cnt <= 1'h0;else if(crt_state == IDLE)parity_cnt <= 1'h0;else if((time_cnt == 9'd10) && (crt_state == SEND_DATA))parity_cnt <= parity_cnt + shift_data[0];elseparity_cnt = parity_cnt; //=============================================================================== //檢測發(fā)送的位順序,位計數(shù)器 //=============================================================================== always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)bit_cnt <= 4'h0;else if(crt_state != next_state)bit_cnt<= 4'h0 ;else if(time_cnt == 10'd867)bit_cnt<= bit_cnt + 4'h1;elsebit_cnt <=bit_cnt;//------------------------------------------------------------------------------ //發(fā)送控制狀態(tài)機(jī) //------------------------------------------------------------------------------ always @ (posedge i_100m_clk or negedge i_rst_n) beginif(!i_rst_n)crt_state <= IDLE;elsecrt_state <= next_state; endalways @ ( *)case(crt_state)IDLE :if( start_en )next_state = SEND_START;//進(jìn)入發(fā)送起始位elsenext_state = crt_state;SEND_START :if((bit_cnt == 4'h0) && (time_cnt == 10'd867))//發(fā)送狀態(tài)必須保持完整的計數(shù)周期,每一位的時間嚴(yán)格保證next_state = SEND_DATA ;elsenext_state = crt_state; SEND_DATA :if((bit_cnt == 4'h7) && (time_cnt == 10'd867))//發(fā)送8位數(shù)據(jù)next_state = SEND_PARITY;elsenext_state = crt_state;SEND_PARITY :if((bit_cnt == 4'h0) && (time_cnt == 10'd867))//奇偶校驗位next_state = SEND_STOP;elsenext_state = crt_state;SEND_STOP :if((bit_cnt == 4'h0) && (time_cnt == 10'd400))//結(jié)束位的持續(xù)時間不是867個周期next_state = IDLE;elsenext_state = crt_state;default : next_state = IDLE;endcase//========================================================================== //數(shù)據(jù)發(fā)送 //============================================================================ always @ (posedge i_100m_clk or negedge i_rst_n)if(!i_rst_n)o_uart_tx_bit <= 1'b1;else if(crt_state[1] || crt_state[2]) //發(fā)送數(shù)據(jù)位和起始位o_uart_tx_bit <= shift_data[0]; else if(crt_state == SEND_PARITY) //發(fā)送奇偶校驗位o_uart_tx_bit <= parity_cnt; else o_uart_tx_bit <= 1'b1; //============================================================================== //發(fā)送完指示 //==============================================================================always @ (posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n) o_tx_done<= 1'b0 ;else if(crt_state [4]) o_tx_done<= 1'b1 ; elseo_tx_done<= 1'b0 ; endmodule

4、接收主要代碼

// 計時 //=============================================================== // 波特率為115200,每一位串行數(shù)據(jù)持續(xù)的周期數(shù)=1/115200s=8.68us=868*10ns,因此計數(shù)868個周期 reg [9:0] time_cnt ; reg [3:0] bit_cnt ;always@(posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n) time_cnt <= 10'b0 ;else if(crt_state==idle)time_cnt <= 10'b0 ;else if(time_cnt==10'd867) time_cnt <=10'b0 ;elsetime_cnt <=time_cnt+1'b1 ; always@(posedge i_100m_clk or negedge i_rst_n)//位計數(shù)器 if(!i_rst_n) bit_cnt <= 4'b0 ;else if(crt_state==idle)bit_cnt <=4'b0 ;else if(time_cnt==10'd867)bit_cnt <=bit_cnt+1'b1 ;elsebit_cnt <=bit_cnt ;//================================================================ //狀態(tài)機(jī) //================================================================ always@(posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n) crt_state <= idle ;elsecrt_state <=next_state ;always@( * ) begincase(crt_state)idle : if( fall_edge ) next_state = start ;elsenext_state = crt_state ;start: if(bit_cnt==0&&time_cnt==10'd867) //起始位 next_state =data ;elsenext_state = crt_state ;data: if(bit_cnt==4'd9) //八位數(shù)據(jù)位next_state = stop ;elsenext_state =crt_state ; // parity: if(time_cnt==10'd867)next_state = stop ;elsenext_state = crt_state ;stop : if(time_cnt==10'd867)next_state = idle ;elsenext_state =crt_state ; default: next_state = idle ;endcaseend //====================================================================//串并轉(zhuǎn)換,移位輸出//==================================================================== reg [7:0] rx_data_reg1 ;always@(posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n)rx_data_reg1 <= 8'b0 ;else if(crt_state[2]&&time_cnt==10'd435) rx_data_reg1 <= {serial_data_r2,rx_data_reg1[7:1]} ;else rx_data_reg1 <=rx_data_reg1 ;always@(posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n) o_rx_data <=8'b 0 ;else if(bit_cnt==4'd8&&time_cnt==10'd700) o_rx_data <=rx_data_reg1 ;elseo_rx_data <=o_rx_data ; ///=======數(shù)據(jù)輸出指示always@(posedge i_100m_clk or negedge i_rst_n) if(!i_rst_n) o_rx_finish <=1'b0 ;else if(bit_cnt==4'd9&&time_cnt==10'd700) o_rx_finish <=1'b1 ;elseo_rx_finish <=1'b0 ; endmodule

總結(jié)

以上是生活随笔為你收集整理的UART原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。