首先得說明一下,在下剛學FPGA,不知道多模塊怎么來寫,或是說有什么技巧,連小白也算不上,只是參考黑金代碼,以自己的理解,記錄編寫串口接收程序的過程,還望得到燒友指點。
193312ae28f2nf1lpnf8zf.png (125.38 KB, 下載次數: 87)
下載附件
2016-3-3 19:10 上傳
設引腳rx_Pin_In是接收上位機信號。由圖可見,當有數據的時候,它會拉低電平來提醒一句,“嗨,數據到了”。如果此時設置好了波特率,就可以開始數據接收工作。在接收完畢一幀數據后,恢復高電平。我們可對接收到的數據處理,并且可以等待加一個低電平的到來在進行此操作。現在我想實現的功能是上位機發送數據,串口接收后發給led,實現對led亮滅的控制。顯然,實現該功能需要倆個模塊,一個是實現數據的接收rx_control_module.v,另一個是實現對led的亮滅控制(led_Control_module.v)。而數據接收需要三個條件:來了低電平信號,有匹配的波特率,還得對數據接收。所以我們需要三個模塊完成,一是檢測信號(rx_detect_module;)、二是波特率計數:rx_bps_module;、三是數據接收控制:rx_receive_module。接下來,咱就拿出一張紙,畫畫看,串口接收在FPGA當中是怎樣工作的。
首先,先把那五個模塊及引腳rx_Pin_In寫上,接下來的一切動作都是由rx_Pin_In而起的。我們要接收數據肯定要先對信號(低電平)進行檢查,否則,怎么開始呢?故先關注rx_detect_module.v(信號檢測模塊),這里要實現數據的電平檢測,并不斷的發送給數據接收模塊。別的不管,先input rx_pin_in;再output L_sig(輸出低電平) ;。這個模塊的任務就完成了。
現由L_sig,信號傳給了數據接收控制模塊(rx_receive_module.v)。按理說下面就該對這個模塊進行描述了。畢竟人家都不斷給咱信號了,咱不能不干活呀。但還真不能干,得設置波特率呀,沒有波特率還接收個毛線。所以走,設置波特率去,然后跟他要個信號,就可以工作了,出發~
“歡迎光臨波特率計數模塊(rx_bps_module),在這里您將得到你想要的一切”
“給我個接收數據的信號就可以了。”
“好,請掏錢”
“納尼??!!,還要錢?”
“不給我錢(信號),我憑什么給你呢,想騙吃騙喝啊,滾~~”
出門不能忘了帶錢啊,要不然人家不待見。回去拿錢吧。
(PS:想讓人家工作,得給信號。起初還真的忘了)
回到數據接收控制模塊(rx_receive_module.v),得弄個output bps_count;(波特率計數),相對應的在模塊中reg bps_work;(波特率工作)。走,這回看他還咋不讓俺們進。
“歡迎光臨波特率計數模塊(rx_bps_module),在這里您將得到你想要的一切”
“給,input bps_count;(波特率計數)”
“請問您要多少的波特率”
“9600吧”
“請告訴我詳細信息,馬上配置”
“晶振50MHZ,周期的中間取走,output BPS_CLK;(采集數據),9600 bps傳輸速度使一位數據的周期是1/9600 = 0.000104166667,以50MHZ時鐘頻率要得到上述的定時則需計數N = 0.000104166667 /(1/50M) = 5208,由于從零開始算起則為5207。中間取樣為2604”這時,波特率計數模塊(rx_bps_module)先input bps_count;(波特率計數),再reg [12:0] BPS_Conut;(計數) BPS_Conut=5027時歸零,等于2604時讀出即output BPS_CLK;說白了,波特率設置就是個計數器。現在他配置好了,等咱需要的時候給他個信號他就工作,加工,并且給咱帶來了BPS_CLK,有它,咱可以就收數據了。 走,回數據接收控制模塊(rx_receive_module.v),在這個模塊主要就是對一幀一幀的數據度,這里采用case(i)來讀,首先,i=0的時候,若~L_sig=1,則bps_work=1;通知波特率計數模塊(rx_bps_module)工作,并i+1。i=1時,if(BPS_CLK)i<=i+1,就是起始位了,起始位忽略。在i=2~9時候是接收數據的。所以當 i=2~9時,只要來了波特率,咱就開始從rx_pin_in接收數據,就定義個 reg [7:0]rData;吧,接收數據。i=10的時候奇偶校驗位,i+1。i=11的時候,停止位。接收完了,波特率不用計數了,咱該收工了吧?不行不行絕對不行,波特率計數模塊(rx_bps_module.v)很靠譜,你不讓他停他一直工作,所以,bps_work=0;您停吧。 好了,接收工作咱干完了,剩下的就是把接收的數據發送給led_Control_module.v模塊,那什么時候發呢?當然是接收完就發啊,FPGA這么講效率,拖個毛線。所以,在i=12的時候,不僅要讓bps_work停止,還要讓led_Control_module.v接收數據,故reg led_begin =1,output led_Begin_work;現在告訴這個模塊要工作了。 但是!工作要干什么? 答:接收數據 好!不要忘了帶數據,故output RX_Data; assign RX_Data = rData; assign led_Begin_work = led_begin; 來到了led_Control_module.v(led燈控制模塊),因為led_Begin_work=1;傳輸數據。傳輸完了呢?即在i=13的時候led_begin=0。結束工作!好了完成了,哈哈。接收數據搞定了。
201525vyiw231fj31x2rxy.jpg (15.16 KB, 下載次數: 81)
下載附件
2016-3-3 19:10 上傳
一直在想,人家怎么從無到有建一個模塊的,我不知道,現在想先一個一個小模塊,再和在一起。先挑個軟柿子捏。
1、 rx_detect_module.v模塊,input rx_pin_in; output L_sig ;
201711vncns333bnnnsei6.png (17.79 KB, 下載次數: 84)
下載附件
2016-3-3 19:10 上傳
2、 波特率模塊(rx_bps_module)也比較簡單,就它吧。 Input bps_count;rx_receive_module模塊來的計數標志位 reg [12:0] BPS_Conut;(計數) 2^13 = 8 192>5027,BPS_Conut=5027時歸零,等于2604時讀出即output BPS_CLK;
201825okwnmak8w1uz1r88.png (21.08 KB, 下載次數: 100)
下載附件
2016-3-3 19:10 上傳
rx_receive_module.v模塊感覺挺復雜的,信號多,不好寫,就寫led_Control_module.v模塊吧。因為他就和rx_receive_module.v相關。 Input led_Begin_work; input RX_Data; Output led;
202027c5fh9t3xq3ah93kx.png (20.92 KB, 下載次數: 87)
下載附件
2016-3-3 19:10 上傳
就差rx_receive_module,想想它怎么寫: Input rx_pin_in(數據) L_Sig(低電平) BPS_CLK(波特率計滿) Output BPS_Conut,(波特率計數信號) led_Begin_work(開始信號)RX_Data(傳值)、
202124cz8mz7om7csogmop.png (21.38 KB, 下載次數: 86)
下載附件
2016-3-3 19:10 上傳
還有倆個模塊,勝利在望啊。 先rx_control_module.v模塊。把那三個綜合一下,進的進,出的出,模塊之間的wire 就OK啦。
- module rx_receive_module(
- clk,rst_n,
- rx_Pin_In,L_Sig,BPS_CLK,
- BPS_Conut,led_Begin_work,RX_Data
- );
-
- input clk ;
- input rst_n;
- input rx_Pin_In;
- input L_Sig;
- input BPS_CLK;
- output BPS_Conut;
- output led_Begin_work;
- output [7:0] RX_Data;
- reg [3:0] i;
- reg [7:0] data;
- reg bps_Begin;
- reg led_Begin;
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
- i <= 4'd0;
- data <= 8'd0;
- bps_Begin <= 1'b0;
- led_Begin <= 1'b0;
- end
- else
- case(i)
- 4'd0:
- if(!L_Sig)
- begin
- i <= i+1'b1;
- bps_Begin <= 1'b1;
- end
-
- 4'd1:
- if(BPS_CLK)
- i <= i+1'b1;
-
- 4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8,4'd9:
- if(BPS_CLK)
- begin
- i <= i+1'b1;
- data[i-2] <= rx_Pin_In;
- end
-
- 4'd10:
- if(BPS_CLK)
- i = i+1'b1;
-
- 4'd11:
- if(BPS_CLK)
- i= i +1'b1;
-
- 4'd12:
- begin
- i <= i +1'b1;
- bps_Begin <= 1'b0;
- led_Begin <= 1'b1;
- end
-
- 4'd13:
- begin
- i <= 4'd0;
- led_Begin <= 1'b0;
- end
- endcase
-
- assign BPS_Conut = bps_Begin;
- assign led_Begin_work = led_Begin;
- assign RX_Data = data;
-
- endmodule
-
-
-
復制代碼
|