串口应用:发送数据

这篇具有很好参考价值的文章主要介绍了串口应用:发送数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

功能描述:

1.每隔3ms以115200波特率的速度发送一个遵循uart协议的数据。每次发送数据增大1(从0开始即可).

2.数据 来自数据采集器,每采集一个数据,发送一个脉冲告知串口,串口对这个数据进行发送。

学习:

1.在上一次底层设计中,我们把发送使能端send_en作为input,不能在底层为它赋值。但是我们在顶层新建一个模块,调用底层模块时,可以把send_en作为顶层的内部变量,这样子就可以赋值了。

2.如果触发条件是脉冲的,我们可以设计一个内部变量en,用脉冲把en置一,让它控制数据发送的使能。再用结束位置零。这样子在外部上看就起到了用脉冲触发的效果。

3.用顶层调用底层时(例化)在顶层中同样是设计逻辑,用到与底层同个变量时,顶层和底层的逻辑是并行执行的。只不过变量在两个地方的地位不一样,在底层中无法赋值的input,在顶层中可以作为可赋值的reg。

4.可以用x=!x把x置为脉冲型。

5.调试的基本思路是:查看仿真波形,看哪个变量的波形不对劲,回到源码中找到该变量的逻辑语句进行分析。一般先看关键变量的波形,具体来说就是输出的波形是否与预期相符。再由输出推到与其联系的相关变量的逻辑。

6.最好每一个变量都用独立的always来描述逻辑变化。文章来源地址https://www.toymoban.com/news/detail-480654.html

  • 1
