09自动售货机综设实验(含按键消抖,led和状态机)
一设计功能
1.上次状态机的练习
|
2这次自动售货机综设
|
(一)对比两次的售货机
上次售货机的关键是画出状态转移图。明确输入分几种,输出是啥,有哪些状态。如下图所示
(二)系统或综合设计的经验:
既然这次的综设,在上次的售货机基础上,加了流水灯,按键等模块。那么根据模块化设计,那我先做核心模块,再做功能模块,然后再连接好各个模块,实现系统功能。
我的经验:做过录音机综设实验,当时先做串口通信模块,再做LED实现多种功能模块,然后再把录音机模块做好,最后利用控制信号把这三大模块组合起来。利用拆分—设计—验证,模块化设计思路。
- 设计方法
关键是照图施工。
即一般做一个系统设计,都是先按照功能划分出几个大致的模块,然后画出系统框图。根据框图,找出核心模块,对于一个模块,也是照图施工,即先画出它的模块框图,时序图或状态转移图,然后根据图纸描述模块。
|
- 系统框图
当然咯,这个系统框图是最好完成设计后,我再画出的。实际的动手过程:第一是先看了设计功能,大致晓得有三个模块,即按键模块,LED灯模块,售货机的状态机模块,也感觉到售货机的状态机模块是核心。
第二:A:在草稿纸画出三个模块的大致框图,并没有连接他们,因为当时也很茫然,一片混乱。B:然后就直接先做售货机的状态机模块,直接在上次的售货机程序上加了两个状态,还有把输出改了一下。C:接着我就做LED模块,从设计功能推出,有三个功能模式,即按下按键亮一个灯或两个;单向流水灯;双向流水灯;我又想起来上次录音机录音与回放实验中,LED灯功能比这个多得多,所以就看了上次录音机的LED模块的设计:由一个输入控制信号的不同值,来给led灯不同功能的标志信号,再由标志信号驱动LED灯实现不同功能。即一个控制信号的不同值对应LED灯的不同功能。
|
最后就是对按键模块的设计,我刚开始很模糊怎么调用按键消抖,实现按键1和按键2按下;还加了三个按键的程序,即按键消抖,按键的组合模块,按键的控制模块,哈哈哈,太有趣了。
实际上,按键的调用:一是有一个按键消抖模块(消抖),一个按键控制模块(实现按键功能),再把消抖模块的输出标志(如Pin_out)作为按键控制模块的输入,而按键控制模块的输出可以作为其他功能模块的输入,如售货机的状态机模块,最后就是在顶层模块例化按键消抖和按键控制即可。如这次的两个按键,只需要把按键消抖例化两次,把按键消抖例化1和例化2的输出标志分别接上,按键控制的按键1和按键2输入端口,再把按键消抖例化1和例化2的输入KEY1 和KEY2和顶层的输入按键连起来就行。
二设计输入
我个人觉得这次LED灯模块,很值得品味一下。它有三种不同的显示状态,而LED却都是那四个,怎么避免对同一变量多次赋值和竞争冒险,还有就是在同一个模块实现多种功能。
(一)LED灯部分
module Water_led( input wire clk, input Rst, input wire [2:0]led_state, output reg [3:0]led ); reg [3:0]rled; //复位时的LED灯寄存器 reg [3:0]rled0; //按键按下亮一个或两个的LED灯寄存器 reg [3:0]rled1; //单向流水灯的LED灯寄存器 reg [3:0]rled2; //双向流水灯的LED灯寄存器 reg en_led1; //单向流水灯的标志信号 reg en_led2;//双向流水灯的标志信号 //200ms timer parameter T200MS = 24'd9_999_999; reg [23:0]div_cnt; always@(posedge clk or negedge Rst) if(!Rst)begin div_cnt<=24'd0; end else if(div_cnt==T200MS)begin div_cnt<=24'd0; end else begin div_cnt<=div_cnt+1'b1; end //用输入控制信号的不同值拉高不同的LED功能的标志信号 //最终实现不同的LED功能 always@(posedge clk or negedge Rst) if(!Rst)begin rled<=4'b0000; end else begin case(led_state) 0:begin rled0<=4'b0000; end 1:begin rled0<=4'b0001; end 2:begin rled0<=4'b0011; end 3:begin rled0<=4'b0111; end 4:begin rled0<=4'b1111; end 5:begin en_led1<=1'b1; end 6:begin en_led2<=1'b1; end endcase end //单向流水灯 always@(posedge clk or negedge Rst) if(!Rst)begin rled1<=4'b0001; end else if(en_led1)begin if(div_cnt==T200MS)begin rled1<={rled1[2:0],rled1[3]}; end else begin rled1<=rled1; end end else begin rled1<=rled1; end //双向流水灯 reg double_led; always@(posedge clk or negedge Rst) if(!Rst)begin rled2<=4'b0001; double_led<=0; end else if(en_led2)begin case(double_led) 0:if(div_cnt==T200MS)begin rled2<={rled2[2:0],rled2[3]}; end else if(rled2==4'b1000)begin double_led<=1'b1; rled2<=rled2; end 1:if(div_cnt==T200MS-1)begin rled2<={rled2[0],rled2[3:1]}; end else if(rled2==4'b0001)begin double_led<=1'b0; rled2<=rled2; end endcase end //the mean to avoid the multiple values by selector always@(*)begin if(Rst==0) led = rled; else if(led_state<3'd5) led = rled0; else if(led_state==3'd5) led = rled1; else if(led_state==3'd6) led = rled2; else led = rled; end endmodule |
通过上面的设计代码,我们清晰得知道了上面提出的那两个问题的答案:通过对不同的LED功能定义一个寄存器且在输出时利用选择器使得在同一时刻,只有一个赋值输出。而实现不同的功能,通过输入控制信号的不同拉高不同LED灯的标志信号,再利用标志信号驱动LED实现不同的功能。
(二)按键控制模块
按键控制模块的功能:按键1按下表示投入5毛,按键2按下表示投入1快,再把这两个的输出传递给售货机的状态机模块。
讲哈,我刚开看到这个按键功能的想法,给按键1和按键2分别给一个输出标志,来表示按键1和按键2按下,但我后面看到售货机的状态机模块输入只有一个,若是再加一个感觉有点麻烦,想想还是算了。那么怎么用一个标志信号来表示两个输入的值。
哈哈哈哈,我想到了设置一个2bit的输出标志,第零位表示按键1的值,第一位表示按键2的值。
第二个问题,怎么解决按键1按下和按键2按下给不同的值到输出标志?
方法是,用组合逻辑的assign语句实现。
assign po_money =(key1_in==1)?2'd1:(key2_in==1)?2'd2:2'd0; |
没错哈按键控制模块就是只有一句这么简单。
(三)顶层模块
`timescale 1ns/1ns `define clk_period 20 module top( input wire sclk, input Rst_n, input wire key_sw1, input wire key_sw2, output wire [3:0]LED ); wire key1_money; wire key2_money; wire [1:0]kmoney; wire [2:0]led_flag; //例化售货机 fsm inst_fsm ( .clk (sclk), .rst_n (Rst_n), .pi_money (kmoney), .po_led (led_flag) ); //例化LED Water_led inst_Water_led ( .clk(sclk), .Rst(Rst_n), .led_state(led_flag), .led(LED) ); //按键按下的例化 key_ctrl inst_key_ctrl ( .key1_in(key1_money), .key2_in(key2_money), .po_money(kmoney) ); //按键消抖的例化 key_filter inst_key1 ( .clk(sclk), .Rst(Rst_n), .Key1(key_sw1), .Pin_out(key1_money) ); //例化按键2 key_filter inst_key2 ( .clk(sclk), .Rst(Rst_n), .Key1(key_sw2), .Pin_out(key2_money) ); endmodule |
由于按键消抖和状态机设计模块,在前面两次实验中,我已经做了详细分析,这次就不再赘述。
三仿真波形
在仿真模块,我是按照拆分--设计—验证的步骤。即每做一个设计模块,先把语法错误等解决了,然后根据设计功能进行仿真,若仿真没问题,再做下一个模块,直到所有模块的仿真没问题,我再把所有模块组合连接起来在顶层,最后我就是对顶层进行仿真,若仿真没问题,再建立工程,关键约束,下载到开发板验证实验现象。
`timescale 1ns/1ns `define clk_period 20 module top_tb(); reg sclk; reg Rst_n; reg key1_in; reg key2_in; wire [3:0]po_led; initial sclk = 1; always#(`clk_period/2) sclk =~sclk; initial begin Rst_n = 0; key1_in=1'b0;key2_in=1'b0; #(`clk_period*20)key1_in=1'b1; Rst_n = 1;key2_in=1'b1; #(`clk_period*15)key2_in=1'b1; #(`clk_period*15)key1_in=1'b0; #(`clk_period*14)key1_in=1'b1; key2_in=1'b1; #(`clk_period*15)key2_in=1'b0; key1_in=1'b1; #(`clk_period*15)key2_in=1'b1; key1_in=1'b1; #(`clk_period*15)key2_in=1'b1; key1_in=1'b0; #(`clk_period*15); key1_in=1'b1; key2_in=1'b1; #(`clk_period*15)key2_in=1'b0; #(`clk_period*15)key2_in=1'b1; #(`clk_period*802)key2_in=1'b1; key1_in=1'b1; #(`clk_period*100)key2_in=1'b0; #(`clk_period*100); Rst_n = 0;#(`clk_period*20); //第二次仿真单向流水灯 key1_in=1'b1; Rst_n = 1;key2_in=1'b1; #(`clk_period*15)key2_in=1'b1; #(`clk_period*15)key1_in=1'b0; #(`clk_period*14)key1_in=1'b1; key2_in=1'b1; #(`clk_period*15)key2_in=1'b0; key1_in=1'b1; #(`clk_period*15)key2_in=1'b1; key1_in=1'b1; #(`clk_period*15)key2_in=1'b1; key1_in=1'b0; #(`clk_period*15); key1_in=1'b1; key2_in=1'b1; #(`clk_period*15)key1_in=1'b0; #(`clk_period*15)key1_in=1'b1; #(`clk_period*802)key2_in=1'b1; key1_in=1'b1; $stop; end top inst_top ( .sclk(sclk), .Rst_n(Rst_n), .key_sw1(key1_in), .key_sw2(key2_in), .LED(po_led) ); endmodule 从图中得知,LED在按键控制下可以实现,亮一个或两个,单向流水灯,双向流水灯。 |
我这次的经验是:
第一点:每个模块都要进行仿真,所有模块仿真没问题,再按照图纸连接各个模块,最后建立顶层和对顶层进行仿真。第二点:仿真的设计,主要是贴近设计功能,如按键1按下亮一个,那就模拟按键1按下;若是流水灯每亮一个需要200ms那么仿真时间也需要大于这个时间。第三点是全面,如按键1和按键2按下,还有单向和双向流水灯等都要仿真。
09自动售货机综设实验(含按键消抖,led和状态机)的更多相关文章
- 我的 FPGA 学习历程(11)—— 实验:按键消抖
按键是一个输入设备,在理论上可以归为开关一类,理想的按键波形如下: 然而由于按键的机械特性,断开和闭合动作是不可能在一瞬间完成的,实际的波形如下: 抖动期间电平处于临界值,由于晶振的频率相当的高,数字 ...
- 玩转华为物联网IoTDA服务系列三-自动售货机销售分析场景示例
场景简介 通过收集自动售货机系统的销售数据,EI数据分析售货销量状况. 该场景主要描述的是设备可以通过MQTT协议与物联网平台进行交互,应用侧可以到物联网平台订阅设备侧变化的通知,用户可以在控制台或通 ...
- 开发实践丨用小熊派STM32开发板模拟自动售货机
摘要:本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代码,通过云端开发和设备终端开发,实现终端数据在的华为云平台显示. 本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代 ...
- 使用NewLife网络库构建可靠的自动售货机Socket服务端(一)
最近有个基于tcp socket 协议和设备交互需求,想到了新生命团队的各种组件,所以决定用NewLife网络库作为服务端来完成一系列的信息交互. 第一,首先说一下我们需要实现的功能需求吧 1,首先客 ...
- YTU 2598: 编程题B-小平智斗自动售货机
2598: 编程题B-小平智斗自动售货机 时间限制: 1 Sec 内存限制: 128 MB 提交: 268 解决: 69 题目描述 LYH自动售货机在销售商品时,具有自动找钱功能.但是找零的最小单 ...
- 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...
- 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...
- Verilog HDL那些事_建模篇笔记(实验三:按键消抖)
实验三:按键消抖 首先将按键消抖功能分成了两个模块,电平检查模块和10ms延迟模块.电平检测模块用来检测按键信号的变化(是否被按下),10ms延迟模块用来稳定电平检查模块的输入,进而稳定按键信号,防止 ...
- C#骏鹏自动售货机接口
MachineJP类: 第1部分:串口初始化,串口数据读写 using System; using System.Collections.Generic; using System.IO.Ports; ...
随机推荐
- 框架5--nginx安装部署 下(web服务)
目录 1.提纲 2.Nginx虚拟主机 3.Nginx日志 4.Nginx访问控制模块 5.Nginx状态监控模块 6.访问连接控制模块 框架5--nginx安装部署 下(web服务) 1.提纲 1. ...
- CPU使用率过高怎么办
实际上前文中关于CPU使用率过高如何通过各种工具获得相关的热点进程.那么进程有了,那得疑惑到底哪个哪段代码导致了这个进程成为热点呢? 如果在调试阶段,可以使用gdb中断运行,但是在生产环境肯定不行.L ...
- 图解python | 面向对象编程
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/56 本文地址:http://www.showmeai.tech/article-det ...
- VMware vSphere,ESXi和vCenter的关系和区别
VMware Inc.是一家软件公司.它开发了很多产品,尤其是各种云解决方案 .他的云解决方案包括云产品,数据中心产品和桌面产品等. vSphere是在数据中心产品下的一套软件.vSphere类似微软 ...
- 【windows 操作系统】什么是窗口?|按钮也是窗口
起因 在看操作系统消息机制的时候,看到一句化:全局消息队列把消息发送到窗口所在的线程消息队列.突然就怀疑起了窗口的意思.于是就有这边基类. 文章来源:https://docs.microsoft.co ...
- Python:list和ndarray的互相转化
a=np.arange(9).reshape(3,3) #a是一个3*3的array #array -> list l=a.tolist() [[0, 1, 2], [3, 4, 5], [6, ...
- tensorflow_keras_预训练模型_Applications接口的使用
在很多复杂的计算机视觉问题上,我们需要使用层次相对较深的卷积神经网络才能得到好结果,但是自己从头去构建卷积神经网络是一个耗时耗力的事情,而且还不一定能训练好.大家通常用到最多的技巧是,使用" ...
- Java中常用的加密方式(附多个工具类)
一.Java常用加密方式 Base64加密算法(编码方式) MD5加密(消息摘要算法,验证信息完整性) 对称加密算法 非对称加密算法 数字签名算法 数字证书 二.分类按加密算法是否需要key被分为两类 ...
- 初识python(2)
目录 引言 数据类型 字典 集合 元组 布尔值 用户交互 格式化输出 运算符 增量赋值 链式赋值 交叉赋值 解压赋值 逻辑运算符 成员运算符 身份运算符 引言 小伙伴们昨天已经讲了一点python的数 ...
- Tableau学习Step4一数据解释、异常值监测、参数使用、分析结果如何对外发布
Tableau学习Step4一数据解释.异常值监测.参数使用.分析结果如何对外发布 本文首发于博客冰山一树Sankey,去博客浏览效果更好. 一. 前言 本教程通过一个案例从浅到深来学习Tableau ...