• 正文
  • 相关推荐
申请入驻 产业图谱

自动售货机控制与倒计时显示 Verilog QuartusII

01/19 11:02
217
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

自动售货机控制与倒计时显示 Verilog QuartusII

项目信息

名称:自动售货机控制与倒计时显示 Verilog QuartusII

软件:QuartusII

语言:Verilog

代码功能

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

相关图片

开发板 (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

 

 

【来源:www.hdlcode.com

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录