当数据传来的时候会伴随一个标志信号,当识别到tx_en的时候,数据便会被一位位的发送。
假设传输速率为9600bit/s,系统时钟为50MHZ,则每个bit需保持的时钟周期个数为50M/9600=5207。因为数据在保持的时间内,中间是最稳定的,因此可以记到一半的时候把数据读出来。根据串口的协议,这个串口在无数据传输的时候,tx为高电平,因此复位时为高点平。
编写一个程序:按键按下去发送一个数据,在电脑端显示出来
module xiaodou(
input wire clk ,
input wire rst_n ,
input wire key,
output reg key_out
);
//按下消抖
reg[18:0] cnt ;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 19’b0;
else if(key==1)
cnt <= 19’b0;
else if(cnt==500000)
cnt <=500000;
else if(key==0)
cnt <= cnt +19’b1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_out <= 1’b0;
else if(key==0&&cnt==499999)
key_out <= 1’b1;
else
key_out <= 1’b0;
/*
//松开消抖
reg key_en;
reg key_en_dly;
reg[18:0] cnt ;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 19’b0;
else if(key==1)
cnt <= 19’b0;
else if(cnt==500000)
cnt <=500000;
else if(key==0)
cnt <= cnt +19’b1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_en <= 1’b0;
else if(cnt==500000)
key_en <= 1’b1;
else
key_en <= 1’b0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_en_dly <= 0;
else
key_en_dly <= key_en;
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_out <= 0;
else if(key_en==0&&key_en_dly==1)
key_out <= 1;
else
key_out <= 0;
*/
endmodule
module gen_data(
input wire clk ,
input wire rst_n ,
input wire key_out ,
output reg[7:0] data_o,
output reg flag_o
);
always@(posedge clk or negedge rst_n)
if(rst_n==0)
data_o <= 8’b0;
else if(key_out==1&&data_o==255)
data_o <= 8’b0;
else if(key_out==1)
data_o <= data_o +8’b1;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
flag_o <= 0;
else if(key_out==1)
flag_o <= 1;
else
flag_o <= 0;
endmodule
module tx(
input wire clk,
input wire rst_n,
input wire[7:0] data_i,
input wire flag_i,
output reg tx_o
);
reg tx_en;
reg[12:0] cnt;
reg[3:0] bit_cnt;
reg flag;
parameter CNT_MAX=5207;
parameter BIT_CNT_MAX=9;
parameter CNT_hMAX=2604;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
flag <= 0;
else if(cnt==CNT_hMAX)
flag <= 1;
else
flag <= 0;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
tx_en <= 0;
else if(flag_i==1)
tx_en <= 1;
else if(bit_cnt==BIT_CNT_MAX&&flag==1)
tx_en <= 0;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
cnt <= 13’b0;
else if(cnt==CNT_MAX&&tx_en==1)
cnt <= 13’b0;
else if(flag==1&&bit_cnt==BIT_CNT_MAX&&tx_en==1)
cnt <= 13’b0;
else if(tx_en==1)
cnt <= cnt +13’b1;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
bit_cnt <= 4’b0;
else if(bit_cnt==BIT_CNT_MAX&&flag==1&&tx_en==1)
bit_cnt <= 4’b0;
else if(flag==1&&tx_en==1)
bit_cnt <= bit_cnt + 4’b1;
always@(posedge clk or negedge rst_n)
if(rst_n==0)
tx_o <= 1;
else if(tx_en==0)
tx_o <= 1;
else if(flag==1)
case(bit_cnt)
0: tx_o <= 0;
1: tx_o <=data_i[0];
2: tx_o <=data_i[1];
3: tx_o <=data_i[2];
4: tx_o <=data_i[3];
5: tx_o <=data_i[4];
6: tx_o <=data_i[5];
7: tx_o <=data_i[6];
8: tx_o <=data_i[7];
default: tx_o <= 1;
endcase
endmodule
module top(
input wire clk,
input wire key,
input wire rst_n,
output wire tx_o
);
xiaodou xiaodou_inst(
.clk (clk ) ,
.rst_n (rst_n ) ,
.key (key ) ,
.key_out (key_out)
);
wire [7:0] data;
wire flag;
gen_data gen_data_inst(
.clk (clk) ,
.rst_n (rst_n) ,
.key_out(key_out) ,
.data_o (data) ,
.flag_o (flag)
);
tx tx_inst(
.clk (clk) ,
.rst_n (rst_n) ,
.data_i (data) ,
.flag_i (flag) ,
.tx_o (tx_o)
);
endmodule