首页 > 其他分享 >用串口来发送信号发生器的数据

用串口来发送信号发生器的数据

时间:2024-09-07 09:36:31浏览次数:9  
标签:sys clk send 发生器 发送 go 串口 rst

一、在串口模块的基础上加一点修改

1. 这一段讲做什么

我的博客是连续剧,觉得有参考/纠错/鼓励的价值的话,我是非常期待能与大家多多交流的呀

梅哥的视频P14集,后半部分讲,能不能通过在大模块中操作一个控制信号send_go,进而影响子模块(就是串口模块,以下称串口模块)种的send_en信号,进而来操控串口发送数据的节奏呢?↓↓↓

alt text

想要在大模块中操纵send_go信号,那就需要在大模块中给send_go信号赋值。而send_go信号的变化凭借的是:信号发生器希望在哪一个时刻发送数据,这完全取决于信号发生器的设置。当然,由于我还没学到写信号发生器的模块,所以假设不随信号发生器的喜好,随我的喜好。我选择每隔10ms通过串口发送8bit数据。那么回到“send_go应该何时发送的问题”,通过分析,认为send_go每隔10ms来一个脉冲挺合适。发送流程是这样的:每隔10mssend_en拉高一个时钟周期,然后把send_go当做串口模块的输入端口,send_go一拉高,send_en就拉高,起始位、数据位、停止位,就是在send_en拉搞的时段没发送数据的。直到停止位的到来,send_en拉低。下一个send_go的到来将再次激发串口传输数据。

2. 这一段讲为什么要在这次的代码中加入r_data

大模块把data传输给串口模块,串口模块会分时刻把data传给uart_tx。这个传输的过程是one by one,说不准就会有一位受到干扰由0变1,因此,把要传的数据寄存到寄存器里面,保证传输尽量少出错。r_data就是那个寄存器。我是这样理解的。

二. 代码

1. 较之前代码的区别

大模块里加入下面这几句话

/*--------------send_en--------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if (!rst_n) begin
        send_go<=0;
    end
    else if (cnt_10ms == 1) begin
        send_go<=1'b1;
    end
    else
        send_go<=0;   
end

在串口模块里面要加入send_go如何驱动send_en:

/*-----------------------send_en-------------------------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        send_en<=32'd0;
    else if(send_go)
        send_en<=1;
    else if (tx_done)
        send_en<=0;
    else
        send_en<=send_en;
end

以及r_data

/*-----------------------r_data-------------------------------*/
always @(posedge sys_clk) begin
    if(!rst_n)
        r_data<=1'b1;
    else if (send_go)
        r_data<=data;
    else
        r_data<=r_data;
end
/*-----------

2. 完整的代码

2.1 设计代码

  • 大模块代码
module byte_send(
input sys_clk,
input rst_n,
output uart_tx
);

reg  [7:0] data        ;
reg  send_go           ;
wire tx_done          ;

send_byte s1(   
.sys_clk      (sys_clk )   ,
.rst_n        (rst_n   )   ,
.time_set     (2)   ,
.data         (data    )   ,//之前是在tb文件里面给data,send_en,现在是在顶层模块给                            
.send_go      (send_go )   ,//顶层模块就是负责给子模块赋值的
.uart_tx      (uart_tx )   ,
.tx_done      (tx_done) 
);
/*--------------变量的声明-------------------*/
reg [31:0] cnt_10ms;
parameter time_10ms = 500_000;
/*-------------- 1 0 ms ---------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_10ms<=0;
    end
    else if (cnt_10ms==time_10ms-1) begin
        cnt_10ms<=0;
    end
    else
        cnt_10ms<=cnt_10ms+1;
end
/*--------------send_en--------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if (!rst_n) begin
        send_go<=0;
    end
    else if (cnt_10ms == 1) begin
        send_go<=1'b1;
    end
    else
        send_go<=0;   
end
/*--------------data--------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if (!rst_n) begin
        data<=0;
    end
    else if (tx_done) begin
        data<=data+1;
    end
    else
        data<=data;
end
endmodule
  • 串口模块代码
module send_byte (                           
input sys_clk         ,          
input rst_n           ,          
input [2:0] time_set  ,   //基础计数器的设置       
input [7:0] data      ,          
input send_go         ,          
output reg uart_tx    ,          
output reg tx_done  
    );
/*-----------------------变量的声明-----------------------------*/
reg [31:0] cnt;//基本计数器
reg [3:0] cnt2;//2级定时器 
reg [31:0] time_cnt;
reg send_en;
reg [7:0] r_data;
/*-----------------------设置时间间隔-----------------------------*/ 
always@(*)
    if(!rst_n)
        time_cnt<=434;
    else
        case(time_set)  
            0:time_cnt<=10416;                 //4800; 
            1:time_cnt<=5208;                  //9600; 
            2:time_cnt<=434;                   //115200;
            default:time_cnt<=434;             //115200;
        endcase
