当前位置:
文档之家› 基于Verilog的串口通信程序
基于Verilog的串口通信程序
always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rs232_rx0 <= 1'b0; rs232_rx1 <= 1'b0; rs232_rx2 <= 1'b0; rs232_rx3 <= 1'b0; end else if(!rx_int) begin rs232_rx0 <= rs232_rx; rs232_rx1 <= rs232_rx0; rs232_rx2 <= rs232_rx1; rs232_rx3 <= rs232_rx2; end
assign clk_bps = clk_bps_r;
endmodule
第二个模块:接收模块
`timescale 1ns / 1ps //////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 21:27:40 14/07/28 // Design Name: // Module Name: my_uart_rx // Project Name: // Target Device: // Tool versions:
/* parameter
bps9600 = 5207, //波特率为 9600bps bps19200 = 2603, //波特率为 19200bps bps38400 = 1301, //波特率为 38400bps bps57600 = 867, //波特率为 57600bps bps115200 = 433; //波特率为 115200bps
算作是 Verilog 入门的第一个程序吧,在别人的程序修改过来的,还没有做太多的优化,只优化了一部分。 程序分成 4 个模块 第一个模块时钟分频:
`timescale 1ns / 1ps //////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 21:27:40 14/07/28 // Design Name: // Module Name: speed_select // Project Name: // Target Device: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // //////////////////////////////////////////////////////////////////////////////// module speed_select(
output bps_start;
//接收到数据后,波特率时钟启动信号置位
output[7:0] rx_data;//接收数据寄存器,保存直至下一个数据来到
output rx_int; //接收数据中断信号,接收到数据期间始终为高电平
output led;
//---------------------------------------------------------------reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;//接收数据寄存器,滤波用 wire neg_rs232_rx; //表示数据线接收到下降沿
if(!rst_n) begin
bps_start_r <= 1'bz;
rx_int <= 1'b0;
end
else if(neg_rs232_rx) begin
//接收到串口接收线 rs232_rx 的下降沿标志信号
bps_start_r <= 1'b1; //启动串口准备数据接收
rx_int <= 1'b1;
end */
end
assign rx_data = rx_data_r; assign led= rs232_rx;
endmodule
第三个模块发送: `timescale 1ns / 1ps //////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 21:27:40 14/07/28 // Design Name: // Module Name: my_uart_rx // Project Name: // Target Device: // Tool versions: // Description: // // Dependencies:
end //下面的下降沿检测可以滤掉<20ns-40ns 的毛刺(包括高脉冲和低脉冲毛刺),
//这里就是用资源换稳定(前提是我们对时间要求不是那么苛刻,因为输入信号打了好几拍) //(当然我们的有效低脉冲信号肯定是远远大于 40ns 的) assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0; //接收到下降沿后 neg_rs232_rx 置高一个时钟周期
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 13'd0;
else if((cnt == `BPS_PARA) || !bps_start) cnt <= 13'd0; //波特率计数清零
else cnt <= cnt+1'b1;
//波特率时钟计数启动
`define BPS_PARA_2
2603 //波特率为 9600 时的分频计数值的一半,用于数据采样
reg[12:0] cnt; reg clk_bps_r;
//分频计数 //波特率时钟寄存器
//---------------------------------------------------------reg[2:0] uart_ctrl; // uart 波特率选择寄存器 //----------------------------------------------------------
endcase
end
/* else if(num == 4'd9) begin
//我们的标准接收模式下只有 1+8+1(2)=11bit 的有效数
据
num <= 4'd0;
//接收到 STOP 位后结束,num 清零 xia
rx_data_r <= rx_temp_data; //把数据锁存到数据寄存器 rx_data 中
4'd4: rx_temp_data[3] <= rs232_rx; //锁存第 3bit
4'd5: rx_temp_data[4] <= rs232_rx; //锁存第 4bit
4'd6: rx_temp_data[5] <= rs232_rx; //锁存第 5bit
4'd7: rx_temp_data[6] <= rs232_rx; //锁存第 6bit
//----------------------------------------------------------------
reg[7:0] rx_data_r;
//串口接收数据寄存器,保存直至下一个数据来到
//----------------------------------------------------------------
// Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // //////////////////////////////////////////////////////////////////////////////// module my_uart_rx(
//----------------------------------------------------------------
reg bps_start_r;
reg[3:0] num; //移位次数
reg rx_int;
//接收数据中断信号,接收到数据期间始终为高电平
always @ (posedge clk or negedge rst_n)
always @ (posedge clk or negedge rst_n) if(!rst_n) clk_bps_r <= 1'b0; else if(cnt == `BPS_PARA_2) clk_bps_r <= 1'b1; // clk_bps_r 高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点 else clk_bps_r <= 1'b0;
reg[7:0] rx_temp_data; //当前接收数据寄存器
always @ (posedge clk or negedge rst_n) if(!rst_n) begin rx_temp_data <= 8'd0; num <= 4'd0; rx_data_r <= 8'd0; end else if(rx_int) begin //接收数据处理 if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit 数据,1 或 2 个结束位