名称:RS232接口数据发送UART串口协议Verilog代码Quartus仿真
软件:Quartus
语言:Verilog
代码功能:
设计RS232接口数据转发协议,将8位并行数据转发为RS232协议的串口数据发送出去。
entity rs232
port(clk: in std_ logic;--16MHz输入时钟
rdy: in std logic;-数据准备好信号,1个时钟周期的正脉冲
data: in std logic vecton(7 downto0);--要发送的并行数据
bps: in std logic_ vector( I downto0):--波特率设置
00:9600bps01:1920010:38400
d_out: out std_ logic);-串行数据输出
end rs232.
协议要求:
(1)波特率:9600/19200/38400可选;
(2)8位数据位,1为停止位,偶校验。
设计要求:
(1)采用VHDL或 Verilog语言设计上述电路;
(2)写出测试激励文件,并仿真;
(3)分析仿真结果,并撰写设计报告;
(4)提交完整的电子版设计报告并附源代码。
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
1. 工程文件
2. 程序文件
3. 程序编译
4. Testbench
5. 仿真图
部分代码展示:
module?rs232( ????input??????clk,??????????????????//系统时钟16MHz ????input?????????rst_n,????????????????//系统复位,低电平有效 ????input?????????rdy,??????????????????//数据准备好信号,1时钟周期正脉冲 ????input??[7:0]??data,?????????????????//待发送并行数据 ?input??[1:0]??bps,??????????????????//波特率设置,00:9600bps?01:19200?10:38400 ????output??reg???d_out?????????????????//串行数据输出 ????); //parameter?define parameter??CLK_FREQ?=?16000000;?????????????//系统时钟频率16MHz reg?[31:0]?UART_BPS?=?9600;?????????????????//串口波特率 always?@(posedge?clk?or?negedge?rst_n)????????? ????if?(!rst_n)? UART_BPS<=9600; ?else case(bps) 2'b00:UART_BPS<=9600;//9600bps 2'b01:UART_BPS<=19200;//19200bps 2'b10:UART_BPS<=38400;//38400bps default:; endcase wire?[31:0]?BPS_CNT;//为得到指定波特率,对系统时钟计数BPS_CNT次 assign?BPS_CNT??=?CLK_FREQ/UART_BPS;????//为得到指定波特率,对系统时钟计数BPS_CNT次 //reg?define reg????????uart_en_d0;? reg????????uart_en_d1;?? reg?[15:0]?clk_cnt;?????????????????????????//系统时钟计数器 reg?[?3:0]?tx_cnt;??????????????????????????//发送数据计数器 reg????????tx_flag;?????????????????????????//发送过程标志信号 reg?[?7:0]?tx_data;?????????????????????????//寄存发送数据 //wire?define wire???????en_flag; //***************************************************** //**????????????????????main?code //***************************************************** //捕获uart_en上升沿,得到一个时钟周期的脉冲信号 assign?en_flag?=?(~uart_en_d1)?&?uart_en_d0; ????????????????????????????????????????????????? //对发送使能信号uart_en延迟两个时钟周期 always?@(posedge?clk?or?negedge?rst_n)?begin????????? ????if?(!rst_n)?begin ????????uart_en_d0?<=?1'b0;?????????????????????????????????? ????????uart_en_d1?<=?1'b0; ????end?????????????????????????????????????????????????????? ????else?begin??????????????????????????????????????????????? ????????uart_en_d0?<=?rdy;??????????????????????????????? ????????uart_en_d1?<=?uart_en_d0;???????????????????????????? ????end end //当脉冲信号en_flag到达时,寄存待发送的数据,并进入发送过程?????????? always?@(posedge?clk?or?negedge?rst_n)?begin????????? ????if?(!rst_n)?begin?????????????????????????????????? ????????tx_flag?<=?1'b0; ????????tx_data?<=?8'd0; ????end? ????else?if?(en_flag)?begin?????????????????//检测到发送使能上升沿?????????????????????? ????????????tx_flag?<=?1'b1;????????????????//进入发送过程,标志位tx_flag拉高 ????????????tx_data?<=?data;????????????//寄存待发送的数据 ????????end ????????else? ????????if?((tx_cnt?==?4'd10)&&(clk_cnt?==?BPS_CNT/2)) ????????begin???????????????????????????????//计数到停止位中间时,停止发送过程 ????????????tx_flag?<=?1'b0;????????????????//发送过程结束,标志位tx_flag拉低 ????????????tx_data?<=?8'd0; ????????end ????????else?begin ????????????tx_flag?<=?tx_flag; ????????????tx_data?<=?tx_data; ????????end? end //进入发送过程后,启动系统时钟计数器与发送数据计数器 always?@(posedge?clk?or?negedge?rst_n)?begin????????? ????if?(!rst_n)?begin????????????????????????????? ????????clk_cnt?<=?16'd0;?????????????????????????????????? ????????tx_cnt??<=?4'd0; ????end?????????????????????????????????????????????????????? ????else?if?(tx_flag)?begin?????????????????//处于发送过程 ????????if?(clk_cnt?<?BPS_CNT?-?1)?begin ????????????clk_cnt?<=?clk_cnt?+?1'b1; ????????????tx_cnt??<=?tx_cnt; ????????end ????????else?begin ????????????clk_cnt?<=?16'd0;???????????????//对系统时钟计数达一个波特率周期后清零 ????????????tx_cnt??<=?tx_cnt?+?1'b1;???????//此时发送数据计数器加1 ????????end ????end ????else?begin??????????????????????????????//发送过程结束 ????????clk_cnt?<=?16'd0; ????????tx_cnt??<=?4'd0; ????end
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=530