1.原理介绍:FPGA实现串口通信,将8bit的数据按照从地位到高位的串口发送。将原理图P上来。
2.通过与按键消抖模块利用top_down,让按键按一次,实现自加1,加到1111_1111。
按键产生数据程序:
module gen_data(
input wire sclk,
input wire rst_n,
input wire key_out_in,
output reg[7:0] gen_data_out,
output reg flag
);
always@(posedge sclk or negedge rst_n)
if(!rst_n)
gen_data_out<=8'd0;
else if(key_out_in==1'b1)
gen_data_out<=gen_data_out+1'b1;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
flag<=1'b0;
else if(key_out_in==1'b1)
flag<=1'b1; //修改后的条件
else flag<=1'b0;
endmodule
串口通信协议模块:
module uart_crtl(
input wire sclk,
input wire rst_n,
input wire [7:0] data_in,
input wire flag_in,
output reg data_o
);
reg [12:0] cnt;
reg [3:0] bit_cnt;
reg tx_en;
parameter CNT=5207;
parameter BIT_CNT=9;
//tx_en
always@(posedge sclk or negedge rst_n)
if(!rst_n)
tx_en<=1'b0;
else if(flag_in==1'b1)
tx_en<=1'b1;
else if(bit_cnt==BIT_CNT&&cnt==CNT)
tx_en<=1'b0;
//cnt 波特率计数
always@(posedge sclk or negedge rst_n)
if(!rst_n)
cnt<=13'd0;
else if(cnt==CNT)
cnt<=13'd0;
else if(tx_en==1'b1) //条件没写对
cnt<=cnt+1'b1;
//bit_cnt 字节统计
always@(posedge sclk or negedge rst_n)
if(!rst_n)
bit_cnt<=4'd0;
else if(tx_en==1'b0)
bit_cnt<=4'd0;
else if(bit_cnt==BIT_CNT&cnt==CNT)
bit_cnt<=4'd0;
else if(cnt==CNT)
bit_cnt<=bit_cnt+1'b1;
//输出数据控制
always@(posedge sclk or negedge rst_n)
if(!rst_n)
data_o<=1'b1;
else if(tx_en==1'b1&&bit_cnt==10'd0) //flag_in==1'b1
data_o<=1'b0;
else if(bit_cnt==10'd1)
data_o<=data_in[0];
else if (bit_cnt==10'd2)
data_o<=data_in[1];
else if(bit_cnt==10'd3)
data_o<=data_in[2];
else if(bit_cnt==10'd4)
data_o<=data_in[3];
else if(bit_cnt==10'd5)
data_o<=data_in[4];
else if(bit_cnt==10'd6)
data_o<=data_in[5];
else if(bit_cnt==10'd7)
data_o<=data_in[6];
else if(bit_cnt==10'd8)
data_o<=data_in[7];
else if(bit_cnt==BIT_CNT)
data_o<=1'b1;
else data_o<=1'b1;
endmodule
说明 if_else模块也可以用case语句实现,下边的代码就是利用case语句实现数据传输:
always@(posedge sclk or negedge rst_n) //输入输出数据串并转换
if(!rst_n)
data_o<=1'b1;
else if(tx_en==1'b1&&cnt_bit==4'd0)
data_o<=1'b0;
else case(cnt_bit)
4'd1: data_o<=data_in[0];
4'd2: data_o<=data_in[1];
4'd3: data_o<=data_in[2];
4'd4: data_o<=data_in[3];
4'd5: data_o<=data_in[4];
4'd6: data_o<=data_in[5];
4'd7: data_o<=data_in[6];
4'd8: data_o<=data_in[7];
4'd9: data_o<=1'b1;
default: data_o<=1'b1;
endcase
top_down 将各个模块连接在一起;
module top_down(
input wire sclk,
input wire rst_n,
input wire key_in,
output wire data
);
wire key_o_1;
wire [7:0] gen_data_1; ///
wire flag_1;
key_rock key_rock_inst(
.sclk (sclk),
.rst_n (rst_n),
.key_in (key_in),
.key_o (key_o_1)
);
gen_data gen_data_inst(
.sclk (sclk),
.rst_n (rst_n),
.key_out_in (key_o_1),
. gen_data_out (gen_data_1),
. flag (flag_1)
);
uart_crtl uart_crtl_inst(
.sclk (sclk),
.rst_n (rst_n),
.data_in (gen_data_1),
.flag_in (flag_1),
.data_o (data)
);
endmodule
3.对模块进行仿真,主要是对通信模块进行仿真。仿真信号必须与预设的一致,不允许有半点偏差,否则实现不了按键发送数据传输。
4.实现后,利用友善数据串口,可以看到按键实现加1功能。