首先得說(shuō)明一下,在下剛學(xué)FPGA,不知道多模塊怎么來(lái)寫,或是說(shuō)有什么技巧,連小白也算不上,只是參考黑金代碼,以自己的理解,記錄編寫串口接收程序的過(guò)程,還望得到燒友指點(diǎn)。
設(shè)引腳rx_Pin_In是接收上位機(jī)信號(hào)。由圖可見(jiàn),當(dāng)有數(shù)據(jù)的時(shí)候,它會(huì)拉低電平來(lái)提醒一句,“嗨,數(shù)據(jù)到了”。如果此時(shí)設(shè)置好了波特率,就可以開(kāi)始數(shù)據(jù)接收工作。在接收完畢一幀數(shù)據(jù)后,恢復(fù)高電平。我們可對(duì)接收到的數(shù)據(jù)處理,并且可以等待加一個(gè)低電平的到來(lái)在進(jìn)行此操作。現(xiàn)在我想實(shí)現(xiàn)的功能是上位機(jī)發(fā)送數(shù)據(jù),串口接收后發(fā)給led,實(shí)現(xiàn)對(duì)led亮滅的控制。顯然,實(shí)現(xiàn)該功能需要倆個(gè)模塊,一個(gè)是實(shí)現(xiàn)數(shù)據(jù)的接收rx_control_module.v,另一個(gè)是實(shí)現(xiàn)對(duì)led的亮滅控制(led_Control_module.v)。而數(shù)據(jù)接收需要三個(gè)條件:來(lái)了低電平信號(hào),有匹配的波特率,還得對(duì)數(shù)據(jù)接收。所以我們需要三個(gè)模塊完成,一是檢測(cè)信號(hào)(rx_detect_module;)、二是波特率計(jì)數(shù):rx_bps_module;、三是數(shù)據(jù)接收控制:rx_receive_module。接下來(lái),咱就拿出一張紙,畫畫看,串口接收在FPGA當(dāng)中是怎樣工作的。
首先,先把那五個(gè)模塊及引腳rx_Pin_In寫上,接下來(lái)的一切動(dòng)作都是由rx_Pin_In而起的。我們要接收數(shù)據(jù)肯定要先對(duì)信號(hào)(低電平)進(jìn)行檢查,否則,怎么開(kāi)始呢?故先關(guān)注rx_detect_module.v(信號(hào)檢測(cè)模塊),這里要實(shí)現(xiàn)數(shù)據(jù)的電平檢測(cè),并不斷的發(fā)送給數(shù)據(jù)接收模塊。別的不管,先input rx_pin_in;再output L_sig(輸出低電平) ;。這個(gè)模塊的任務(wù)就完成了。
現(xiàn)由L_sig,信號(hào)傳給了數(shù)據(jù)接收控制模塊(rx_receive_module.v)。按理說(shuō)下面就該對(duì)這個(gè)模塊進(jìn)行描述了。畢竟人家都不斷給咱信號(hào)了,咱不能不干活呀。但還真不能干,得設(shè)置波特率呀,沒(méi)有波特率還接收個(gè)毛線。所以走,設(shè)置波特率去,然后跟他要個(gè)信號(hào),就可以工作了,出發(fā)~
“歡迎光臨波特率計(jì)數(shù)模塊(rx_bps_module),在這里您將得到你想要的一切”
“給我個(gè)接收數(shù)據(jù)的信號(hào)就可以了。”
“好,請(qǐng)?zhí)湾X”
“納尼??!!,還要錢?”
“不給我錢(信號(hào)),我憑什么給你呢,想騙吃騙喝啊,滾~~”
出門不能忘了帶錢啊,要不然人家不待見(jiàn)。回去拿錢吧。
(PS:想讓人家工作,得給信號(hào)。起初還真的忘了)
回到數(shù)據(jù)接收控制模塊(rx_receive_module.v),得弄個(gè)output bps_count;(波特率計(jì)數(shù)),相對(duì)應(yīng)的在模塊中reg bps_work;(波特率工作)。走,這回看他還咋不讓俺們進(jìn)。
“歡迎光臨波特率計(jì)數(shù)模塊(rx_bps_module),在這里您將得到你想要的一切”
“給,input bps_count;(波特率計(jì)數(shù))”
“請(qǐng)問(wèn)您要多少的波特率”
“9600吧”
“請(qǐng)告訴我詳細(xì)信息,馬上配置”
“晶振50MHZ,周期的中間取走,output BPS_CLK;(采集數(shù)據(jù)),9600 bps傳輸速度使一位數(shù)據(jù)的周期是1/9600 = 0.000104166667,以50MHZ時(shí)鐘頻率要得到上述的定時(shí)則需計(jì)數(shù)N = 0.000104166667 /(1/50M) = 5208,由于從零開(kāi)始算起則為5207。中間取樣為2604”這時(shí),波特率計(jì)數(shù)模塊(rx_bps_module)先input bps_count;(波特率計(jì)數(shù)),再reg [12:0] BPS_Conut;(計(jì)數(shù)) BPS_Conut=5027時(shí)歸零,等于2604時(shí)讀出即output BPS_CLK;說(shuō)白了,波特率設(shè)置就是個(gè)計(jì)數(shù)器。現(xiàn)在他配置好了,等咱需要的時(shí)候給他個(gè)信號(hào)他就工作,加工,并且給咱帶來(lái)了BPS_CLK,有它,咱可以就收數(shù)據(jù)了。 走,回?cái)?shù)據(jù)接收控制模塊(rx_receive_module.v),在這個(gè)模塊主要就是對(duì)一幀一幀的數(shù)據(jù)度,這里采用case(i)來(lái)讀,首先,i=0的時(shí)候,若~L_sig=1,則bps_work=1;通知波特率計(jì)數(shù)模塊(rx_bps_module)工作,并i+1。i=1時(shí),if(BPS_CLK)i<=i+1,就是起始位了,起始位忽略。在i=2~9時(shí)候是接收數(shù)據(jù)的。所以當(dāng) i=2~9時(shí),只要來(lái)了波特率,咱就開(kāi)始從rx_pin_in接收數(shù)據(jù),就定義個(gè) reg [7:0]rData;吧,接收數(shù)據(jù)。i=10的時(shí)候奇偶校驗(yàn)位,i+1。i=11的時(shí)候,停止位。接收完了,波特率不用計(jì)數(shù)了,咱該收工了吧?不行不行絕對(duì)不行,波特率計(jì)數(shù)模塊(rx_bps_module.v)很靠譜,你不讓他停他一直工作,所以,bps_work=0;您停吧。 好了,接收工作咱干完了,剩下的就是把接收的數(shù)據(jù)發(fā)送給led_Control_module.v模塊,那什么時(shí)候發(fā)呢?當(dāng)然是接收完就發(fā)啊,F(xiàn)PGA這么講效率,拖個(gè)毛線。所以,在i=12的時(shí)候,不僅要讓bps_work停止,還要讓led_Control_module.v接收數(shù)據(jù),故reg led_begin =1,output led_Begin_work;現(xiàn)在告訴這個(gè)模塊要工作了。 但是!工作要干什么? 答:接收數(shù)據(jù) 好!不要忘了帶數(shù)據(jù),故output RX_Data; assign RX_Data = rData; assign led_Begin_work = led_begin; 來(lái)到了led_Control_module.v(led燈控制模塊),因?yàn)閘ed_Begin_work=1;傳輸數(shù)據(jù)。傳輸完了呢?即在i=13的時(shí)候led_begin=0。結(jié)束工作!好了完成了,哈哈。接收數(shù)據(jù)搞定了。
一直在想,人家怎么從無(wú)到有建一個(gè)模塊的,我不知道,現(xiàn)在想先一個(gè)一個(gè)小模塊,再和在一起。先挑個(gè)軟柿子捏。
1、 rx_detect_module.v模塊,input rx_pin_in; output L_sig ;
2、 波特率模塊(rx_bps_module)也比較簡(jiǎn)單,就它吧。 Input bps_count;rx_receive_module模塊來(lái)的計(jì)數(shù)標(biāo)志位 reg [12:0] BPS_Conut;(計(jì)數(shù)) 2^13 = 8 192>5027,BPS_Conut=5027時(shí)歸零,等于2604時(shí)讀出即output BPS_CLK;
rx_receive_module.v模塊感覺(jué)挺復(fù)雜的,信號(hào)多,不好寫,就寫led_Control_module.v模塊吧。因?yàn)樗秃?/font>rx_receive_module.v相關(guān)。 Input led_Begin_work; input RX_Data; Output led; 就差rx_receive_module,想想它怎么寫: Input rx_pin_in(數(shù)據(jù)) L_Sig(低電平) BPS_CLK(波特率計(jì)滿) Output BPS_Conut,(波特率計(jì)數(shù)信號(hào)) led_Begin_work(開(kāi)始信號(hào))RX_Data(傳值)、
還有倆個(gè)模塊,勝利在望啊。 先rx_control_module.v模塊。把那三個(gè)綜合一下,進(jìn)的進(jìn),出的出,模塊之間的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
-
-
-
復(fù)制代碼
|