FPGA 按键控制串口发送

按键消抖

消抖时间一般为10ms,我使用的板子是ACX720,晶振为50MHZ,20ns为一周期。

在这里插入图片描述

状态机

在这里插入图片描述

模块设计

在这里插入图片描述

设计文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/01/11 12:18:36
// Design Name: 
// Module Name: key_filter
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module key_filter(Clk,Rst_n,Key_in,Key_flag, //按键按下标志位Key_State //高电平,按键按下
);input Clk;input Rst_n;input Key_in;output reg Key_flag;output reg Key_State;parameter Filter_Time=500_000; //10mslocalparam S1=4'b0001,//按键松开S2=4'b0010,//消抖计数S3=4'b0100,//按键松开S4=4'b1000;//消抖计数//捕捉按键上升沿和下降沿reg [2:0] Pos_Neg_r;wire pos_edge;wire neg_edge;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)Pos_Neg_r<=0;else beginPos_Neg_r={Pos_Neg_r[1:0],Key_in};endendassign pos_edge=Pos_Neg_r[2:1]==2'b01;//上升沿  //按键松开assign neg_edge=Pos_Neg_r[2:1]==2'b10;//下降沿  //按键按下//消抖延迟计数器reg [18:0] counter_cnt;reg En_counter_cnt;//按键消抖计数的条件wire end_counter_cnt;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)counter_cnt<=19'd0;else if(En_counter_cnt)beginif(end_counter_cnt)counter_cnt<=19'd0;elsecounter_cnt<=counter_cnt+1'd1;endelsecounter_cnt<=19'd0;endassign end_counter_cnt=counter_cnt>=(Filter_Time-1);reg	[3:0]	cur_state;					//定义现态寄存器reg	[3:0]	next_state;					//定义次态寄存器/*-----------------------------------------------------------------------状态机第一段:同步时序描述状态转移-----------------------------------------------------------------------*/always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)cur_state <= S1;				//复位初始状态elsecur_state <= next_state;		//次态转移到现态end/*-----------------------------------------------------------------------状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出-----------------------------------------------------------------------*/always@(*)begincase(cur_state)S1:begin                    //按键松开状态if(neg_edge)            //按键按下--检测到下降沿next_state=S2;elsenext_state=cur_state;endS2:beginif(pos_edge)next_state=S1;else if(end_counter_cnt)next_state=S3;elsenext_state=cur_state;endS3:begin                    //按键按下状态if(pos_edge)            //按键松开--检测到上升沿next_state=S4;elsenext_state=cur_state;endS4:begin    if(neg_edge)next_state=S3;else if(end_counter_cnt)next_state=S1;elsenext_state=cur_state;enddefault:next_state=cur_state;endcaseend/*-----------------------------------------------------------------------状态机第三段:时序逻辑描述输出-----------------------------------------------------------------------*///消抖计数使能always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)En_counter_cnt <= 1'b0;			      //复位、初始状态 elsecase(cur_state)					      //根据当前状态进行输出S1:	En_counter_cnt <= 1'b0;		  //不计数			S2:	En_counter_cnt <= 1'b1;		  //计数S3:	En_counter_cnt <= 1'b0;		  //不计数S4:	En_counter_cnt <= 1'b1;		  //计数default:En_counter_cnt <= 1'b0;   //默认不计数endcaseend//按键按下标志位always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)Key_flag <= 1'b0;                    //复位、初始状态 //Key_State存在一拍else if(cur_state==S2 && end_counter_cnt) Key_flag<=1'd1;else Key_flag<=1'd0;end//输出按键状态always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)Key_State <= 1'b0;                    //复位、初始状态 else if(cur_state==S3) Key_State<=1'd1;else if(cur_state==S4 && end_counter_cnt)Key_State<=1'd0;elseKey_State<=Key_State;endendmodule

仿真验证

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/01/06 16:24:27
// Design Name: 
// Module Name: key_filter_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module key_filter_tb();reg Clk;reg Rst_n;reg Key_in;wire Key_flag;wire Key_State;key_filter#(.Filter_Time(5000)//100us)key_filter(Clk,Rst_n,Key_in,Key_flag, //按键按下标志位Key_State //高电平,按键按下);initial Clk=1;always #10 Clk=~Clk;initial beginRst_n=0;Key_in=1;#201;Rst_n=1;Key_in=1;#20000;Key_in=0;#20000;Key_in=1;#10000;Key_in=0;#20000;Key_in=1;#20000;Key_in=0;#600000;Key_in=1;#20000;Key_in=0;#20000;Key_in=1;#10000;Key_in=0;#20000;Key_in=1;#20000;Key_in=0;#20000;Key_in=1;#10000;Key_in=0;#20000;Key_in=1;#20000;Key_in=0;#20000;Key_in=1;#10000;Key_in=1;#600000;$stop;endendmodule

