当前位置:首页 » 《随便一记》 » 正文

基于FPGA的串口通信,按键控制发送0~255数据_不吃土豆丝的博客

5 人参与  2021年12月17日 13:08  分类 : 《随便一记》  评论

点击全文阅读


文章目录

  • 前言
    • 本实验是基于FPGA的串口通信实验。
  • 一、实验结果
  • 二、实验步骤
    • 顶层模块
    • 串口发送模块中的累加模块
    • 波特率
    • 边沿检测
  • 实验中遇到的问题及解决办法
  • 写在最后的话


前言

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

加油吧!打工人!!!


点击全文阅读


本文链接:http://zhangshiyu.com/post/31685.html

实验  模块  波特率  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1