FPGA基礎學習 簡易串列埠傳送

2021-08-19 16:23:26 字數 4216 閱讀 3375

首先需要了解uart 的通訊協議和傳輸時序

uart通訊首先將接收到的並行資料轉換成序列資料來傳輸。訊息幀起始位為低電平,後面接7或8個資料位(大部分為8個資料位),1個可用的奇偶校驗位(根據資料中1的個數是否為偶數(偶校驗位)還是奇數(奇校驗位)),1個或者多個高位停止位。(傳輸乙個位元組大約需要10個位元位)

接收器發現開始位時知道資料準備傳送,並嘗試與傳送器時鐘頻率同步。如果選擇了奇偶校驗位,可以用來幫助錯誤校驗。在接收過程中,uart從訊息幀中去掉起始位和結束位,對進來的位元組進行奇偶校驗,並將資料位元組從序列轉成並行。

(t為乙個資料位占用的時間,如果波特率為9600,那麼t4=1/9600)

實驗實現,當按鍵key1按下,不斷傳送乙個常數,在串列埠除錯助手上可以檢視。利用狀態機實現

module uart_tx(

input      clk,       //時鐘輸入

input      rst_n,     //復位輸入

input      key,       //乙個按鍵,用於傳送控制,低電平有效

output reg txd        //串列埠傳送管腳

//狀態機狀態定義,空閒位+開始位+8bit資料位+停止位

parameter s_idle  = 4'd0; //空閒狀態

parameter s_start = 4'd1; //傳送1bit起始碼0

parameter s_bit0  = 4'd2; //傳送第一位資料

parameter s_bit1  = 4'd3;

parameter s_bit2  = 4'd4;

parameter s_bit3  = 4'd5;

parameter s_bit4  = 4'd6;

parameter s_bit5  = 4'd7;

parameter s_bit6  = 4'd8;

parameter s_bit7  = 4'd9;

parameter s_stop  = 4'd10;//傳送停止位 1 

reg [3:0] state;    //定義狀態暫存器,11個狀態,2^4=16,足夠

reg[15:0] bit_timer; //用於控制波特率的計數器如果波特率是9600,每個資料位50000000/9600個時鐘週期

wire[7:0] tx_data;   //傳送的固定資料12

assign tx_data = 8'hab;   //此處可以修改傳送的資料

//----------一段式狀態機編寫

always@ (posedge clk or negedge rst_n)

begin

if (!rst_n)

begin

state<=s_idle;

bit_timer<=16'd0;

txd<=1'b1;             //復位傳送管腳為高電平,因為開始為低電平

endelse

begin

case(state)

s_idle:

begin

txd<=1'b1;

bit_timer <= 16'd0;

if(!key)          //如果按鍵按下

state<=s_start;

else 

state<=state;

ends_start:

begin

txd<=1'b0;                //開始狀態

if(bit_timer == 16'd5208)//乙個bit的時間到了,狀態轉換

begin

state <= s_bit0;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <=bit_timer+16'd1;

endend

s_bit1:

begin

txd <= tx_data[1]; //第二位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit2;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit2:

begin

txd <= tx_data[2];   //第三位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit3;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit3:

begin 

txd <= tx_data[3];   //第四位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit4;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit4:

begin 

txd <= tx_data[4];   //第五位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit5;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit5:

begin

txd <= tx_data[5];        //第六位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit6;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit6:

begin

txd <= tx_data[6];         //第七位資料

if(bit_timer == 16'd5208)

begin

state <= s_bit7;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_bit7:

begin

txd <= tx_data[7];//最後一位資料

if(bit_timer == 16'd5208)

begin

state <= s_stop;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

s_stop:

begin

txd <= 1'b1;//停止位為高電平

if(bit_timer == 16'd5208)

begin

state <= s_idle;

bit_timer <= 16'd0;

endelse

begin

state <= state;

bit_timer <= bit_timer + 16'd1;

endend

default:

begin

state <= s_idle;

endendcase

endend

FPGA學習筆記 串列埠傳送模組的設計與驗證

從上圖我們可以看到,串列埠傳送模組一共被定義了5個訊號,其中4個輸入,1個輸出,下面,對這5個訊號進行一一闡述。clk 我想不用多說,哪怕是小白也知道,這是系統時鐘,自然是輸入訊號。rst n 系統復位訊號,自然也是輸入。另外,n表示低電平有效。tx trig 傳送資料開始訊號,只有當這個訊號出現乙...

FPGA學習 基於FPGA的簡易音訊採集系統

本篇部落格記錄乙個小專案的開發 基於fpga的簡易音訊採集系統,專案 是乙個寒假的活動的題目,直接購買了設計好的板卡,專案的基本要求如下 使用的板卡是lattice的ice40up5k,這裡首先記錄一下在lattice的軟體中開發fpga的簡單流程 參考 windows 下 ice40 fpga 開...

FPGA 學習之路 (七) UART串列埠設計

uart使用的是 非同步,序列通訊。序列通訊是指利用一條傳輸線將資料一位位地順序傳送。特點是通訊線路簡單,利用簡單的線纜就可實現通訊,降低成本,適用於遠距離通訊,但傳輸速度慢的應用場合。非同步通訊以乙個字元為傳輸單位,通訊中兩個字元間的時間間隔多少是不固定的,然而在同乙個字元中的兩個相鄰位間的時間間...