基于FPGA的串口通信,按键控制发送0~255数据

Posted 不吃土豆丝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于FPGA的串口通信,按键控制发送0~255数据相关的知识,希望对你有一定的参考价值。


前言

本实验是基于FPGA的串口通信实验。

想要完整电路图的同学可直接可加我微信:wxid_c82ezb72s7cf22或QQ:1871478767。

一、实验结果

①:串口发送0~255数据,通过按键来控制,按键每按下一次,就实现发送一次数据,并且数据加一。如下图所示:
②:和①大致一样,每次按键按下,数据就减一。如下图:

③:对于波特率,本次实验也是将其单独独立出来,用户可以随意更改,本次我采用的是9600.

二、实验步骤

本实验总共只有两个模块,一个是按键消抖模块,另一个是串口通信中的发送模块。

顶层模块

module top_uart(
      input        sys_clk,       //时钟信号50Mhz
      input        sys_rst_n,     //复位信号
      
      input        key,           //按键信号       
      output     uart_txd,                 //UART发送端口
      output   wire  key_value,
      output    wire key_flag
      );
      

assign uart_en = key_flag & (~key_value);

//*****************************************************
//**                    main code
//*****************************************************
//串口发送模块
s_c u_s_c(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    .key_value      (key_value),
    .uart_en        (uart_en),
    .uart_txd        (uart_txd )
   );

//按键消抖模块
key_debounce u_key_debounce(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .key            (key),
    .key_flag       (key_flag),
    .key_value      (key_value)
    );
    
endmodule 

串口发送模块中的累加模块

always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
       uart_din <= 8'b0;   
    else if(uart_en)
    uart_din <= uart_din + 1'd1;
    else
          uart_din <= uart_din;   
 end

之前要定义一下uart_din的位宽,我此处定义的是8位,即是最大值为255,用户可以根据自己的需要进行改动,此处不做过多的赘述。

波特率

用户可以自行更改波特率

parameter  CLK_FREQ = 50000000;          
parameter  UART_BPS = 9600;     //波特率此处更改         
localparam BPS_CNT  = CLK_FREQ/UART_BPS; 

边沿检测

//捕获uart_en上升沿,得到一个时钟周期的脉冲信号
assign en_flag = (~uart_en_d0) & uart_en;
//assign en_flag = (~uart_en_d1) & uart_en_d0;                                                 
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        uart_en_d0 <= 1'b0;                                  
        //uart_en_d1 <= 1'b0;
    end                                                      
    else begin                                               
        uart_en_d0 <= uart_en;                               
        //uart_en_d1 <= uart_en_d0;                            
    end
end

实验中遇到的问题及解决办法

我在本次实验中遇到了许多问题,但是最值得被记录的一个是这个边沿检测的时序问题。
在上述边沿检测代码中,可以看到我注释了一些,那是因为如果将uart_en打两拍之后,取//assign en_flag = (~uart_en_d1) & uart_en_d0,这个则是取第二拍,如下图所示:

图中的箭头是第一拍。
这个的结果是,发出的数据从01开始累加,而不是从00开始。
我改进的办法在上述代码中也可以看出,上时序图:

这样改进之后,就会取第一拍,就是从00开始计数了。

写在最后的话

想要完整代码的小伙伴可直接可加我微信:wxid_c82ezb72s7cf22
或者
QQ:1871478767

我现在还是一个FPGA小白,在文章中的一些地方的措辞会有一些口语化,而并不是用专业的术语,希望大家理解,相反,我个人还是有点高兴,因为如果一个知识能够用你自己的话说出来,那样对于知识的理解是非常深刻的,相信在之后的学习中,我自己会逐渐向专业靠拢,为之努力!

加油吧!打工人!!!

以上是关于基于FPGA的串口通信,按键控制发送0~255数据的主要内容,如果未能解决你的问题,请参考以下文章

开发板上的五方向按键如何通过串口控制

基于FPGA的RS232串口控制指令发送并在VGA上显示控制效果

小梅哥FPGA进阶教程第九章 基于串口猎人软件的串口示波器

FPGA 串口通信

FPGA教程案例65硬件开发板调试5——基于RS232的串口通信,由FPGA发射数据到PC

MCU与FPGA串口通信