36.UART(通用异步收发传输器)-RS232(3)

news2024/9/20 15:03:34

(1)串口发送模块visio视图:

(2)串口发送模块Verilog代码:

/*
常见波特率: 4800、9600、14400、115200
在系统时钟为50MHz时,对应计数为:   
(1/4800)    * 10^9 /20 -1 = 10416     
(1/9600)    * 10^9 /20 -1 = 5207
(1/14400)   * 10^9 /20 -1 = 3471
(1/115200)  * 10^9 /20 -1 = 433 
*/

module rs232_tx
(
    input   [16:0]  baud_set        ,
    input           clk             ,
    input           reset_n         ,
    input   [7:0]   tx_data         ,
    input           tx_start        ,
    
    output   reg    tx              ,
    output   reg    tx_done            
    
);
    
    reg [15:0]      BAUD_MCNT       ;
    reg [7:0]       r_tx_data       ;
    reg             en_baud_cnt     ;
    reg [15:0]      baud_cnt        ;
    reg [3:0]       bit_cnt         ;
    
    
//波特最大计数设计
    always@(posedge clk)
            begin
                case(baud_set)
                    17'd4800    :BAUD_MCNT <= 16'd10416;
                    17'd9600    :BAUD_MCNT <= 16'd5207;
                    17'd14400   :BAUD_MCNT <= 16'd3471;
                    17'd115200  :BAUD_MCNT <= 16'd433;
                    default     :BAUD_MCNT <= 16'd5207;      //当输入baud_set为其他值时,一律当成9600处理。
                endcase
            end
    
//输入信号同步化处理
    always@(posedge clk)
        if(tx_start)
            r_tx_data <= tx_data;
        else
            r_tx_data <= r_tx_data;
        
