状态机实现售货机
一、 实验目的
运用状态机实现自动售货机
1.能进行多种商品的选择,以及商品数量的选择
2.投币进行付款,可以投1元、0.5元、0.1元
3.提交后根据所付金额进行找零操作
二、 实验原理
1. 理论原理
状态机一般指有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机(英语:finite-state automaton,缩写:FSA),是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。
状态机的四个要素分别是:当前输入、当前状态、下一状态、当前输出值。而状态机状态的转化明显是由两个外部输入(时钟clock、当前输入input)进行驱动的,根据外部输入的不同就可以做出以下两种分类:
- **Moore型状态机:**输出只与当前状态有关,从另一个角度来讲,这是一个“同步”输出的状态机(synchronous machine)。
- **Mealy型状态机:**输出不仅取决于当前状态,还受到输入的直接控制,并且可能与状态无关,从另一个角度来讲,这是一个“异步”输出的状态机(asynchronous machine)。相比于Moore型状态机,Mealy型状态机需要的状态数更少,而且由于其异步特性,输出不用等待一个时钟周期,但是也是因为异步的特性其输出有可能产生毛刺,所以Mealy型的输出通常还会接一个寄存器来达到同步的效果。
本次实验我采用了混合状态机进行实现。
在状态机中有5个状态,分别是IDLE、COIN、SUBMIT、SUCCESS、FAIL。
IDLE是初始状态,在IDLE状态可以进行商品的选择与购买个数调整,通过按键key[0]能进行商品的选择,商品的价格存储在RAMIP核中,通过key[1]和key[2]可以对商品数量进行调整,key[1]按下数量增加。最大为5,10后面的数值通过16进制的A、B等显示,key[2]将当前选择的商品及商品数量得出的价格记录,用户可以选择多个商品同时付款,按下key[3]跳转到COIN状态。数码管实现显示所选商品,所选商品单价,购买数量。
COIN是投币状态,在COIN状态可以进行投币,key[2]为投币1元,key[2]为投币0.5元,key[2]为投币0.1元,按下key[3]跳转到SUBMIT状态。数码管显示商品所需总价格,所投硬币总金额
SUBMIT是判断状态,通过比较所投的金额与所需的总金额来跳转,若所投的金额大于所需的,这跳转到SUCCESS状态,否则跳转到FAIL状态。
SUCCESS是付款成功状态,进行找零操作,led灯闪烁,蜂鸣器响起两只老虎,等待4s后回到IDLE状态。数码管显示商品所需总价格,找零金额
FAIL是付款失败状态,进行退回操作,led灯从右到左依次亮起,蜂鸣器响起小星星,等待4s后回到IDLE状态。数码管显示退回金额。
商品价格存储在ram ip核中
2. 硬件原理
数码管显示原理,位选信号和段选信号都是低电平有效
蜂鸣器发声原理,低电平有效
按键原理,低电平有效
LED,高电平有效
三、 系统架构设计
四、 模块说明
1. 模块端口信号列表
顶层模块:
输入 | ||
---|---|---|
clk | 时钟 | 50MHz |
rst_n | 复位信号 | 低电平有效 |
key[3:0] | 按键信号 | 低电平有效 |
输出 | ||
---|---|---|
LED[3:0] | LED灯显示信号 | 高电平有效 |
Buzzer | 蜂鸣器发生信号 | 低电平有效 |
sel[5:0] | 数码管位选信号 | 低电平有效 |
seg[7:0] | 数码管段选信号 | 低电平有效 |
key_debounce按键消抖模块:
输入 | ||
---|---|---|
clk | 时钟 | 50MHz |
rst_n | 复位信号 | 低电平有效 |
key[3:0] | 按键信号 | 低电平有效 |
输出 | ||
---|---|---|
key_out[3:0] | 消抖后的按键信号 | 高电平有效 |
Vending售货机状态转移模块
输入 | ||
---|---|---|
clk | 时钟 | 50MHz |
rst_n | 复位信号 | 低电平有效 |
key[3:0] | 消抖后的按键信号 | 高电平有效 |
输出 | ||
---|---|---|
seg_value[24:0] | 数码管需要显示的数据 | |
dot[5:0] | 小数点显示信息 | 低电平有效 |
buzzer_en[1:0] | 蜂鸣器使能 | 高电平有效 |
seg_driver数码管显示模块
输入 | ||
---|---|---|
clk | 时钟 | 50MHz |
rst_n | 复位信号 | 低电平有效 |
seg_value[24:0] | 数码管需要显示的数据 | |
dot[5:0] | 小数点显示信息 | 低电平有效 |
输出 | ||
---|---|---|
sel[5:0] | 数码管位选信号 | 低电平有效 |
seg[7:0] | 数码管段选信号 | 低电平有效 |
buzzer_ctrl蜂鸣器控制及发声模块
输入 | ||
---|---|---|
clk | 时钟 | 50MHz |
rst_n | 复位信号 | 低电平有效 |
buzzer_en[1:0] | 蜂鸣器使能 | 高电平有效 |
输出 | ||
---|---|---|
buzzer | 蜂鸣器信号 | 低电平有效 |
2. 状态转移图
3. 时序图
vending模块时序图:
seg_driver模块时序图:
数码管控制模块时序图:
pwm_buzzer模块
五、 仿真波形图
总波形图:
IDLE状态下按键key[1]按下,购买数量增加
按键key[2]按下,summary记录当前的商品价格*商品个数的值,同时商品个数回到1。
按下key[0]切换商品种类,goods加1,ram_data改变
再次按下key[2],summary增加当前的商品价格*商品个数的值
按下key[3],从IDLE状态进入了coin状态,数码管显示同时改变为总价格,所币金额,高三位为总价格,低三位为所投金额。
当前状态下按下key[2]表示投币1元,pay_money(所付金额)增加10,数码管显示数值同时更新
按下key[0]、key[1]分别表示投币0.1和0.5元,pay_money(所付金额)增加1和5.
当按下key[3]时进入submit状态,根据所付金额与所需金额进行比较,如果所付大于等于所需则进入success状态,1s计数器开始工作,蜂鸣器开始工作,led灯开始闪烁,找零金额产生,通过数码管显示。
cnt_4s计数达最大值后,状态回到IDLE。
当所付小于所需则进入FAIL状态,计数器开始,工作退回所付金额,流水灯提示,数码管显示所推金额。cnt_4s计数达最大值后,状态回到IDLE。
六、代码
https://github.com/sunnywindow/FSM_vendring