1. UART_SEND简介:
串口是用的非常多的一种接口,实现原理比较简单,基本所有CPU芯片都配置有串口,所以经常被用来作为调试接口。
2. UART_SEND规格:
实现9600波特率的串口发送,上位机串口软件可以接收到发送的数据。
3. 实现原理
以波特率9600为例子说明,波特率9600接收一个bit的时间为1s/9600=104us,即每隔104us发送一个数据。
104us = 104000ns 50M时钟的一个周期时间为20ns要远小于104000ns,所以可以用50M时钟产生的计数器来计数,然后根据计数器来发送数据。
新建一个计数器,50Mhz为时钟,那么计数器变化一次时间为20ns。
由于一次完整数据接收需要有1144000ns时间,所以计数器必须记到1144000ns时间。
1144000ns/20ns = 57200,所以需要16位计数器。
Startbit(0)占据计数器的0 -104000ns/20ns = 5200
D0 占据计数器的5200-208000ns/20ns = 10400
D1 占据计数器的10400-312000ns/20ns = 15600
D2 占据计数器的15600-416000ns/20ns = 20800
D3 占据计数器的20800-520000ns/20ns = 26000
D4 占据计数器的26000-624000ns/20ns = 31200
D5 占据计数器的31200-728000ns/20ns = 36400
D6 占据计数器的36400-832000ns/20ns = 41600
D7 占据计数器的41600-936000ns/20ns = 46800
校验位 占据计数器的46800-1040000ns/20ns = 52000
Endbit(1) 占据计数器的52000-1144000ns/20ns = 57200
4. Verilog HDL源代码
Verilog HDL代码为:
moduleUartSend (
//input
sys_clk ,
sys_rst_n ,
data_in , //data in 8bit
//output
uart_txd
);
//inputports
input sys_clk ; //system clock;
input sys_rst_n ; //system reset, low is active;
input[WIDTH-1:0] data_in ; //to send data 8bit ;
//outputports
output uart_txd ; //uart txd output ;
//regdefine
reg [WIDTH-1:0] buff ;
reg [WIDTH-1:0] data_out ;
reg uart_txd ;
reg txd ; //temp txd signal;
reg [SIZE-1:0] counter ;
//wiredefine
//parameterdefine
parameterWIDTH = 8;
parameterSIZE = 16;
/*******************************************************************************************************
** Main Program
**
********************************************************************************************************/
always@(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
buff <= 8'b0;
end
else
buff <= data_in ;
end
always@(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
counter <= 16'b0;
end
else if (counter > 57200 )
counter <= 16'b0;
else
counter <= counter + 1'b1;
end
always@(*) begin
if ((counter > 0) && (counter <= 5200 ))
txd = 1'b0 ;
else if ((counter > 5200)&& (counter <= 10400))
txd = buff[0] ;
else if ((counter > 10400) &&(counter <= 15600))
txd = buff[1] ;
else if ((counter > 15600) &&(counter <= 20800))
txd = buff[2] ;
else if ((counter > 20800) &&(counter <= 26000))
txd = buff[3] ;
else if ((counter > 26000) &&(counter <= 31200))
txd = buff[4] ;
else if ((counter > 31200) &&(counter <= 36400))
txd = buff[5] ;
else if ((counter > 36400) &&(counter <= 41600))
txd = buff[6] ;
else if ((counter > 41600) &&(counter <= 46800))
txd = buff[7] ;
else if ((counter > 46800) &&(counter <= 52000))
txd = 1'b1 ;
else if ((counter > 52000) &&(counter <= 57200))
txd = 1'b1 ;
else
txd = 1'b1 ;
end
always@(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0) begin
uart_txd <= 1'b1;
end
else
uart_txd <= txd;
end
endmodule
//endof RTL code