扫码加入

  • 方案介绍
  • 附件下载
  • 相关推荐
申请入驻 产业图谱

自动售货机控制与倒计时显示的设计Verilog代码Quartus开发板

23小时前
253
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

2-260116163613224.docx

共1个文件

名称:自动售货机控制与倒计时显示的设计Verilog代码Quartus开发板

软件:QuartusII

语言:Verilog

代码功能

该工程实现一个简化的自动售货机逻辑:6个数码管分别显示6种商品的剩余数量(0~9),6个按键对应选择购买。选择后,LED显示当前商品价格,并启动60秒倒计时;若倒计时内收到“付款成功”信号则出货提示并将该商品数量减1;若超时则取消本次交易并回到待机。当选中商品库存为0时,通过缺货指示灯提示,避免进入付款流程。

FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com

本代码已在开发板验证,开发板如下,其他开发板可以修改管脚适配:

相关图片

开发板 (1).jpg

 

管脚.jpg

设计文档:

代码实现思路

整体采用“状态机+计时器+显示驱动”的结构。状态机分为待机/付款计时/取消/确认出货/结束回到待机等阶段:在待机阶段检测各选择键,若库存>0则锁存对应价格并进入付款计时;若库存为0则点亮缺货灯。付款计时阶段使用分频得到的节拍(工程中以计数阈值实现,可根据板卡主频调整)对BCD格式的60秒倒计时做递减,倒计时到0则进入取消流程;若检测到付款成功按键,则进入短暂等待后出货成功指示,并对选中商品库存做一次减1。显示部分将6路库存与倒计时组合成动态扫描的数码管显示,价格则用独立LED直观给出。

代码结构

顶层模块负责把按键、LED与数码管接口连起来,并把核心控制与显示拆成两个子模块:控制侧集中在state_ctrl中,完成按键有效电平处理、价格锁存、缺货判断、状态跳转、倒计时以及库存扣减;显示侧由display_num完成数码管位选/段选扫描,把6路库存与倒计时两位BCD统一显示。这种分层方式把“业务规则”和“显示驱动”解耦,后续如果更换显示器件或扩展商品数量,只需局部修改对应模块。

文件/模块一览

auto_sell_bd7auto_sell.v:auto_sell

部分代码

auto_sell_bd7state_ctrl.v

