完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
前言
博客上面,人人都说uart简单,刚上手时,笔者也是一脸懵逼。只能假装uart协议确实简单,只不过。。。。(手动笑脸) 00.串口发送原理图 01.串口发送模块uart_byte_tx.v module uart_byte_tx( Clk ,//50M时钟 Rst_n ,//复位信号 send_en ,//发送使能信号 baud_set ,//波特率选项 data_byte ,//要发送的单字节数据 rs232_tx ,//要发送出去的单比特数据 tx_done ,//发送接收标志 tx_state //发送的状态 ); input Clk ; input Rst_n ; input send_en ; input [2:0] baud_set ; input [7:0] data_byte ; output reg rs232_tx ; output reg tx_done ; output reg tx_state ; //两级寄存器消除亚稳态 reg [7:0] r_data_byte; //根据波特率选择查找表,选择分频计数时的最大值 reg [15:0] baud_dr; //根据上面分频计数时的最大值,生成波特率时钟 reg bps_clk; reg [15:0] div_cnt; //这是根据波特时钟产生的计数器,方便后面进一步控制数据串并转换 reg [3:0] bps_cnt; //两级寄存器消除亚稳态 //reg [7:0] r1_data_byte,r2_data_byte; always@(posedge Clk or negedge Rst_n) if(!Rst_n)begin r_data_byte 《= ‘d0; end else if(send_en) begin r_data_byte 《= data_byte; end //根据波特率选择查找表,选择分频计数时的最大值 //reg [15:0] baud_dr; always@(posedge Clk or negedge Rst_n) if(!Rst_n) baud_dr 《= 15’d5207; else begin case(baud_set) 0:baud_dr 《= 16‘d5207; 1:baud_dr 《= 16’d2603; 2:baud_dr 《= 16‘d1301; 3:baud_dr 《= 16’d867; 4:baud_dr 《= 16‘d433; default:baud_dr 《= 16’d5207; endcase end //根据上面分频计数时的最大值,生成波特率时钟 //reg bps_clk; //reg [15:0] div_cnt; always@(posedge Clk or negedge Rst_n) if(!Rst_n) div_cnt 《= ‘d0; else if(tx_state) if(div_cnt == baud_dr)//这里之前赋值为baud_set了,波形不对 div_cnt 《= ’d0; else div_cnt 《= div_cnt + 1‘b1; else div_cnt 《= ’d0; always@(posedge Clk or negedge Rst_n) if(!Rst_n) bps_clk 《= 1‘b0; //else if(div_cnt == baud_dr)//这是每次计数完的时候产生的波特率时钟,如果在计数结束时生成时钟就统一往后延迟了下,可以选择在div_cnt=1时生成 else if(div_cnt == 1’b1) bps_clk 《= 1‘b1; else bps_clk 《= 1’b0; //这是根据波特时钟产生的计数器,方便后面进一步控制数据串并转换 //reg [3:0] bps_cnt; always@(posedge Clk or negedge Rst_n) if(!Rst_n) bps_cnt 《= ‘d0; else if(bps_cnt == ’d11) bps_cnt 《= ‘d0; else if(bps_clk) bps_cnt 《= bps_cnt + 1’b1; else bps_cnt 《= bps_cnt; //根据波特率时钟产生的计数器,选择数据的传输 localparam START_BIT = 1‘b0; localparam STOP_BIT = 1’b1; always@(posedge Clk or negedge Rst_n) if(!Rst_n) rs232_tx 《= 1‘b1; else case(bps_cnt) ’d0:rs232_tx 《= 1‘b1; ’d1:rs232_tx 《= START_BIT; ‘d2:rs232_tx 《= r_data_byte[0]; ’d3:rs232_tx 《= r_data_byte[1]; ‘d4:rs232_tx 《= r_data_byte[2]; ’d5:rs232_tx 《= r_data_byte[3]; ‘d6:rs232_tx 《= r_data_byte[4]; ’d7:rs232_tx 《= r_data_byte[5]; ‘d8:rs232_tx 《= r_data_byte[6]; ’d9:rs232_tx 《= r_data_byte[7]; ‘d10:rs232_tx 《= STOP_BIT; default:rs232_tx 《= 1’b1; endcase //tx_done:当波特率时钟计数器计数到11时,计数就清零,方便进行下一轮的计数 always@(posedge Clk or negedge Rst_n) if(!Rst_n) tx_done 《= 1‘b0; else if(bps_cnt == ’d11) tx_done 《= 1‘b1; else tx_done 《= 1’b0; //tx_state:通过send_en和波特率计数(bps_cnt == 11)描述出发送的状态 always@(posedge Clk or negedge Rst_n) if(!Rst_n) tx_state 《= 1‘b0; else if(send_en) tx_state 《= 1’b1; else if(bps_cnt == ‘d11) tx_state 《= 1’b0; else tx_state 《= tx_state; endmodule 02.串口发送仿真uart_byte_tx_tb.v `timescale 1ns/1ns `define clock_period 20 module uart_byte_tx_tb; reg Clk ; reg Rst_n ; reg send_en ; reg [2:0] baud_set ; reg [7:0] data_byte ; wire rs232_tx ; wire tx_done ; wire tx_state ; uart_byte_tx uart_byte_tx_inst( .Clk (Clk ), .Rst_n (Rst_n ), .send_en (send_en ), .baud_set (baud_set ), .data_byte (data_byte ), .rs232_tx (rs232_tx ), .tx_done (tx_done ), .tx_state (tx_state ) ); //产生时钟 initial Clk = 1‘b1; always #(`clock_period/2) Clk = ~Clk; //产生激励信号 initial begin Rst_n = 1’b0; data_byte = 8‘b0; send_en = 1’b0; baud_set = 3‘d4; #(`clock_period*20 + 1); Rst_n = 1’b1; #(`clock_period*50); data_byte = 8‘haa; send_en = 1’d1; #`clock_period; send_en = 1‘d0; @(posedge tx_done); #(`clock_period*5000); data_byte = 8’h55; send_en = 1‘d1; #`clock_period; send_en = 1’d0; @(posedge tx_done); #(`clock_period*5000); data_byte = 8‘hdc; send_en = 1’d1; #`clock_period; send_en = 1‘d0; @(posedge tx_done); #(`clock_period*5000); data_byte = 8’hcd; send_en = 1‘d1; #`clock_period; send_en = 1’d0; @(posedge tx_done); #(`clock_period*5000); $stop; end endmodule 功能仿真如下: 后记 下面就开始,串口接收模块。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1792 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1626 浏览 1 评论
1094 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
732 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1682 浏览 2 评论
1943浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
740浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
577浏览 3评论
600浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
562浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 05:37 , Processed in 0.936643 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号