今天我們開始fpga最初的小工程:如何使用板卡實現簡單的uart通訊。(結尾送原始碼)
這次我們用最白話來講,首先來看uart是什麼。他並不是乙個實際的物體,而是一種協議。就好比兩個人說話,必須要以一種兩個人都能懂的方式來交流,這種方式也就是協議。uart是一種序列傳送協議。一位一位的傳送資料就需要乙個控制傳送節拍的,例如我們在踢正步的時候需要喊「121」,而在我們的fpga設計中這個喊121的不再是教官,而是時鐘。
時鐘訊號就是像這樣的脈衝訊號,我們在時鐘的每個上公升沿時傳送資料,接收時也使用同樣用相同的頻率的時鐘接收,收發就可以解決。在傳送時我們常說波特率,波特率就是一秒鐘傳送多少個資料,也就是波特率就是波特率的頻率。常用的波特率就是9600/115200等。
但是我們如何確定傳送部分開始傳送了呢?我們規定在未傳送時資料位置於高位,當資料開始傳送(資料有效)我們先將資料位拉低,再來接收資料位。這樣接收端就可以檢測下降沿來判斷是否開始傳送。
檢測下降沿可以把資料位打一拍,
然後取(~in1)&in2就可以檢測到了。
基本概念就是這麼多,就下來我們來做設計。首先我們使用的fpga板卡都會有自帶的晶振,也就是系統時鐘,但是我們在做設計的時候需要用的時鐘是和波特率有關,為了得到和波特率有關的時鐘(達到對應時鐘頻率)我們需要分頻,這裡推薦使用pll,但是由於設計很小,對頻率要求不高,門控時鐘分頻也可以。
傳送時如何控制傳送階段呢?這裡我們使用狀態機,狀態轉移:
狀態0:開始階段,檢測下降沿,如果沒檢測到保持0狀態,如果檢測到轉移到1;
狀態1~8:傳送當前位,一次跳轉下一狀態
狀態9:傳送結束訊號,訊號拉高
狀態10:結束,跳轉0狀態
頂層就不寫了,都是例項化
bps_clk模組
`timescale 1ns / 1ps
//// company:
// engineer:
// // create date: 22:39:01 05/02/2017
// design name:
// module name: uart_bps
// project name:
// target devices:
// tool versions:
// description:
//// dependencies:
//// revision:
// revision 0.01 - file created
// additional comments:
////
module uart_bps(
input clk,
input rst_n,
input cnt_start,
output bps_sig
);reg [12:0]cnt_bps;
parameter bps_t = 13'd5207;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_bps <= 13'd0;
else if(cnt_bps == bps_t)
cnt_bps <= 13'd0;
else if(cnt_start)
cnt_bps <= cnt_bps + 1'b1;
else
cnt_bps <= 1'b0;
endassign bps_sig = (cnt_bps == 13'd2604) ? 1'b1 : 1'b0;
endmodule
sentdata模組
UART和波特率
什麼是 uart uart是一種通用序列資料匯流排,用於非同步通訊。該匯流排雙向通訊,可以實現全雙工傳輸和接收。在嵌入式設計中,uart用來與pc進行通訊,包括與監控偵錯程式和其它器件,如eeprom通訊。uart通訊 uart首先將接收到的並行資料轉換成序列資料來傳輸。訊息幀從乙個低位起始位開始,...
UART和波特率
什麼是 uart uart是一種通用序列資料匯流排,用於非同步通訊。該匯流排雙向通訊,可以實現全雙工傳輸和接收。在嵌入式設計中,uart用來與pc進行通訊,包括與監控偵錯程式和其它器件,如eeprom通訊。uart通訊 uart首先將接收到的並行資料轉換成序列資料來傳輸。訊息幀從乙個低位起始位開始,...
波特率 位元率和波特率
最近因為專案在複習通訊原理,對於位元率和波特率概念始終區分不是很明確,網上找了很多教程,找到了我認為最好理解的乙個版本。一,位元 bit 與資訊度量衡 度量衡是乙個名詞,通俗簡單的理解就是某個東西的單位,舉個栗子 1,乙個妹子的重量是100kg,那麼kg就是單位,用來描述物體 妹子 的性質 質量 k...