在这里插入图片描述

串口发送

**注意:**电平信号的传输线中有一个参考电平线(一般是GND),然后信号线上的信号值是由信号线电平和参考电平线的电压差决定。所以我们一定要养成模块之间共地的好习惯。

串口帧

在这里插入图片描述

模块设计

在这里插入图片描述

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/01/06 11:30:58
// Design Name: 
// Module Name: UART_Byte_Tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module UART_Byte_Tx#(parameter BaudRate = 115200,//波特率parameter ClockRate = 50_000_000//系统时钟)
(Clk,Rst_n,Send_En,data_byte,Tx_Data,Tx_Done,uart_state
);input Clk;input Rst_n;input Send_En;input [7:0] data_byte;output reg Tx_Data;output reg Tx_Done;output reg uart_state;//设置使能reg tx_en;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)tx_en<=0;else if(Send_En)tx_en<=1'd1;else if(Tx_Done)tx_en<=1'd0;elsetx_en<=tx_en;end//设置波特率localparam Buad_Num = ClockRate/BaudRate;//设置计数器reg [12:0] buad_cnt;wire add_buad_cnt;wire end_buad_cnt;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)buad_cnt<=0;else if(add_buad_cnt)beginif(end_buad_cnt)buad_cnt<=0;else buad_cnt<=buad_cnt+1'b1;endelsebuad_cnt<=0;endassign add_buad_cnt=tx_en;assign end_buad_cnt=buad_cnt>=(Buad_Num-1'd1);//设置发送bit计数reg [3:0] bit_cnt;wire add_bit_cnt;wire end_bit_cnt;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)bit_cnt<=0;else if(add_bit_cnt)bit_cnt<=bit_cnt+1'd1;else if(end_bit_cnt)bit_cnt<=0;elsebit_cnt<=bit_cnt;endassign add_bit_cnt=buad_cnt==1;assign end_bit_cnt=(bit_cnt==4'd10 && add_bit_cnt) || !tx_en;//发送数据always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)Tx_Data<=1;else begincase(bit_cnt)4'd1:Tx_Data<=0;4'd2:Tx_Data<=data_byte[0];4'd3:Tx_Data<=data_byte[1];4'd4:Tx_Data<=data_byte[2];4'd5:Tx_Data<=data_byte[3];4'd6:Tx_Data<=data_byte[4];4'd7:Tx_Data<=data_byte[5];4'd8:Tx_Data<=data_byte[6];4'd9:Tx_Data<=data_byte[7];4'd10:Tx_Data<=1;default:Tx_Data<=1;endcaseendend//发送结束always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)Tx_Done<=0;else if(bit_cnt==4'd10 && add_bit_cnt)Tx_Done<=1;elseTx_Done<=0;end//发送状态(有效数据)wire En_uart_state;wire Nen_uart_state;always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)uart_state<=0;else if(En_uart_state)uart_state<=1;else if(Nen_uart_state)uart_state<=0;endassign En_uart_state=bit_cnt==4'd1 && add_bit_cnt;assign Nen_uart_state=bit_cnt==4'd9 && add_bit_cnt;endmodule

仿真验证

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/01/06 11:31:09
// Design Name: 
// Module Name: UART_Byte_Tx_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module UART_Byte_Tx_tb();reg Clk;reg Rst_n;reg Send_En;reg [7:0]data_byte;wire Tx_Data;wire Tx_Done;wire uart_state;initial Clk=1;always #10 Clk=~Clk;initial beginRst_n=0;Send_En=0;data_byte=0;#201;Rst_n=1;data_byte=8'b1001_0110;Send_En=1;#20;Send_En=0;#100000;data_byte=8'b0111_0110;Send_En=1;#20;Send_En=0;#100000;$stop;endUART_Byte_Tx UART_Byte_Tx(.Clk(Clk),.Rst_n(Rst_n),.Send_En(Send_En),.data_byte(data_byte),.Tx_Data(Tx_Data),.Tx_Done(Tx_Done),.uart_state(uart_state));endmodule

在这里插入图片描述

按键控制串口发送

RTL视图

在这里插入图片描述

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/01/07 13:43:42
// Design Name: 
// Module Name: Uart_Key_Send_cmd
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module Uart_Key_Send_cmd(Clk,Rst_n,Key_in,uart_tx
);input Clk;input Rst_n;input Key_in;output uart_tx;//按键模块wire Key_flag;wire Key_State;key_filter key_filter(Clk,Rst_n,Key_in,Key_flag, //按键按下标志位Key_State //高电平,按键按下);//串口发送reg [7:0] data_byte;wire Tx_Done;wire uart_state;//assign data_byte=8'b0100_0001; //发送Aalways@(posedge Clk or negedge Rst_n)beginif(!Rst_n)  data_byte<=8'b0100_0001; //发送Aelse if(Tx_Done)data_byte<=data_byte+1'b1;//数据加一endUART_Byte_Tx UART_Byte_Tx(.Clk(Clk),.Rst_n(Rst_n),.Send_En(Key_flag),.data_byte(data_byte),.Tx_Data(uart_tx),.Tx_Done(Tx_Done),.uart_state(uart_state));endmodule

