Vivado 串口通信(UART)原理A ------串口发送实验

Vivado 摸鱼记录 Day_8  (*'▽'*)♪

review

         day_7 阻塞赋值与非阻塞赋值 Vivado Verilog 阻塞赋值与非阻塞赋值-CSDN博客

         day_6  day_5的补充 Vivado 从计数器到可控线性序列机 B-CSDN博客

         day_5  从计数器到可控线性序列机 A  Vivado 从计数器到可控线性序列机 A-CSDN博客

         day_4  参数化设计 Vivado 时序逻辑 点灯带师 流水灯 参数化-CSDN博客

         day_3  实现单个led Vivado 时序逻辑 计数器-CSDN博客

         day_2  译码器 Vivado 3-8译码器 4-16译码器-CSDN博客

         day_1  Vivado使用流程  Vivado 使用流程 二选一数据选择器-CSDN博客

1.串口通信(UART)原理

        小梅哥视频链接12A_什么是UART串口_哔哩哔哩_bilibili

        通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART)是一种异步收发传输器,其在数据发送时将并行数据转换成串行数据来传输,在数据接收时将接收到的串行数据转换成并行数据,可以实现全双工传输和接收。它包括了 RS232、RS449、RS423、RS422RS485等接口标准规范和总线标准规范。

1.1 串口发送模块

        串口发送模块接口列表:

 1.2 串口发送小结

        由此可以得知,编写串口通信时:

        输入信号包括:

                1. 时钟clk  复位reset_n

                2.波特率baud_set   

                3.数据 data

        输出信号包括:

                1. uart_tx

2. 今日摸鱼任务

        分析:输入 :bps = 9600 ;  1000,000,000 /9600 /20 = 5208 

        分析串口数据可以看:一文读懂串口(波形分析、起始位、数据位、停止位、空闲位)_串口数据位-CSDN博客

        对于本实验实现串口通信,需要uart_tx满足:

        起始位(1'b0) + 数据位(8bit) + 校验位(无) + 停止位(1'b1)

         这样看来,就与day_6 T6比较接近啦(*'▽'*)♪Vivado 从计数器到可控线性序列机 B-CSDN博客

3. design sources

module UART_tx(input clk , input reset_n , input [7:0]data , 
               output reg uart_tx , output reg LED  );
    // To :  every second  send SW[7:0]
    //    bps = 9600  发送完成后 ,停止发送
    // 发送完成后 LED = ~LED
    parameter start_bit = 0 ;
    parameter stop_bit  = 1 ;
    parameter bps = 9600 ;
    parameter [12:0]bps_c = 5208;   
    parameter time_every = 1000000000/20;   


    //大框架 : 1s
    reg [31:0] counter_second ;
    always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            counter_second <= 0 ;
        else if (counter_second == time_every-1)
            counter_second <= 0 ;
        else
            counter_second <= counter_second + 1'b1 ;


     // send_en
      reg  send_en;
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            send_en <= 1 ;
        else if (counter_second == time_every-1 || counter_second < bps_c *
10 )
            send_en <= 1 ;
        else
            send_en <= 0 ;


      // bps 9600 104.166 us
      reg [12:0] counter_bps ;        
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            counter_bps <= 0 ;
        else if (counter_second == time_every-1)
            counter_bps <= 0 ;
        else if (send_en)
            if(counter_bps == bps_c - 1)
                counter_bps <= 0 ;
            else
                counter_bps <= counter_bps + 1'b1 ;
        else
            counter_bps <= 0 ;

            
      // 发送状态
      reg [3:0] tx_flag;
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            tx_flag <= 0 ;
        else if(counter_second == time_every-1)
             tx_flag <= 0 ;
        else if (!send_en) tx_flag <= 0 ;
        else
            if(counter_bps == bps_c - 1)
                tx_flag <= tx_flag + 1'b1 ;
    //  tx_flag          
       always@(*)
       if(!send_en) uart_tx <= 1'b1;  //空闲状态置1
       else
        begin 
            case(tx_flag)
            4'b0000 : uart_tx <= start_bit;
            4'b0001 : uart_tx <= data[0];
            4'b0010 : uart_tx <= data[1];
            4'b0011 : uart_tx <= data[2];
            4'b0100 : uart_tx <= data[3];
            4'b0101 : uart_tx <= data[4];
            4'b0110 : uart_tx <= data[5];
            4'b0111 : uart_tx <= data[6];
            4'b1000 : uart_tx <= data[7];
            4'b1001 : uart_tx <= stop_bit;
            default : uart_tx <= uart_tx;
            endcase
            
        end      
     // LED反转
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            LED <= 0 ;
        else if (send_en)
            if(counter_second == 10 * bps_c - 1)
                LED <= ~LED ;