//波特率计数器使能信号设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            en_baud_cnt <= 1'd0;
        else if(tx_start)
            en_baud_cnt <= 1'd1;
        else if((bit_cnt == 4'd9)&&(baud_cnt == BAUD_MCNT))
            en_baud_cnt <= 1'd0;
        else 
            en_baud_cnt <= en_baud_cnt;
        
//波特率计数器模块设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            baud_cnt <= 16'd0;
        else if(!en_baud_cnt)
            baud_cnt <= 16'd0;
        else if(baud_cnt == BAUD_MCNT)
            baud_cnt <= 16'd0;
        else 
            baud_cnt <= baud_cnt + 16'd1;
            
//位计数器模块设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)    
            bit_cnt <= 4'd0;
        else if((baud_cnt == BAUD_MCNT) && (bit_cnt == 4'd9))
            bit_cnt <= 4'd0;
        else if(baud_cnt == BAUD_MCNT)
            bit_cnt <= bit_cnt + 4'd1;
        else 
            bit_cnt <= bit_cnt;
            
//tx输出序列机设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            tx <= 1'd1;
        else if(!en_baud_cnt)
            tx <= 1'd1;
        else if(baud_cnt == 16'd1)begin
            case(bit_cnt)
                4'd0:   tx <= 1'd0;
                4'd1:   tx <= r_tx_data[0];
                4'd2:   tx <= r_tx_data[1];
                4'd3:   tx <= r_tx_data[2];
                4'd4:   tx <= r_tx_data[3];
                4'd5:   tx <= r_tx_data[4];
                4'd6:   tx <= r_tx_data[5];
                4'd7:   tx <= r_tx_data[6];
                4'd8:   tx <= r_tx_data[7];
                4'd9:   tx <= 1'd1;
                default:tx <= 1'd1;
            endcase
        end
        else 
            tx <= tx;
            
//tx_done信号设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            tx_done <= 1'd0;
        else if((baud_cnt == BAUD_MCNT) && (bit_cnt == 4'd9))
            tx_done <= 1'd1;
        else 
            tx_done <= 1'd0;
       
endmodule

(3)串口发送模块仿真代码:

`timescale 1ns / 1ps

module rs232_tx_tb;

reg     [16:0]      baud_set    ; 
reg                 clk         ;     
reg                 reset_n     ;
reg     [7:0]       tx_data     ;  
reg                 tx_start    ;

wire                tx          ;
wire                tx_done     ;

initial clk = 1'd1;
always #10 clk = ~clk;

initial begin
    baud_set <= 17'd9600;
    reset_n <= 1'd0;
    tx_data <= 1'd0;
    tx_start <= 1'd0;
    #21;
    reset_n <= 1'd1;
    #40;
    @(posedge clk);
    //输入数据0
    tx_data <= 8'd0;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据1
    tx_data <= 8'd1;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据2
    tx_data <= 8'd2;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据3
    tx_data <= 8'd3;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据4
    tx_data <= 8'd4;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据5
    tx_data <= 8'd5;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据6
    tx_data <= 8'd6;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据7
    tx_data <= 8'd7;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    $stop;
end

rs232_tx rs232_tx_inst
(
    .baud_set       ( baud_set)        ,
    .clk            ( clk     )        ,
    .reset_n        ( reset_n )        ,
    .tx_data        ( tx_data )        ,
    .tx_start       ( tx_start)        ,
    
    .tx             ( tx      )        ,
    .tx_done        ( tx_done )           
    
);

endmodule

(4)仿真波形:

同时,可以看见,tx一开始被赋予了高电平,在波特计数器计数为1,起始位时被拉低。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1936073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙语言基础类库:【@system.vibrator (振动)】

振动 说明&#xff1a; 本模块首批接口从API version 4开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。从API Version 8开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.vibrator]。该功能使用需要对应硬件支持&#xff0c;仅支持…

学生信息管理系统-优化版

springbootthymeleafmybatis 记录一下闲来无事&#xff0c;将之前做的1.0页面优化。 一、【管理员】首页 1、增加了【批量删除】、【导出学生信息】、【分页】、【统计及格率、平均分、优秀率】等功能。 2、将页面样式优化了一下&#xff0c;做的好看些 原来&#xff1a; 现…

.NET C# 配置 Options

.NET C# 配置 Options 使用 options 模式可以带来许多好处&#xff0c;包括清晰的配置管理、类型安全、易于测试和灵活性。但在使用过程中&#xff0c;也需要注意配置复杂性、性能开销和依赖框架等问题。通过合理设计和使用&#xff0c;可以充分发挥 options 模式的优势&#…

【链表】算法题(二) ----- 力扣/牛客

一、链表的回文结构 思路&#xff1a; 找到链表的中间节点&#xff0c;然后逆置链表的后半部分&#xff0c;再一一遍历链表的前半部分和后半部分&#xff0c;判断是是否为回文结构。 快慢指针找到链表的中间节点 slow指针指向的就是中间节点 逆置链表后半部分 逆置链表后半部分…

【JavaScript 算法】图的遍历:理解图的结构

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、深度优先搜索&#xff08;DFS&#xff09;深度优先搜索的步骤深度优先搜索的JavaScript实现 二、广度优先搜索&#xff08;BFS&#xff09;广度优先搜索的步骤 三、应用场景四、总结 图的遍历是图论中的基本操作之一&am…

安卓 mvp 的架构的详细介绍

MVP 架构介绍 MVP&#xff08;Model-View-Presenter&#xff09;是一种软件架构模式&#xff0c;常用于构建用户界面&#xff08;UI&#xff09;。它将应用程序的逻辑划分为三个部分&#xff1a;Model、View 和 Presenter。MVP 的主要目标是分离视图和业务逻辑&#xff0c;使代…

ECU通讯:CAN总线仿真测试

01.ECU 在软件定义汽车的大背景下&#xff0c;几乎每一个汽车功能都需要依靠ECU&#xff08;Electronic Control Unit&#xff0c;电子控制单元&#xff09;来实现&#xff1a;有些功能靠ECU独立实现&#xff0c;有些功能则需要多个ECU联合实现。总体来说&#xff0c;ECU绝大多…

解决SonarQube中Vue项目中deep选择器报错的问题

1. 前言 当使用SonarQube对Vue项目进行代码质量审查时&#xff0c;可能会遭遇因Vue特有的deep选择器&#xff08;旨在实现样式深度穿透&#xff09;而触发的错误或警告。由于SonarQube默认并不识别这一Vue特有的语法&#xff0c;这些错误报告可能会成为审查过程中的干扰项。为了…

Mysql sql技巧与优化

1、解决mysql同时更新、查询问题 2、控制查询优化 hint 3、 优化 特定类型的查 优化 COUNT() 查询 使用 近似值 业务能接受近似值的话&#xff0c;使用explain拿到近似值 优化关联查询 优化子查询 4、优化group by和distinct 优化GROUP BY WITH ROLLUP 5、优化 limit分页 其他…

【MySQL-19】一文带你了解存储函数

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

Richteck立锜科技电源管理芯片简介及器件选择指南

一、电源管理简介 电源管理组件的选择和应用本身的电源输入和输出条件是高度关联的。 输入电源是交流或直流&#xff1f;需求的输出电压比输入电压高或是低&#xff1f;负载电流多大&#xff1f;系统是否对噪讯非常敏感&#xff1f;也许系统需要的是恒流而不是稳压 (例如 LED…

应届生软件测试面经_一名应届生的软件测试面试题目

1.你为什么选择软件测试行业 因为之前有了解软件测试这个行业&#xff0c;觉得他的发展前景很好&#xff0c; 2.根据你以前的项目经验描述一下软件开发、测试过程&#xff0c;由那些角色负责&#xff0c;你做什么 要有架构师、开发经理、测试经理、程序员、测试员。我在里面…

什么是死锁 , 以及产生的原因详细介绍

死锁 一. 什么是死锁 指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁, 通俗的说死锁产生的原因主要是由于线程的相互等待 , 导致程序无法进行下去 二. 代码阐述 这里我们写…

科技论文在线--适合练习期刊写作和快速发表科技成果论文投稿网站

中国科技论文在线这个平台可以作为练手的一个渠道&#xff0c;至少可以锻炼一下中文写作&#xff0c;或者写一些科研方向的简单综述性文章。当然&#xff0c;如果你的老师期末要求也是交一份科技论文在线的刊载证明的话&#xff0c;这篇文章可以给你提供一些经验。 中国科技论…

数据结构 - 队列(精简介绍)

文章目录 单端队列单端队列操作&#xff1a;Queue实现 双端队列双端队列操作&#xff1a;Deque实现 循环队列循环队列手动实现 优先级队列Q 不断取最大礼物并开方 单端队列 普通队列为单端队列&#xff0c;先进先出&#xff08;FIFO&#xff09; 只能从尾部插入&#xff0c;头…

jscolor 赋值input 没能引起前边色框的颜色变化

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

操作系统内核源码杂谈篇:临界区

临界资源&#xff0c;是指同一时刻只能由一个线程&#xff08;linux下为进程&#xff09;访问的资源&#xff0c;而临界区就是为了确保临界资源访问是单一数据流。 临界区的代码执行&#xff0c;也就是进行原子操作&#xff0c;不会被打断。 先分析RTOS的运行架构&#xff0c…

35道最新【软件测试】面试题,常见面试题及答案汇总

前言 除了掌握扎实的专业技能之外&#xff0c;你还需要一份《软件测试面试宝典2024版》才能在万千面试者中杀出重围&#xff0c;成功拿下offer。 小编特意整理了35道测试必问必过面试题&#xff0c;送给大家&#xff0c;希望大家都能顺利通过面试&#xff0c;拿下高薪。赶紧码…

ngnix添加自定义模块

参考如下的 示例: hello handler 模块 部分&#xff0c; handler模块(100%) — Nginx开发从入门到精通 参考&#xff1a; 【Nginx】Nginx新增自定义模块_nginx 自定义模块-CSDN博客 需要详细说明的是&#xff0c; 创建一个addtion_module文件夹&#xff0c;将.c文件放进去&…

应急靶场(6):Linux1

目录 黑客的IP地址遗留下的三个flag 第一个flag第二个flag第三个flag 下载好靶场&#xff08;应急响应靶机-Linux(1)&#xff09;并搭建好环境&#xff0c;使用帐号密码&#xff08;defend / defend&#xff09;登录靶机&#xff0c;然后使用su root命令和帐号密码&#xff08;…