USART串口发送模块的编写,模块的参数列表输入信号有时钟clk,复位rst,发送使能tx_en,校验模式mod,时钟频率frequency,波特率baud,输出信号有串口发送的数据data,接受使能。由于串口是半双工通讯,在进行发送的时候,不可以接受。所以有一个接收使能的输出。串口的校验模式,有奇校验,偶校验和无校验。
波特率是串口每秒发送数据的最大个数,每传送一个数据所需要的时间为时钟频率除以波特率。这样我们可以定义一个计数器,让它根据时钟来计数,当计数值等于频率除以波特率减一时,我们设置一个标志位flag等于1。当flag等于一时,计数器清零。再定义一个5位的寄存器select,当接收到发送使能时,并且收到标志位的高电平(每个标志位的间隔即是发送数据所需要的间隔)给select赋值为1,并且把需要输出的数据传给一个寄存器,这个就寄存器的作用是保存要发送的数据,防止发送段数据变化影响发送结果。串口一个帧结构包含起始位,起始位为低电平,起始位后面跟着8位数据位,和一位的校验位,和结束为位,结束为的位数可以自定义,一般多加几位,以隔开下一个数据。
当select为0时,代表还没接收到发送使能信号,接受使能为高电平,当接受到发送使能,select会一直变化知道发送完数据,这时发送使能rx_en为低电平。
最后就是输出信号,用前面的select为状态机,当select为0,1时,给数据一个传输时间,传输数据为默认的高电平,当select等2时,产生低电平的起始位,接着当select为3到10时传输8位数据,后面跟着校验位,校验方式根据输入的校验模式决定,最后时4位的结束位。串口的发送模块就完成了。
module usart_tx(
input clk,rst,tx_en,frequency,baud,
input [7:0] tx_data,
input [1:0] mod,
ouput data,rx_en
);
reg [32:0]cnt;
wire [7:0] checkout = ^tx_data;
wire flag = (cnt == frequency / baud - 1);
always@(posedge clk) if (rst) cnt <= 0; else cnt <= (flag) ? 0 : cnt + 1;
reg [4:0] select;
reg [7:0] transfer;
always@(posedge clk) if(rst) select <= 0; else case(tx_en)
0: if(select) begin transfer<= tx_data; select <= 1;end
1:if(flag) select <= 2;
2:if(flag) select <= 3;
3:if(flag) select <= 4;
4:if(flag) select <= 5;
5:if(flag) select <= 6;
6:if(flag) select <= 7;
7:if(flag) select <= 8;
8:if(flag) select <= 9;
9:if(flag) select <= 10;
10:if(flag) select <= 11;
11:if(flag) select <= 12;
12:if(flag) select <= 13;
13:if(flag) select <= 14;
14:if(flag) select <= 15;
15:if(flag) select <= 0;
default: select select <= 0;
endcase
always@(posdege clk) if (rst) rx_en <= 1; else case(select) 0: rx_en <= 1;default: rx_en <= 0;endcase
always @(posdege clk) if (rst) data <= 1; esle case (select) 0,1: data <= 1;
2: data <= 0;
3: data <= transfer[0];
4: data <= transfer[1];
5: data <= transfer[2];
6: data <= transfer[3];
7: data <= transfer[4];
8: data <= transfer[5];
9: data <= transfer[6];
10: data <= transfer[7];
11:
begin case(mod)
0: data <= 0;
1: data <= ~checkout;
2: data <= checkout;
default: data <= 1;
endcase
end
12,13,14,15: data <= 1;
default: data <= 1;
endcase
endmodule