徐州木塑模板,云南seo公司,网站建设需要什么内容,千锋教育招聘文章目录 一、串口通信二、UART通信三、tx发送模块四、rx模块接收 一、串口通信
处理器与外部设备通信的两种方式#xff1a; 串行通信#xff1a; 指数据的各个位使用多条数据线同时进行传输。 并行通信#xff1a; 将数据分成一位一位的形式在一条数据线上逐个传输。
串… 文章目录 一、串口通信二、UART通信三、tx发送模块四、rx模块接收 一、串口通信
处理器与外部设备通信的两种方式 串行通信 指数据的各个位使用多条数据线同时进行传输。 并行通信 将数据分成一位一位的形式在一条数据线上逐个传输。
串行通信的通信方式 同步通信 带时钟同步信号的数据传输发送方和接收方在同一时钟控制下同步传输数据。 异步通信 不带时钟同步信号的数据传输发送方和接收方使用各自的时钟控制数据的发送和接收过程。
串行通信的传输方向 单工 数据只能沿一个方向进行传输。 半双工 数据传输可以沿两个方向但需要分时进行。 全双工 数据可以同时进行双向传输。
常见的串行通信接口
二、UART通信
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)通常称作UART是一种异步收发传输器。 它在发送数据时将并行数据转换为串行的数据来传输在接收数据时将接收到的串行数据转换成并行数据。UART串口通信需要两根信号线来实现一根用于发送另一个用于接收。
协议层 数据格式1帧数据由4部分组成。
起始位1bit数据位6/7/8bit奇偶校验位1bit停止位1bit/1.5bit/2bit
奇校验原始码流校验位 总共有奇数个1 偶校验原始码流校验位 总共有偶数个1
传输速率 串口通信速率用波特率表示它表示每秒传输二进制数据的位数单位是bit/s位/秒简称bps常用的波特率有9600115200等。
物理层 串口电平标准
TTL电平的串口3.3VRS232电平的串口5V ~ 12V为低电平-12V ~ -5V为高电平)
三、tx发送模块
tx发送模块共四个状态IDLE状态START状态DATA状态FINISH状态。
/** Description: tx输出,波特率115200系统时钟50M传输1bit所需计数434个周期* Author: Fu Yu* Date: 2023-08-15 11:10:41* LastEditTime: 2023-08-15 14:55:04* LastEditors: Fu Yu*/module uart_tx (input wire clk ,input wire rst_n ,input wire [7:0] tx_din ,input wire tx_din_vld ,output wire tx_dout ,output wire ready
);parameter MAX_BIT 50_000_000/115200;//1bit计数最大值,434localparam IDLE 4b0001,START 4b0010,DATA 4b0100,FINISH 4b1000;reg [3:0] state_c;//现态
reg [3:0] state_n;//次态wire idle_start ;// IDLE - START
wire start_data ;// START - DATA
wire data_finish ;// DATA - FINISH
wire finish_idle ;// FINFISH - IDLEreg [8:0] cnt_bit ;
wire add_cnt_bit ;
wire end_cnt_bit ;reg [11:0] cnt_data ;
wire add_cnt_data ;
wire end_cnt_data ;reg [7:0] tx_din_r;
reg tx_dout_r;//****************************************************************
//-- 状态机
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginstate_c IDLE;endelse beginstate_c state_n;end
endalways ( *) begincase (state_c)IDLE : beginif(idle_start) beginstate_n START;endelse beginstate_n state_c;endendSTART : beginif(start_data) beginstate_n DATA;endelse beginstate_n state_c;endendDATA : beginif(data_finish) beginstate_n FINISH;endelse beginstate_n state_c;endendFINISH : beginif(finish_idle) beginstate_n IDLE;endelse beginstate_n state_c;endenddefault : state_n IDLE;endcase
endassign idle_start state_c IDLE tx_din_vld ;
assign start_data state_c START end_cnt_bit;
assign data_finish state_c DATA end_cnt_data;
assign finish_idle state_c FINISH end_cnt_bit;//****************************************************************
//-- 计数器
//****************************************************************
//1bit计数器
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_bit d0;end else if(add_cnt_bit)begin if(end_cnt_bit)begin cnt_bit d0;endelse begin cnt_bit cnt_bit 1b1;end end
end assign add_cnt_bit state_c START || state_c FINISH || state_c DATA;
assign end_cnt_bit add_cnt_bit cnt_bit MAX_BIT - 1;//8bit计数器
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_data d0;end else if(add_cnt_data)begin if(end_cnt_data)begin cnt_data d0;endelse begin cnt_data cnt_data 1b1;end end
end assign add_cnt_data state_c DATA end_cnt_bit;
assign end_cnt_data add_cnt_data cnt_data 8 - 1 ;//****************************************************************
//-- 输入数据寄存
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) begintx_din_r 0;endelse begintx_din_r tx_din;end
end//****************************************************************
//-- 实现串口时序
//****************************************************************
always ( *) begincase (state_c)IDLE : begintx_dout_r 1;endSTART : begintx_dout_r 0;endDATA : beginif(tx_din_r[cnt_data]) begintx_dout_r 1;endelse begintx_dout_r 0;endendFINISH : begintx_dout_r 1;enddefault : tx_dout_r 1;endcase
endassign tx_dout tx_dout_r;assign ready state_c IDLE;endmodule //uart_tx测试文件
/** Description: uart_tx仿真模块* Author: Fu Yu* Date: 2023-08-15 14:58:32* LastEditTime: 2023-08-15 15:06:49* LastEditors: Fu Yu*/timescale 1ns/1nsmodule tb_uart_tx();//激励信号定义 reg tb_clk ;reg tb_rst_n ;reg [7:0] tb_tx_din ;reg tb_tx_din_vld;//输出信号定义 wire tx_dout ;wire ready ;//时钟周期参数定义 parameter CLOCK_CYCLE 20; defparam u_uart_tx.MAX_BIT 10;
//模块例化
uart_tx u_uart_tx(/*input wire */ . clk (tb_clk) ,/*input wire */ . rst_n (tb_rst_n) ,/*input wire [7:0] */ . tx_din (tb_tx_din) ,/*input wire */ . tx_din_vld(tb_tx_din_vld) ,/*output wire */ . tx_dout (tx_dout) ,/*output wire */ . ready (ready)
);//产生时钟initial tb_clk 1b0;always #(CLOCK_CYCLE/2) tb_clk ~tb_clk;//产生激励initial begin tb_rst_n 1b1;tb_tx_din 0;tb_tx_din_vld 0;#(CLOCK_CYCLE*2);tb_rst_n 1b0;#(CLOCK_CYCLE*20);tb_rst_n 1b1;repeat(10) begintb_tx_din_vld 1;tb_tx_din {$random};#20;tb_tx_din_vld 0;wait(ready 1);#20;end#1000;$stop;endendmodule 仿真波形图 上板验证 加入按键控制模块每一次按下输出8’hAB
按键消抖模块
/** Description: 按键消抖使用延迟方法消抖后输出高电平信号* Author: Fu Yu* Date: 2023-08-07 14:22:56* LastEditTime: 2023-08-07 14:48:48* LastEditors: Fu Yu*/module key_filter #(parameter WITDH 3//WITDH表示位宽
)(input wire clk ,input wire rst_n ,input wire [WITDH-1:0] key_in ,output wire [WITDH-1:0] key_down
);parameter MAX_20MA 20d999_999;//20msreg [WITDH - 1:0] key_r0;//同步信号
reg [WITDH - 1:0] key_r1;//打拍
reg [WITDH - 1:0] key_r2;
reg [WITDH - 1:0] key_down_r;
reg [19:0] cnt_20ms;
reg flag;//开始计数信号wire [WITDH - 1:0] nedge;//下降沿
wire add_cnt_20ms;
wire end_cnt_20ms;//****************************************************************
//--同步打拍
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginkey_r0 {WITDH{1b1}};key_r1 {WITDH{1b1}};key_r2 {WITDH{1b1}};endelse beginkey_r0 key_in;key_r1 key_r0;key_r2 key_r1;end
end//下降沿检测
assign nedge ~key_r1 key_r2;//****************************************************************
//--flag
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginflag 1b0;endelse if(nedge) begin//检测到下降沿开始计数flag 1b1;endelse if(end_cnt_20ms) begin//20ms后停止计数flag 1b0;endelse beginflag flag;end
end//****************************************************************
//--20ms计数器
//****************************************************************always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_20ms 20d0;end else if(add_cnt_20ms)begin if(end_cnt_20ms)begin cnt_20ms 20d0;endelse begin cnt_20ms cnt_20ms 1b1;end end
end assign add_cnt_20ms flag;
assign end_cnt_20ms add_cnt_20ms cnt_20ms MAX_20MA;//****************************************************************
//--key_down
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginkey_down_r {WITDH{1b0}};endelse if(end_cnt_20ms) beginkey_down_r ~key_r2;endelse beginkey_down_r {WITDH{1b0}};end
endassign key_down key_down_r;endmodule //key_filter顶层模块
module top (input wire clk ,input wire rst_n ,input wire key_in ,output wire tx
);wire key_wire;
wire ready;key_filter #(.WITDH(1)) u_key_filter(/* input wire */. clk (clk) ,/* input wire */. rst_n (rst_n) ,/* input wire [WITDH-1:0]*/. key_in (key_in) ,/* output wire [WITDH-1:0]*/. key_down(key_wire)
);uart_tx u_uart_tx(/*input wire */ . clk (clk) ,/*input wire */ . rst_n (rst_n) ,/*input wire [7:0] */ . tx_din (8hab) ,/*input wire */ . tx_din_vld(key_wire ready) ,/*output wire */ . tx_dout (tx) ,/*output wire */ . ready (ready)
);endmodule //top效果展示
四、rx模块接收
/** Description: rx接收,波特率115200系统时钟50M传输1bit所需计数434个周期* Author: Fu Yu* Date: 2023-08-15 11:10:41* LastEditTime: 2023-08-16 10:03:27* LastEditors: Fu Yu*/module uart_rx (input wire clk ,input wire rst_n ,input wire rx_din ,output wire [7:0] rx_dout ,output wire rx_dout_vld ,output wire ready
);parameter MAX_BIT 50_000_000/115200;//1bit计数最大值,434localparam IDLE 4b0001,START 4b0010,DATA 4b0100,FINISH 4b1000;reg [3:0] state_c;//现态
reg [3:0] state_n;//次态wire idle_start ;// IDLE - START
wire start_data ;// START - DATA
wire data_finish ;// DATA - FINISH
wire finish_idle ;// FINFISH - IDLEreg [8:0] cnt_bit ;
wire add_cnt_bit ;
wire end_cnt_bit ;reg [11:0] cnt_data ;
wire add_cnt_data ;
wire end_cnt_data ;reg [7:0] rx_dout_r;//****************************************************************
//-- 状态机
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginstate_c IDLE;endelse beginstate_c state_n;end
endalways ( *) begincase (state_c)IDLE : beginif(idle_start) beginstate_n START;endelse beginstate_n state_c;endendSTART : beginif(start_data) beginstate_n DATA;endelse beginstate_n state_c;endendDATA : beginif(data_finish) beginstate_n FINISH;endelse beginstate_n state_c;endendFINISH : beginif(finish_idle) beginstate_n IDLE;endelse beginstate_n state_c;endenddefault : state_n IDLE;endcase
endassign idle_start state_c IDLE rx_din 0 ;
assign start_data state_c START end_cnt_bit;
assign data_finish state_c DATA end_cnt_data;
assign finish_idle state_c FINISH end_cnt_bit;//****************************************************************
//-- 计数器
//****************************************************************
//1bit计数器
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_bit d0;end else if(add_cnt_bit)begin if(end_cnt_bit)begin cnt_bit d0;endelse begin cnt_bit cnt_bit 1b1;end end
end assign add_cnt_bit state_c START || state_c FINISH || state_c DATA;
assign end_cnt_bit add_cnt_bit cnt_bit MAX_BIT - 1;//8bit计数器
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_data d0;end else if(add_cnt_data)begin if(end_cnt_data)begin cnt_data d0;endelse begin cnt_data cnt_data 1b1;end end
end assign add_cnt_data state_c DATA end_cnt_bit;
assign end_cnt_data add_cnt_data cnt_data 8 - 1 ;//****************************************************************
//-- 实现数据接收
//****************************************************************
always (posedge clk or negedge rst_n) beginif(!rst_n) beginrx_dout_r 0;endelse if(state_c DATA cnt_bit MAX_BIT 1) beginrx_dout_r[cnt_data] rx_din;end
endassign rx_dout rx_dout_r;assign rx_dout_vld data_finish;assign ready state_c IDLE;endmodule //uart_rxip核fifo调用
module ctrl (input wire clk ,input wire rst_n ,input wire [7:0] rx_data ,input wire rx_data_vld ,input wire tx_ready ,output wire [7:0] tx_data ,output wire tx_data_vld
);wire fifo_rd_empty;
wire fifo_wr_full;fifo fifo_inst (.aclr ( ~rst_n ),.data ( rx_data ),.wrclk ( clk ),.wrreq ( rx_data_vld ~fifo_wr_full ),.q ( tx_data ),.rdclk ( clk ),.rdreq ( tx_ready ~fifo_rd_empty ),.rdempty ( fifo_rd_empty ),.wrfull ( fifo_wr_full ));assign tx_data_vld tx_ready ~fifo_rd_empty ;endmodule //ctrl顶层模块
module top (input wire clk ,input wire rst_n ,input wire key_in ,input wire rx ,output wire tx
);wire key_wire;
wire tx_ready;
wire [7:0] rx_data;
wire rx_data_vld;
wire [7:0] tx_data;
wire tx_data_vld;key_filter #(.WITDH(1)) u_key_filter(/* input wire */. clk (clk) ,/* input wire */. rst_n (rst_n) ,/* input wire [WITDH-1:0]*/. key_in (key_in) ,/* output wire [WITDH-1:0]*/. key_down(key_wire)
);uart_tx u_uart_tx(/*input wire */ . clk (clk) ,/*input wire */ . rst_n (rst_n) ,/*input wire [7:0] */ . tx_din (tx_data) ,/*input wire */ . tx_din_vld(tx_data_vld) ,/*output wire */ . tx_dout (tx) ,/*output wire */ . ready (tx_ready)
);uart_rx u_uart_rx(/* input wire */. clk (clk ) ,/* input wire */. rst_n (rst_n ) ,/* input wire */. rx_din (rx ) ,/* output wire [7:0] */. rx_dout (rx_data) ,/* output wire */. rx_dout_vld(rx_data_vld) ,/* output wire */. ready ()
);ctrl u_ctrl(/* input wire */ . clk (clk) ,/* input wire */ . rst_n (rst_n) ,/* input wire [7:0] */ . rx_data (rx_data) ,/* input wire */ . rx_data_vld(rx_data_vld) ,/* input wire */ . tx_ready (tx_ready) ,/* output wire [7:0] */ . tx_data (tx_data) ,/* output wire */ . tx_data_vld(tx_data_vld)
);endmodule //top将rx接收模块与tx发送模块联合使用效果如下