生活随笔
收集整理的這篇文章主要介紹了
40_ZYNQ7020开发板RS485协议通信
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
工業(yè)控制現(xiàn)場
很多智能儀表都具備RS-232和RS-485兩種通信接口類型。
RS-232是美國1969年公布的通信協(xié)議,也是工業(yè)控制中應(yīng)用最廣泛的一種串行接口,采取不平衡傳輸方式。
缺點:傳輸距離短,最大約30米,傳輸速率低,最高20kb/s,共模能力差,抗干擾能力弱,所以RS232只適合本地設(shè)備之間的通信。
RS-485是彌補RS232通信距離短,傳輸速率低等不足之處,于1983年提出一種串行數(shù)據(jù)接口標(biāo)準(zhǔn),RS485采用差分傳輸方式,也叫平衡傳輸,有較高的噪音抑制能力,最大傳輸距離約1200米,最大傳輸速率10Mb/s增加了雙向通信能力,所以RS485是首選的串行接口。
網(wǎng)絡(luò)通信協(xié)議
主機(jī)和從機(jī)之間搭建的是RS-485網(wǎng)絡(luò),硬件是采用RS-485接線,主機(jī)呼叫從機(jī)地址,從機(jī)應(yīng)答方式通訊。
數(shù)據(jù)幀10位,1位起始位,8個數(shù)據(jù)位,1個停止位,無效驗。波特率:9600;19200;38400。
RS485可以聯(lián)網(wǎng)構(gòu)成分布式,最多并聯(lián)32臺驅(qū)動器和32臺接收器。
RS485設(shè)備網(wǎng)想要互相通信,只有通過主設(shè)備(PC)中轉(zhuǎn)才能實現(xiàn),設(shè)備網(wǎng)只容許有一個主設(shè)備,其余都是從設(shè)備。
RS485電壓范圍-7~+12V
邏輯“1”,—2v-6v
邏輯“0”,—(-2v)-(-6v)
(1)通過RS232/RS485轉(zhuǎn)換電路將PC機(jī)串口RS232信號轉(zhuǎn)換成RS485信號,對于情況比較復(fù)雜的工業(yè)環(huán)境最好是選用防浪涌帶隔離珊的產(chǎn)品。(2)通過PCI多串口卡,可以直接選用輸出信號為RS485類型的擴(kuò)展卡。
頭文件:uart_tx_top.v
module
uart_tx_top(Clk
, Rst_n
, Rs232_Tx
, Rs232_Rx
, Rs232_Ren
,key_in0
, led
);input Clk
;input Rst_n
;input key_in0
;output Rs232_Tx
;input Rs232_Rx
;output Rs232_Ren
;output led
;wire send_en
;wire
[7:0]data_byte
;wire
[7:0]data_rx
;wire key_flag0
;wire key_state0
;wire
[2:0]baud_set
;wire uart_state
;assign led
= uart_state
;assign send_en
= key_flag0
& !key_state0
;assign Rs232_Ren
= uart_state
;assign data_byte
= 8'b1010_1111
;assign baud_set
= 3'd4
; uart_byte_tx
uart_byte_tx(.Clk(Clk
),.Rst_n(Rst_n
),.data_byte(data_byte
),.send_en(send_en
),.baud_set(baud_set
),.Rs232_Tx(Rs232_Tx
),.Tx_Done(),.uart_state(uart_state
));key_filter
key_filter0(.Clk(Clk
),.Rst_n(Rst_n
),.key_in(key_in0
),.key_flag(key_flag0
),.key_state(key_state0
));uart_byte_rx
uart_byte_rx(.Clk(Clk
),.Rst_n(Rst_n
),.baud_set(baud_set
),.Rs232_Rx(Rs232_Rx
),.data_byte(data_rx
),.Rx_Done(Rx_Done
));endmodule
按鍵模塊
key_filter.v
module
key_filter(Clk
, Rst_n
, key_in
, key_flag
, key_state
);input Clk
;input Rst_n
;input key_in
;output reg key_flag
;output reg key_state
;localparamIDEL
= 4'b0001
,FILTER0
= 4'b0010
,DOWN
= 4'b0100
,FILTER1
= 4'b1000
;reg
[3:0]state
;reg
[19:0]cnt
;reg en_cnt
; reg key_in_sa
,key_in_sb
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)beginkey_in_sa
<= 1'b0
;key_in_sb
<= 1'b0
;end
else beginkey_in_sa
<= key_in
;key_in_sb
<= key_in_sa
; endreg key_tmpa
,key_tmpb
;wire pedge
,nedge
;reg cnt_full
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)beginkey_tmpa
<= 1'b0
;key_tmpb
<= 1'b0
;end
else beginkey_tmpa
<= key_in_sb
;key_tmpb
<= key_tmpa
; endassign nedge
= !key_tmpa
& key_tmpb
;assign pedge
= key_tmpa
& (!key_tmpb
);always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)beginen_cnt
<= 1'b0
;state
<= IDEL
;key_flag
<= 1'b0
;key_state
<= 1'b1
;end
else begin
case(state
)IDEL
:beginkey_flag
<= 1'b0
;if(nedge
)beginstate
<= FILTER0
;en_cnt
<= 1'b1
;end
elsestate
<= IDEL
;endFILTER0
:if(cnt_full
)beginkey_flag
<= 1'b1
;key_state
<= 1'b0
;en_cnt
<= 1'b0
;state
<= DOWN
;end
else if(pedge
)beginstate
<= IDEL
;en_cnt
<= 1'b0
;end
elsestate
<= FILTER0
;DOWN
:beginkey_flag
<= 1'b0
;if(pedge
)beginstate
<= FILTER1
;en_cnt
<= 1'b1
;end
elsestate
<= DOWN
;endFILTER1
:if(cnt_full
)beginkey_flag
<= 1'b1
;key_state
<= 1'b1
;state
<= IDEL
;end
else if(nedge
)beginen_cnt
<= 1'b0
;state
<= DOWN
;end
elsestate
<= FILTER1
;default:begin state
<= IDEL
; en_cnt
<= 1'b0
; key_flag
<= 1'b0
;key_state
<= 1'b1
;endendcase endalways@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)cnt
<= 20'd0
;else if(en_cnt
)cnt
<= cnt
+ 1'b1
;elsecnt
<= 20'd0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)cnt_full
<= 1'b0
;else if(cnt
== 999_999
)cnt_full
<= 1'b1
;elsecnt_full
<= 1'b0
; endmodule
單字節(jié)接收模塊
uart_byte_rx.v
module
uart_byte_rx(Clk
, Rst_n
, baud_set
, Rs232_Rx
, data_byte
, Rx_Done
);input Clk
;input Rst_n
;input
[2:0]baud_set
;input Rs232_Rx
;output reg
[7:0]data_byte
;output reg Rx_Done
;reg s0_Rs232_Rx
,s1_Rs232_Rx
;reg tmp0_Rs232_Rx
,tmp1_Rs232_Rx
;reg
[15:0]bps_DR
;reg
[15:0]div_cnt
;reg bps_clk
;reg
[7:0]bps_cnt
;reg uart_state
;reg
[2:0] r_data_byte
[7:0];reg
[2:0] START_BIT
,STOP_BIT
;wire nedege
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)begins0_Rs232_Rx
<= 1'b0
;s1_Rs232_Rx
<= 1'b0
; end
else begins0_Rs232_Rx
<= Rs232_Rx
;s1_Rs232_Rx
<= s0_Rs232_Rx
; endalways@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)begintmp0_Rs232_Rx
<= 1'b0
;tmp1_Rs232_Rx
<= 1'b0
; end
else begintmp0_Rs232_Rx
<= s1_Rs232_Rx
;tmp1_Rs232_Rx
<= tmp0_Rs232_Rx
; endassign nedege
= !tmp0_Rs232_Rx
& tmp1_Rs232_Rx
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)bps_DR
<= 16'd324
;else begin
case(baud_set
)0:bps_DR
<= 16'd324
;1:bps_DR
<= 16'd162
;2:bps_DR
<= 16'd80
;3:bps_DR
<= 16'd53
;4:bps_DR
<= 16'd26
;default:bps_DR
<= 16'd324
; endcaseendalways@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)div_cnt
<= 16'd0
;else if(uart_state
)begin
if(div_cnt
== bps_DR
)div_cnt
<= 16'd0
;elsediv_cnt
<= div_cnt
+ 1'b1
;end
elsediv_cnt
<= 16'd0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)bps_clk
<= 1'b0
;else if(div_cnt
== 16'd1
)bps_clk
<= 1'b1
;elsebps_clk
<= 1'b0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
) bps_cnt
<= 8'd0
;else if(bps_cnt
== 8'd159 | (bps_cnt == 8'd12
&& (START_BIT
> 2)))bps_cnt
<= 8'd0
;else if(bps_clk
)bps_cnt
<= bps_cnt
+ 1'b1
;elsebps_cnt
<= bps_cnt
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)Rx_Done
<= 1'b0
;else if(bps_cnt
== 8'd159
)Rx_Done
<= 1'b1
;elseRx_Done
<= 1'b0
;
always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)data_byte
<= 8'd0
;else if(bps_cnt
== 8'd159
)begindata_byte
[0] <= r_data_byte
[0][2];data_byte
[1] <= r_data_byte
[1][2];data_byte
[2] <= r_data_byte
[2][2];data_byte
[3] <= r_data_byte
[3][2];data_byte
[4] <= r_data_byte
[4][2];data_byte
[5] <= r_data_byte
[5][2];data_byte
[6] <= r_data_byte
[6][2];data_byte
[7] <= r_data_byte
[7][2];end always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)beginSTART_BIT
= 3'd0
;r_data_byte
[0] <= 3'd0
;r_data_byte
[1] <= 3'd0
;r_data_byte
[2] <= 3'd0
;r_data_byte
[3] <= 3'd0
;r_data_byte
[4] <= 3'd0
;r_data_byte
[5] <= 3'd0
;r_data_byte
[6] <= 3'd0
;r_data_byte
[7] <= 3'd0
;STOP_BIT
= 3'd0
;end
else if(bps_clk
)begin
case(bps_cnt
)0:beginSTART_BIT
= 3'd0
;r_data_byte
[0] <= 3'd0
;r_data_byte
[1] <= 3'd0
;r_data_byte
[2] <= 3'd0
;r_data_byte
[3] <= 3'd0
;r_data_byte
[4] <= 3'd0
;r_data_byte
[5] <= 3'd0
;r_data_byte
[6] <= 3'd0
;r_data_byte
[7] <= 3'd0
;STOP_BIT
= 3'd0
; end
6,7,8,9,10,11:START_BIT
<= START_BIT
+ s1_Rs232_Rx
;22,23,24,25,26,27:r_data_byte
[0] <= r_data_byte
[0] + s1_Rs232_Rx
;38,39,40,41,42,43:r_data_byte
[1] <= r_data_byte
[1] + s1_Rs232_Rx
;54,55,56,57,58,59:r_data_byte
[2] <= r_data_byte
[2] + s1_Rs232_Rx
;70,71,72,73,74,75:r_data_byte
[3] <= r_data_byte
[3] + s1_Rs232_Rx
;86,87,88,89,90,91:r_data_byte
[4] <= r_data_byte
[4] + s1_Rs232_Rx
;102,103,104,105,106,107:r_data_byte
[5] <= r_data_byte
[5] + s1_Rs232_Rx
;118,119,120,121,122,123:r_data_byte
[6] <= r_data_byte
[6] + s1_Rs232_Rx
;134,135,136,137,138,139:r_data_byte
[7] <= r_data_byte
[7] + s1_Rs232_Rx
;150,151,152,153,154,155:STOP_BIT
<= STOP_BIT
+ s1_Rs232_Rx
;default:beginSTART_BIT
= START_BIT
;r_data_byte
[0] <= r_data_byte
[0];r_data_byte
[1] <= r_data_byte
[1];r_data_byte
[2] <= r_data_byte
[2];r_data_byte
[3] <= r_data_byte
[3];r_data_byte
[4] <= r_data_byte
[4];r_data_byte
[5] <= r_data_byte
[5];r_data_byte
[6] <= r_data_byte
[6];r_data_byte
[7] <= r_data_byte
[7];STOP_BIT
= STOP_BIT
; endendcaseendalways@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)uart_state
<= 1'b0
;else if(nedege
)uart_state
<= 1'b1
;else if(Rx_Done
|| (bps_cnt
== 8'd12
&& (START_BIT
> 2)))uart_state
<= 1'b0
;elseuart_state
<= uart_state
; endmodule
單字節(jié)發(fā)送模塊
uart_byte_tx.v
module
uart_byte_tx(Clk
, Rst_n
, data_byte
, send_en
, baud_set
, Rs232_Tx
, Tx_Done
, uart_state
);input Clk
;input Rst_n
;input
[7:0]data_byte
;input send_en
;input
[2:0]baud_set
;output reg Rs232_Tx
;output reg Tx_Done
;output reg uart_state
;reg bps_clk
; reg
[15:0]div_cnt
;reg
[15:0]bps_DR
;reg
[3:0]bps_cnt
;reg
[7:0]r_data_byte
;localparam START_BIT
= 1'b0
;localparam STOP_BIT
= 1'b1
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)uart_state
<= 1'b0
;else if(send_en
)uart_state
<= 1'b1
;else if(bps_cnt
== 4'd11
)uart_state
<= 1'b0
;elseuart_state
<= uart_state
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)r_data_byte
<= 8'd0
;else if(send_en
)r_data_byte
<= data_byte
;elser_data_byte
<= r_data_byte
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)bps_DR
<= 16'd5207
;else begin
case(baud_set
)0:bps_DR
<= 16'd5207
;1:bps_DR
<= 16'd2603
;2:bps_DR
<= 16'd1301
;3:bps_DR
<= 16'd867
;4:bps_DR
<= 16'd433
;default:bps_DR
<= 16'd5207
; endcaseend always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)div_cnt
<= 16'd0
;else if(uart_state
)begin
if(div_cnt
== bps_DR
)div_cnt
<= 16'd0
;elsediv_cnt
<= div_cnt
+ 1'b1
;end
elsediv_cnt
<= 16'd0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)bps_clk
<= 1'b0
;else if(div_cnt
== 16'd1
)bps_clk
<= 1'b1
;elsebps_clk
<= 1'b0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
) bps_cnt
<= 4'd0
;else if(bps_cnt
== 4'd11
)bps_cnt
<= 4'd0
;else if(bps_clk
)bps_cnt
<= bps_cnt
+ 1'b1
;elsebps_cnt
<= bps_cnt
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)Tx_Done
<= 1'b0
;else if(bps_cnt
== 4'd11
)Tx_Done
<= 1'b1
;elseTx_Done
<= 1'b0
;always@
(posedge Clk or negedge Rst_n
)if(!Rst_n
)Rs232_Tx
<= 1'b1
;else begin
case(bps_cnt
)0:Rs232_Tx
<= 1'b1
;1:Rs232_Tx
<= START_BIT
;2:Rs232_Tx
<= r_data_byte
[0];3:Rs232_Tx
<= r_data_byte
[1];4:Rs232_Tx
<= r_data_byte
[2];5:Rs232_Tx
<= r_data_byte
[3];6:Rs232_Tx
<= r_data_byte
[4];7:Rs232_Tx
<= r_data_byte
[5];8:Rs232_Tx
<= r_data_byte
[6];9:Rs232_Tx
<= r_data_byte
[7];10:Rs232_Tx
<= STOP_BIT
;default:Rs232_Tx
<= 1'b1
;endcaseend endmodule
RS485通信完成
總結(jié)
以上是生活随笔為你收集整理的40_ZYNQ7020开发板RS485协议通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。