输入信号 input clk , input reset_n , input [7:0]data 

输出信号 output reg uart_tx , output reg LED

标志位    start_bit = 0 ; stop_bit  = 1
波特率   parameter bps = 9600 ;
    parameter [12:0]bps_c = 5208;   

1s   send_en  bps 9600 104.166 us 

同day_6 T6  Vivado 从计数器到可控线性序列机 B-CSDN博客

 send_en

 else if (counter_second == time_every-1 || counter_second < bps_c * 10 )
            send_en <= 1 ;

10代表着 : 起始位(1'b0) + 数据位(8bit) + 校验位(无) + 停止位(1'b1)    每个周期内共10bit

发送状态  reg [3:0] tx_flag;  0~9需要四位表示

                 case(tx_flag) 要考虑10~15不包含所以 default : uart_tx <= uart_tx;

空闲状态  if(!send_en) uart_tx <= 1'b1; 置1

4.  UART_tx_tb

`timescale 1ns / 1ns
module UART_tx_tb();
    reg clk ,reset_n ;
    reg [7:0]data;
    wire uart_tx , LED;
    UART_tx#(.time_every(100000))
     uart_tx_1(.clk(clk) , .reset_n(reset_n) , .data(data) ,
               .uart_tx(uart_tx) , .LED(LED)  );
    initial clk = 1 ;
    always #10 clk = ~clk ;
    initial
    begin
        data = 8'b0110_1001;
        reset_n = 0 ;
        #201;
        reset_n = 1 ;       
        # 10000000;
        data = 8'b0101_0101;
        # 10000000;
        $stop;
    end
    
endmodule
UART_tx#(.time_every(100000))  时间间隔 2ms

        data = 8'b0110_1001;

        data = 8'b0101_0101;

5. 串口调试结果

6. 小结

        哒哒哒~ 串口这里要学会起始位(1'b0) + 数据位(8bit) + 校验位(无) + 停止位(1'b1)

        (真正的勇士敢于边调试边找问题T^T)

//好啦,摸鱼结束啦(*'▽'*)♪

  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Vivado 是一种集成设计环境,用于进行FPGA和SoC的设计和开发。在 Vivado 中实现 UART 串口通信需要进行以下几个步骤: 1. 创建工程:在 Vivado 中创建一个工程,并选择目标设备。 2. 添加模块:创建一个新的 Verilog 或 VHDL 模块来实现 UART 通信功能。这个模块将负责处理 UART 协议,并与其他模块进行数据交换。 3. IP 核配置:在 Vivado 中添加一个 IP 核,来实现 UART 控制器。可以选择现有的 UART IP 核,或者根据需要自定义一个。 4. 连接模块和 IP 核:使用 Vivado 的连接编辑器将自定义模块和 UART IP 核进行连接,以便数据传输和控制。 5. 约束文件设置:创建一个约束文件,对 I/O 端口进行约束和引脚映射。 6. 综合和实现:运行综合和实现过程,将设计映射到目标设备上。 7. 配置串口参数:在 SDK(Software Development Kit)中配置串口通信的参数,如波特率、数据位数、校验位等。 8. 软件开发:使用 C 或 C++ 编程语言编写软件来实现 UART 通信的逻辑。可以使用 SDK 提供的串口库函数来进行数据的发送和接收操作。 9. 编译和生成可执行文件:在 SDK 中编译软件代码,并生成可烧录到目标设备上的可执行文件。 10. 下载和调试:通过 JTAG 或者其他下载方式将可执行文件下载到目标设备上,并进行调试和验证。 通过以上步骤,就可以在 Vivado 中实现 UART 串口通信功能。使用自定义的模块和 UART IP 核,可以灵活地实现各种不同需求的串口通信功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值