module uart_1(  //设计输入
    clk,//时钟
    reset,//复位
    data,//数据
    send_en,//使能
    baud_rate,//波特率
    uart_tx,//串口输出
    tx_done//结束信号
);
    input clk;
    input reset;
    input [7:0]data;
    input send_en;
    input [2:0]baud_rate;
    output reg uart_tx;
    output reg tx_done;
    
     reg [17:0]bit_tim;
    
    //设计逻辑
    //把波特率转化为一位的持续时间  //单位时间内通过信道传输的码元数称为码元传输速率,即波特率,码元/s,一个码元可能由多个位组成。而比特率即 ‘位/s’
    always@(baud_rate)  //在这里一个 码元由一位组成,所以波特率=比特率
        begin
            case(baud_rate)         //常见的串口传输波特率
            3'd0 : bit_tim = 1000000000/300/20 ; //波特率为300
            3'd1 : bit_tim = 1000000000/1200/20 ; //波特率为1200
            3'd2 : bit_tim = 1000000000/2400/20 ; //波特率为2400
            3'd3 : bit_tim = 1000000000/9600/20 ; //波特率为9600
            3'd4 : bit_tim = 1000000000/19200/20 ; //波特率为19200
            3'd5 : bit_tim = 1000000000/115200/20 ; //波特率为115200
            default bit_tim = 1000000000/9600/20 ;   //多余的寄存器位置放什么:默认速率
            endcase
        end
    
    reg [17:0]counter1 ;//用来计数每一位的持续时间
    always@(posedge clk or negedge reset)
        begin
            if(!reset)//复位清零
                counter1 <=17'b0 ;
            else if (send_en )//使能端有效,计数
                begin
                if( counter1 == bit_tim - 1'b1 )//位持续时间到达时归零
                    counter1 <= 17'b0 ;
                else
                    counter1 <= counter1 + 1'b1 ;//位持续时间没达到时继续进行
                end
            else counter1 <= 17'b0 ;            //使能端无效时,清零
        end 
    
    reg [3:0]counter2 ; //输出第几位。如果忘了考虑归零,那么计数器会出现溢出归零,在这里是加到15然后归零
    always@(posedge clk or negedge reset)
        begin
            if(!reset)//复位
                counter2 <= 4'b0 ;
            else if ( send_en )//使能端有效
                begin
                if(counter2 == 0)//消耗20ns,进入起始位。这个挺重要的,没有这个的话得消耗一位的时间进入起始位
                    counter2 <= counter2 +1'b1 ;
                else if( counter1 == bit_tim - 1'b1 )//开始进行位移
                    counter2 <= counter2 + 4'b1 ;   
                else
                    counter2 <= counter2 ;
                end
            else//使能端无效,归零,进入空闲位
                counter2 <= 4'b0 ;    
        end                

    always@(posedge clk or negedge reset)
        begin
            if(!reset)//复位
                begin
                    uart_tx <= 4'b1 ; 
                end  
            else if ( send_en )//使能端有效,输出每一位
                    case(counter2)
                        0:begin uart_tx <= 1'b1 ; end//设定第一位为空闲位。没有空闲位的话,使能端无效时,counter停留在0,不能保持输出高电平(取决于要输出的数据),不符合要求。
                        1:uart_tx <= 1'b0 ;//起始位
                        2:uart_tx <= data[0] ;
                        3:uart_tx <= data[1] ;
                        4:uart_tx <= data[2] ;
                        5:uart_tx <= data[3] ;
                        6:uart_tx <= data[4] ;
                        7:uart_tx <= data[5] ;
                        8:uart_tx <= data[6] ;
                        9:uart_tx <= data[7] ;
                        10:uart_tx <= 1'b1 ;//结束位
                        11:begin uart_tx <= 1'b1 ;  end//为了让结束位跑满,设置11,作为第11个点,定第十位长度。
                        default uart_tx <= 1'b1 ;
                    endcase
           else 
                uart_tx <= 1'b1 ;         
        end 
        
        always@(posedge clk or negedge reset)
        begin
            if(!reset)//复位清零
                tx_done <= 1'b0 ;
            else if (send_en )//使能端有效
                begin
                if( counter2 == 0 )//
                     tx_done <= 1'b0 ;
                else if ( counter2 == 11 )
                     tx_done <= 1'b1 ;
                end
            else if (tx_done == 1'b1)
                tx_done <= 1'b0 ;
        end 
endmodule
module uart_2(//使能端信号为电平型
    Clk,
    Reset,
    uart_tx
    );

    input Clk ;
    input Reset ;
    reg [7:0]data ;
    reg send_en ;
    wire [2:0]baud_rate ;
    output wire uart_tx ;
    wire tx_done ; 
    
    uart_1 uart_1_send(  //设计输入
        .clk(Clk),//时钟
        .reset(Reset),//复位
        .data(data),//数据
        .send_en(send_en),//使能
        .baud_rate(baud_rate),//波特率
        .uart_tx(uart_tx),//串口输出
        .tx_done(tx_done)//结束信号
    );  

    assign baud_rate = 3'b101 ;
    
    reg [18:0]counter ;
    
    always@(posedge Clk or negedge Reset)
        begin
            if(!Reset)//复位清零
                counter <= 1'd0 ;
            else if (counter == 19'd149000 )//
                counter <= 1'b0 ;//
            else 
                counter <= counter + 1'b1 ;    
        end 
        
    always@(posedge Clk or negedge Reset)
        begin
            if(!Reset)//复位清零
                send_en <= 1'd0 ;
            else if (counter == 19'd1 )//
                send_en <= 1'b1 ;//
            else if  (tx_done == 1'b1 )//
                send_en <= 1'b0 ;
        end 
        
    always@(posedge Clk or negedge Reset)
        begin
            if(!Reset)//复位清零
                 data <= 8'd0 ;
            else if (counter == 19'd149000 )//
                begin
                 data <= data + 1'b1 ;               
                end
            else
                 data <= data ;//
        end 

endmodule
module uart_3(//使能端信号为脉冲型
    Clk,
    Reset,
    send_pulse,
    data1,
    uart_tx
    );

    input Clk ;
    input Reset ;
    input send_pulse ;
    input [7:0]data1 ;
    output wire uart_tx ;
    
    wire tx_done ; 
    reg send_en ;
    wire [2:0]baud_rate ;
    wire [7:0]data ;
    
    uart_1_1 uart_1_1send(  //设计输入
        .clk(Clk),//时钟
        .reset(Reset),//复位
        .data(data),//数据
        .send_en(send_en),//使能
        .baud_rate(baud_rate),//波特率
        .uart_tx(uart_tx),//串口输出
        .tx_done(tx_done)//结束信号
    );  

    assign baud_rate = 3'b101 ;
    assign data = data1 ;
    reg [18:0]counter ;
    
    always@(posedge Clk or negedge Reset)
        begin
            if(!Reset)//复位清零
                counter <= 1'd0 ;
            else if (counter == 19'd149000 )//
                counter <= 1'b0 ;//
            else 
                counter <= counter + 1'b1 ;    
        end 
        
    always@(posedge Clk or negedge Reset)
        begin
            if(!Reset)//复位清零
                send_en <= 1'd0 ;
            else if (send_pulse == 1'd1 )//
                send_en <= 1'b1 ;//
            else if  (tx_done == 1'b1 )//
                send_en <= 1'b0 ;
        end 
        

endmodule
`timescale 1ns / 1ns

module uart_3_tb ();
    reg Clk ;
    reg Reset ;
    reg send_pulse;
    reg [7:0]data1 ;
    wire uart_tx ;
    
    uart_3 uart_3_sim(
    .Clk(Clk),
    .Reset(Reset),
    .send_pulse(send_pulse),
    .data1(data1),
    .uart_tx(uart_tx)
    );

    initial Clk = 1 ;
    always #10 Clk = ! Clk ;
    initial 
        begin
        Reset = 0 ;
        data1 = 8'b0 ;
        send_pulse = 1'b0 ;
        #201 ;
        Reset = 1 ;
        data1 = 8'b0110_1001 ;
        send_pulse = 1'b1 ;
        #20
        send_pulse = !send_pulse  ;
        #3100000 ;
        data1 = 8'b1001_1101 ;
        send_pulse = 1'b1 ;
        #20
        send_pulse = !send_pulse  ;
        #3100000 ;
        $stop ;
        end
        
endmodule
 
                    

到了这里,关于串口应用:发送数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenMV:23串口发送数据

    本节讲解 如何使用OpenMV通过串口来发送数据 OpenMV 是可以直接通过串口发送字符串的。 为什么要用串口呢?因为要时候需要把信息传给其他MCU(单片机),串口简单,通用,基本每一个MCU都会有串口。 TTL串口至少需要3根线: TXD,RXD,GND 。 TXD是发送端 , RXD是接收端 , GN

    2024年02月15日
    浏览(80)
  • SpringBoot+jSerialComm实现Java串口通信 读取串口数据以及发送数据

    记录一下使用SpringBoot+jSerialComm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作,在win和linux系统都是可以的,有一点好处是不需要导入额外的文件。 案例demo源码:SpringBoot+jSerialComm实现Java串口通信 读取串口数据以及发送数据 之前使用RXTXcomm实现Java串口通信,这

    2024年02月05日
    浏览(42)
  • SpringBoot+RXTXcomm实现Java串口通信 读取串口数据以及发送数据

    记录一下使用SpringBoot+RXTXcomm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作。 案例源码:SpringBoot+RXTXcomm实现Java串口通信 读取串口数据以及发送数据 RXTXcomm.jar这个包支持的系统较多,但是更新太慢,在win系统下使用没有问题,但是在centos的工控机系统里使用

    2024年02月04日
    浏览(41)
  • 单片机通过串口向电脑端发送数据&&电脑端发送数据控制led

    上节课我们学习了串口的理论部分,这节课我们要来学习实操部分。 要想实现单片机通过串口向电脑端发送数据,我们首先要来配置寄存器。 1.配置SCON SCON寄存器中的SM0配置为0,SM1配置为1决定了串口工作在模式一,也就是 8位UART, 波特率可变的工作模式。REN置1表示能接收

    2023年04月21日
    浏览(43)
  • C#串口通信从入门到精通(26)——多个串口多个线程发送数据和接收数据

    我们在开发串口程序的过程中有时候会遇到多个串口,并且多个串口也需要在多个线程进行操作,本文就来讲解如何实现多个串口在多线程下的安全发送与接收。 我们首先使用虚拟串口助手虚拟COM1、COM2这一对串口;COM3、COM4这一对串口,然后使用代码操作COM1,然后打开一个

    2024年02月11日
    浏览(63)
  • Unity串口通信、接受和发送数据、C#

    串行接口(串口)通常指COM接口,是采用串行通信方式的扩展接口。串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。特别适用于远距离通信。 查看串口:右键 我的电脑-管理-设备管理器

    2023年04月13日
    浏览(55)
  • 串口发送数据,只接收到00的原因之一

    1、环境: STM32F103RCT6 KEIL 5 2、现象: 不管我发送任何类型的数据,在串口助手上显示接收到的都是00, 我头很大,去网上找了别人的代码对比检查。 终于,细心的我发现,原来粗心的我少了一行代码。 3、解决方案1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); 好了,加上这一行

    2024年02月12日
    浏览(98)
  • Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述

    Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述。三种描述方式抽象级别不同,各有优缺点,相辅相成,需要配合使用。 目录 一、结构化描述 1、概念 2、特点 3、示例 真值表: 电路抽象:

    2024年02月04日
    浏览(67)
  • 最详细STM32,cubeMX串口发送,接收数据

    这篇文章将详细介绍 串口 发送数据,接受数据。 实验开发板:STM32F103C8T6。 所需软件:keil5 , cubeMX 。 实验目的:了解 串口的基础知识,掌握串口如何发送,接收数据 。 实验:串口发送数据点亮 led。 如果想了解串口的基础知识可以参考我之前的文章: STM32Cube串口USART发送

    2024年02月04日
    浏览(74)
  • C51单片机串口发送数据的使用

             假如说电路板上没有CH340芯片,我们就要使用TTL转USB模块来进行电平的转换,然后将模块的RX接单片机的TX,模块的TX接单片机的RX,来进行接线连接。          在连接好连线后,我们打开计算机管理,来查看端口是否存在,如果没有,我们需要下载CH340驱动,

    2024年02月03日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包