板级验证

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/520370.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Effective C++ 学习笔记 条款16 成对使用new和delete时要采取相同形式

以下动作有什么错&#xff1f; std::string *stringArray new std::string[100]; // ... delete stringArray;每件事看起来都井然有序&#xff0c;使用了new&#xff0c;也搭配了对应的delete。但还是有某样东西完全错误&#xff1a;你的程序行为未定义。至少&#xff0c;str…

Flink实时数仓之用户埋点系统(一)

需求分析及框架选型 需求分析数据采集用户行为采集业务数据采集 行为日志分析用户行为日志页面日志启动日志APP在线日志 业务数据分析用户Insert数据用户Update数据 技术选型Nginx配置Flume配置MaxWellHadoopFlink架构图 需求分析 数据采集 用户行为采集 行为数据&#xff1…

LabVIEW智能Modbus监控系统

LabVIEW智能Modbus监控系统 在自动化和信息化迅速发展下&#xff0c;传统的监控系统已无法满足现代工业对于数据通讯和处理的高效率和高可靠性要求。为了解决这一问题&#xff0c;设计了一套基于LabVIEW的智能Modbus监控系统。该系统利用LabVIEW的图形化编程环境和Modbus协议的…

关于汽车E\E架构演进的思考(2)

目录 1.概述 2. 整车通信的限制 3 如何保证融合ECU的功能安全和信息安全 4.小结 1.概述 上篇文章主要聊了当前电子电气架构以及未来电子电气架构的特点&#xff0c;简述了即将要面临的挑战&#xff0c;下面我们继续讲述挑战。 2. 整车通信的限制 下一代架构主要以以太网…

Android将自己写的maven库上传至jitpack(2024靠谱版)

浏览了一堆陈年旧贴&#xff0c;终于实验成功了 第一步 将自建空项目同步至github并保证能正常运行第二步新增一个library类型的modul第三步 在新建的library里面写一些测试用的代码第四步在library的gradle文件增加插件和发布脚本第五步新建一个配置文件第六步 把所有更改push…

万物皆可Find My,伦茨科技ST17H6x芯片赋能产品苹果Find My功能

苹果的Find My功能使得用户可以轻松查找iPhone、Mac、AirPods以及Apple Watch等设备。如今Find My还进入了耳机、充电宝、箱包、电动车、保温杯等多个行业。苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、Ai…

uniapp封装文字提示气泡框toolTip组件

uniapp封装文字提示气泡框toolTip组件 文字提示气泡框&#xff1a;toolTip 因为uniapp 中小程序中没有window对象&#xff0c;需手动调用 关闭 第一种办法关闭&#xff1a;this.$refs.tooltip.close() 第二种办法关闭&#xff1a;visible.sync false 移动端没有现成的toolTip组…

浮点数和定点数

前言 大家好我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第七篇,在这里分享给大家,还有一些书籍《深入理解计算机系统》《计算机组成&#xff1a;结构化方法》《计算机体系结构&#xff1a;量化研究方法》&#xff0c;今天我们来了解定点数和浮点数 定点数 BCD编码 …

ffmpeg maxrate 导致转码输出的内容包含随机性

https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate 问题 领导提出了一个问题&#xff0c;为什么转码后的视频大小字节数据都不一样&#xff0c;这问到我了&#xff0c;一时语塞。查一下吧&#xff0c;没有什么资料支撑。主动试一下。 尝试 首先尝试一下直接…

Java_排序

文章目录 一、排序的概念二、常见的排序算法三、常见排序算法的实现1.插入排序1、基本思想2、直接插入排序3、希尔排序&#xff08;缩小增量排序&#xff09; 2.选择排序1、基本思想2、直接选择排序2、堆排序 3.交换排序1、冒泡排序2、快速排序3、快速排序优化4、快速排序非递归…

JVM-垃圾收集器

名词解释 并行和并发 并行与并发在垃圾回收上的含义 并行&#xff08;Parallel&#xff09;&#xff1a;指多条垃圾收集线程并行工作&#xff0c;但此时用户线程仍然处于等待状态。并发&#xff08;Concurrent&#xff09;&#xff1a;指用户线程与垃圾收集线程同时执行&…

网络编程(3/6)

使用C语言完成数据库的增删改 #include<myhead.h> int do_add(sqlite3 *ppDb) {int numb;char name[50];int salary;printf("请输入员工信息&#xff1a;工号、姓名、薪水\n");scanf("%d %s %d",&numb,name,&salary);char sql[128];char *e…