/*-----------------------r_data-------------------------------*/
always @(posedge sys_clk) begin
    if(!rst_n)
        r_data<=1'b1;
    else if (send_go)
        r_data<=data;
    else
        r_data<=r_data;
end
/*-----------------------send_en-------------------------------*/
always @(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        send_en<=32'd0;
    else if(send_go)
        send_en<=1;
    else if (tx_done)
        send_en<=0;
    else
        send_en<=send_en;
end
/*-----------------------基本计数器-----------------------------*/
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        cnt<=32'd0;
    else if(send_en)
        if(cnt==time_cnt-1)
            cnt<=32'd0;
        else
            cnt<=cnt+1;
    else//!send_en
        cnt<=32'd0;     
/*-----------------------2级计数器-----------------------------*/
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        cnt2<=4'd0;//默认发start
    else if(send_en)begin
        if((cnt2>=0)&&(cnt2<10))begin
            if(cnt==time_cnt-1)
                cnt2<=cnt2+1;
            else  
                cnt2<=cnt2;
        end
        else if(cnt2==10)
            cnt2<=0;//cnt2的清0
        else  
                cnt2<=cnt2;
    end
    else //!send_en
        cnt2<=4'd0;
/*-----------------------uart_tx-----------------------------*/
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        uart_tx<=0;
    else if(send_en)
        case(cnt2)
            0: begin uart_tx<=0;  end                        
            1:  uart_tx<=r_data[0] ;                  
            2:  uart_tx<=r_data[1] ;                  
            3:  uart_tx<=r_data[2] ;                  
            4:  uart_tx<=r_data[3] ;                  
            5:  uart_tx<=r_data[4] ;                  
            6:  uart_tx<=r_data[5] ;                  
            7:  uart_tx<=r_data[6] ;                  
            8:  uart_tx<=r_data[7] ;                  
            9:  uart_tx<=1 ;       
            default:uart_tx<=1;    
        endcase
    else//!send_en
        uart_tx<=uart_tx;                                          
/*-----------------------tx_done-----------------------------*/
always@(posedge sys_clk or negedge rst_n)
    if(!rst_n)
        tx_done<=0;
    else if(cnt2==9 && cnt == time_cnt-1)                                    
            tx_done<=1;     
    else if(send_en)
            tx_done<=0;                
    else
            tx_done<=0;
endmodule          
                               

2.2 tb文件代码

`timescale 1ns/1ps
module tb ;
reg  sys_clk;
reg  rst_n;  
wire uart_tx ;

byte_send b1(
. sys_clk(sys_clk),
. rst_n  (rst_n  ),  
. uart_tx(uart_tx) 
);
/*-----------------sys_clk-----------------*/
initial 
    sys_clk=0;
    always #10 sys_clk=~sys_clk;
/*-------------------rst_n-----------------*/
initial begin
    rst_n=0;
    #201
    rst_n=1;
    #500_000_0;
    $stop;
end 


endmodule

三、仿真效果

  • 一次串口发送,显示uart_tx为
    alt text

  • 所以除去最左边的start位、最右边的stop位,发送的数据为:0000_1100
    alt text

  • 一个send_go脉冲时间为一个时钟周期:alt text

标签:sys,clk,send,发生器,发送,go,串口,rst
From: https://www.cnblogs.com/hfhfhfffhh/p/18401342

相关文章

  • jekins自动化部署完项目后发送消息到企业微信
    在上一篇文章说到了,部署一个执行远程虚拟机的脚本的item这里说一下执行完脚本后通过企业微信的群聊机器人发送消息1:安装插件 QyWechatNotification 2:在群聊新建群机器人,拿到webhook 3:jenkins具体的项目配置有中3.1:点击构建后操作,选择企业微信通知Webhook地址:填写企......
  • 串口发送数据
    一、这是一篇描述怎么用串口发送数据的文章1.设计思想稍微介绍一下这个项目想要完成的效果是:每隔10ms,用串口发送一次数据。前一个项目完成了如何用串口发送8bit,这个项目是在前一个的基础上,写一个涵盖它的大模块。大模块把send_en、data信号传给子模块,子模块有了激励信号(而不用......
  • send发送完成后测试select函数,每次都要等带20ms 实际数据在2ms内已经返回
    在发送完成后加入该函数  tcdrain(ctx->s); 使用该函数将会增加发送的时间,但是接收的时间会缩短,并未真正改善。Modbusslave工具基本上要等待40ms后才能返回,但是modbusascii返回的快一些,工具存在bug使用真实从站效果好一些      if(msg_type==1)p_......
  • 发送到PO/PI后查看报文发现会在末尾多给一个空格,后来发现基本上是数字、金额等字段,这
    PO报文发出去数字,金额等字段统统后面都会带有空格但是在abapdebugger看值看不出字段后面有空格<CGHTMXLIST><CGWXMC/><ZJTBM/><XQSL>1.000</XQSL><MEINS>XIA</MEINS><XQGJ>20000000.00</XQGJ><JHAMOUNT>20000000.00</JHAMOUNT><......
  • 浏览器串口助手插件,web版本串口调试助手浏览器插件 Web Serial Online 发布
    WebSerialOnline:串口调试的新时代在数字化不断进步的今天,开发者和工程师面对单片机如ESP8266、ESP32以及RS485设备的调试任务时,往往需要便捷而高效的工具。我们最近推出的浏览器插件——WebSerialOnline,旨在简化这一流程,提供一个无缝且直观的解决方案。即插即用的高效工具......
  • STM32 VCP串口通信 浮点数printf打印的问题 保姆级教程
    各位,我最近用STM32G474,设计一个电机驱动的电路。其中ADC采样供电电压,结果是个浮点数,想用printf打印出来看看。然而,电脑上都是USB的接口,没有串口,不想接USB转串口的芯片的话,就将STM32的USB直接配置成VCP(virtualCommunicationPort),那么,电脑就直接将USB识别为串口,直接用printf......
  • Python监控进程资源占用并发送邮件
    项目新特性上线后,有时会因为包含内存泄露的问题导致服务资源被占满,以至于线上服务崩溃。最简单的方式是对服务期CPU/内存占用进行监测和及时预警。python中pyutil包是自动化运维常用的工具库之一,可以进行方便获取服务器CPU/内存及进程等相关信息。安装方法pipinstallpsutil......
  • 在Android中发送网络请求(post和get的区别)
    get//将参数附加到URLStringurlWithParams=HttpConfig.GET_USER_NAME+"?qrCodeContent="+msg;//构建请求Requestrequest=newRequest.Builder().url(urlWithParams).addHeader("Authorization&q......
  • imap发送邮件:如何配置IMAP服务器发邮件?
    imap发送邮件的设置教程?如何使用IMAP服务发送邮件?IMAP发送邮件作为一种高效的邮件管理方式,允许用户在多个设备上同步邮件,极大地提升了工作效率。AokSend将详细介绍如何配置IMAP服务器以实现邮件的发送。imap发送邮件:选择服务在开始配置之前,需要选择一个可靠的IMAP发送邮件......
  • 什么是串口服务器?
    1.什么是串口服务器?        了解串口服务器之前,我们需要先了解什么串口。串口:又叫串行数据接口,主要是用来表示传递各种的数据的通信接口,通常指COM口。一般分为RS232、RS422、与RS485三种。RS232接口:采用全双工方式传输,传输距离约为15m。RS422接口:采用全双工方式传输......