//状态控制模块          module state_ctrl(          input clk_in,//24M          input reset_n,//复位--key0          input select_1,//选择商品1--key1          input select_2,//选择商品2--key2          input select_3,//选择商品3--key3          input select_4,//选择商品4--key4          input select_5,//选择商品5--key5          input select_6,//选择商品6--key6          input confirm_key,//成功付款信号(按键)--key7          output less_led,//商品缺货指示灯--LED A7          output [3:0] need_money_led,//LED显示选中商品的价格--LED A0~A3          output reg succeed_ledn,//购买成功指示灯--LED A5          output [7:0] time_60s_bcd,          output [3:0] num_1_o,//商品1数量          output [3:0] num_2_o,//商品2数量          output [3:0] num_3_o,//商品3数量          output [3:0] num_4_o,//商品4数量          output [3:0] num_5_o,//商品5数量          output [3:0] num_6_o //商品6数量          );          wire select_1_p;//选择商品1          wire select_2_p;//选择商品2          wire select_3_p;//选择商品3          wire select_4_p;//选择商品4          wire select_5_p;//选择商品5          wire select_6_p;//选择商品6          wire confirm_p;          assign select_1_p=~select_1;          assign select_2_p=~select_2;          assign select_3_p=~select_3;          assign select_4_p=~select_4;          assign select_5_p=~select_5;          assign select_6_p=~select_6;          assign confirm_p =~confirm_key;          reg [3:0] num_1;//商品1数量          reg [3:0] num_2;//商品2数量          reg [3:0] num_3;//商品3数量          reg [3:0] num_4;//商品4数量          reg [3:0] num_5;//商品5数量          reg [3:0] num_6;//商品6数量          assign num_1_o=num_1;//商品1数量          assign num_2_o=num_2;//商品2数量          assign num_3_o=num_3;//商品3数量          assign num_4_o=num_4;//商品4数量          assign num_5_o=num_5;//商品5数量          assign num_6_o=num_6;//商品6数量          reg [2:0] state=3'd0;          parameter s_idle=3'd0;//起始状态          parameter s_coin=3'd1;//付钱状态          parameter s_coin_return=3'd2;//取消状态          parameter s_change=3'd3;//购买成功状态          parameter s_end=3'd4;//结束          parameter s_wait=3'd5;//          reg [3:0] need_money;          reg [31:0] clk_div_cnt=32'd0;          wireclk_1Hz;          reg [7:0] time_60s_count=8'd0;//60秒计数器          reg [7:0] time_change_count=8'd0;//成功          always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      clk_div_cnt<=0;                        else if(state==s_coin || state==s_change || state == s_wait)                                      if(clk_div_cnt>=32'd999)                                                    clk_div_cnt<=0;                                      else                                                    clk_div_cnt<=clk_div_cnt+31'd1;//计数                        else                                      clk_div_cnt<=0;          assign clk_1Hz = (clk_div_cnt>=32'd999) ? 1'b1 : 1'b0;          always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      succeed_ledn<=0;                        else                                      if(state==s_change)//购买成功状态                                                    succeed_ledn<=1;//购买成功,亮                                      else                                                    succeed_ledn<=0;              always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      need_money<=4'd0;                        else                                      if(state==s_idle)//选择商品                                                    if(select_1_p==1 && num_1>4'd0)                                                                  need_money<=4'd1;                                                    else if(select_2_p==1&& num_2>4'd0)                                                                  need_money<=4'd2;                                                    else if(select_3_p==1&& num_3>4'd0)                                                                  need_money<=4'd3;                                                    else if(select_4_p==1&& num_4>4'd0)                                                                  need_money<=4'd4;                                                    else if(select_5_p==1&& num_5>4'd0)                                                                  need_money<=4'd5;                                                    else if(select_6_p==1&& num_6>4'd0)                                                                  need_money<=4'd6;                                                    else                                                                  need_money<=need_money;                                      else if(state==s_end)                                                                  need_money<=4'd0;                                      else                                                    need_money<=need_money;                                                    assign need_money_led = need_money;//LED显示选中商品的价格                                                                                                                          //缺货指示          reg less_led_buf=0;          always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      less_led_buf<=1'd0;                        else                                      if(state==s_idle)//选择商品                                                    if(select_1_p==1 && num_1==4'd0)                                                                  less_led_buf<=1'd1;                                                    else if(select_2_p==1&& num_2==4'd0)                                                                  less_led_buf<=1'd1;                                                    else if(select_3_p==1&& num_3==4'd0)                                                                  less_led_buf<=1'd1;                                                    else if(select_4_p==1&& num_4==4'd0)                                                                  less_led_buf<=1'd1;                                                    else if(select_5_p==1&& num_5==4'd0)                                                                  less_led_buf<=1'd1;                                                    else if(select_6_p==1&& num_6==4'd0)                                                                  less_led_buf<=1'd1;                                                    else                                                                  less_led_buf<=1'd0;                                      else if(state==s_end)                                                                  less_led_buf<=1'd0;                                      else                                                    less_led_buf<=1'd0;                            assign less_led= less_led_buf;//输出低电平亮                                                        always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      state<=s_idle;                        else                                      case(state)                                                    s_idle://起始状态,可以选择商品价格                                                                  if(need_money>4'd0)//确认后进入付钱状态                                                                                state<=s_coin;                                                                  else                                                                                state<=s_idle;                                                    s_coin://付钱状态                                                                  if(time_60s_count==8'd0)//计时60s改小                                                                                state<=s_coin_return;//60S内不继续投币取消购买                                                                  else if(confirm_p)//支付成功                                                                                state<=s_wait;                                                                  else                                                                                state<=s_coin;                                                    s_coin_return://取消状态                                                                  state<=s_end;                                                    s_wait:                                                                  state<=s_change;                                                    s_change://购买成功状态,持续3秒                                                                  if(time_change_count>=8'd3)//d72_000_000计时3s,改小                                                                                state<=s_end;                                                                  else                                                                                state<=s_change;                                                    s_end://结束状态                                                                  state<=s_idle;                                                    default:;                                      endcase          always@(posedge clk_in or negedge reset_n)                        if(reset_n==0)                                      time_60s_count<=8'h60;                        else if(state==s_coin)begin                                                    if(clk_1Hz)                                                                  if(time_60s_count[7:4] ==4'd0 && time_60s_count[3:0] ==4'd0)                                                                                time_60s_count<=8'h00;                                                                  else if(time_60s_count[3:0] ==4'd0)                                                                                begin                                                                                              time_60s_count[7:4] <=time_60s_count[7:4] -4'd1;                                                                                              time_60s_count[3:0] <=4'd9;                                                                                end                                                                  else                                                                                begin                                                                                              time_60s_count[7:4] <=time_60s_count[7:4];                                                                                              time_60s_count[3:0] <=time_60s_count[3:0] - 4'd1;                                                                                end                                                                                                                end                        else

 

 

  • 2-260116163613224.docx
    下载

相关推荐