logo资料库

自动售卖机verilog语言程序代码.docx

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
//输入 50MHz 时钟信号 //输出控制红灯 //输出控制小数点 module shen(key,clock,outstate,seg_date,seg_com,L1,L2,L3,L4,p); input [1:0]key;//key[0]表示投入 5 角的开关,key[1]表示投入 1 元的开关 input clock ; reg [1:0]currentstate,nextstate;// currentstate 表示现态,nextstate 表示次态 output reg outstate; output reg p; output reg L1,L2,L3,L4;//红灯辅助控制电路 output reg [7:0]seg_date; output reg[3:0] seg_com; reg outnext; reg [2:0]x1,x2,x3,x4; reg [2:0]y1,y2,y3,y4; reg[31:0] reg[2:0] scan_led_com; reg clk_500Hz,clk_scan; reg i; reg counter; reg [2:0]shujv; reg [1:0] in; reg [1:0] in_flag; reg [3:0] count; //段选 //位选 DCLK_DIV,DCLK_DIV1; /***主功能实现函数***/ always @(posedge clk_500Hz) begin L1=0; L2=1; L3=1; L4=1; if(currentstate==0)//状态为 S0 begin if(~in[0]) //投入 5 角,低电平为有效信号 begin if(~in_flag[0])//in_flag[0]标志位防止低电平期间重复计数 begin nextstate=1;//次态变成 S1 outnext=0; //无饮料输出 //第一位数码管应该显示的数据 0 y1=3'b000; //第二位数码管应该显示的数据 5 y2=3'b101; //第三位数码管应该显示的数据 0 y3=3'b000; y4=3'b000; //第四位数码管应该显示的数据 0 in_flag[0]=1;
end end else if (~in[1]) //投入 1 元,低电平为有效信号 begin if(~in_flag[1])//in_flag[1]标志位防止低电平期间重复计数 begin nextstate=2;//次态变成 S2 //无饮料输出 outnext=0; //第一位数码管应该显示的数据 1 y1=3'b001; //第二位数码管应该显示的数据 0 y2=3'b000; y3=3'b000; //第一位数码管应该显示的数据 0 y4=3'b000; //第一位数码管应该显示的数据 0 in_flag[1]=1; end end else//未投币 begin nextstate=0; outnext=0; y1=3'b000; y2=3'b000; y3=3'b000; y4=3'b000; in_flag[0]=0; in_flag[1]=0; end //保持 S0 状态 //无饮料输出 //第一位数码管应该显示的数据 0 //第二位数码管应该显示的数据 0 //第三位数码管应该显示的数据 0 //第四位数码管应该显示的数据 0 end if(currentstate==1) //状态为 S1 begin if(~in[0]) begin if(~in_flag[0]) begin nextstate=2;//次态变成 S2 outnext=0; y1=3'b001; y2=3'b000; y3=3'b000; y4=3'b000; in_flag[0]=1; end //无饮料输出 //第一位数码管应该显示的数据 1 //第二位数码管应该显示的数据 0 //第三位数码管应该显示的数据 0 //第四位数码管应该显示的数据 0 end else if (~in[1]) begin
if(~in_flag[1]) begin nextstate=0;//次态变成 S0 outnext=1; y1=3'b001; y2=3'b101; y3=3'b000; y4=3'b000; in_flag[1]=1; end //有饮料输出 //第一位数码管应该显示的数据 1 //第二位数码管应该显示的数据 5 //第三位数码管应该显示的数据 0 //第四位数码管应该显示的数据 0 end else begin nextstate=1;//保持 S1 状态 outnext=0; y1=3'b000; y2=3'b101; y3=3'b000; y4=3'b000; in_flag[0]=0; in_flag[1]=0; end //无饮料输出 //第一位数码管应该显示的数据 0 //第二位数码管应该显示的数据 5 //第三位数码管应该显示的数据 0 //第四位数码管应该显示的数据 0 end if(currentstate==2) begin if(~in[0]) begin if(~in_flag[0]) begin nextstate=0;//次态变成 S0 outnext=1; //有饮料输出 y1=3'b001;//第一位数码管应该显示的数据 1 y2=3'b101;//第二位数码管应该显示的数据 5 y3=3'b000;//第三位数码管应该显示的数据 0 y4=3'b000;//第四位数码管应该显示的数据 0 in_flag[0]=1; end end else if(~in[1]) begin if(~in_flag[1]) begin nextstate=0;//次态变成 S0 //有饮料输出 outnext=1;
y1=3'b010;//第一位数码管应该显示的数据 2 y2=3'b000;//第二位数码管应该显示的数据 0 y3=3'b000;//第三位数码管应该显示的数据 0 y4=3'b101;//第四位数码管应该显示的数据 5 in_flag[1]=1; end end else begin nextstate=2;//保持 S2 状态 outnext=0;//无饮料输出 y1=3'b001;//第一位数码管应该显示的数据 1 y2=3'b000; y3=3'b000; y4=3'b000; in_flag[0]=0; in_flag[1]=0; end //第二位数码管应该显示的数据 0 //第三位数码管应该显示的数据 0 //第四位数码管应该显示的数据 0 end end /***消抖程序***/ always @ (posedge clk_500Hz) begin if((~key[0]) ||( ~key[1])) //判断是否有按键按下 begin if(count==10) //延时 20ms 消除抖动 begin 的判断 in[0]=key[0]; //此时 key 值为稳定状态复值给 in 进行主函数 in[1]=key[1]; count=0; end else count=count+1; end else begin in[0]=1;//否则 in 为高电平不能进入主程序 in[1]=1; end end /***扫描数码管**/
always @(posedge clk_scan) if(scan_led_com<3) begin scan_led_com = scan_led_com + 1;//循环扫描 4 位数码管 else scan_led_com = 0; end /********状态转换***/ always @(posedge clk_500Hz) begin currentstate<=nextstate; outstate<=outnext; end //将前面主程序执行的结果进行状态转换 /**时钟分频 2.5Khz,用来扫描数码管**/ always @(posedge clock) begin if(DCLK_DIV < 10_000) begin DCLK_DIV <= DCLK_DIV+1'b1; else DCLK_DIV <= 0; clk_scan <= ~clk_scan; end end /****分频 500hz,用来检测按键****/ always @(posedge clock) begin if(DCLK_DIV1 < 50_000) begin DCLK_DIV1 <= DCLK_DIV1+1'b1; else DCLK_DIV1 <= 0; clk_500Hz <= ~clk_500Hz; end end /**数码管显示***/ always @(posedge clk_scan) begin //2.5KHz case(scan_led_com) //循环扫描 4 个 LED,共阳极 3'b000: seg_com=8'b00000001; //扫描第一位数码管 3'b001: seg_com=8'b00000010; 3'b010: seg_com=8'b00000100; 3'b011: seg_com=8'b00001000; default: seg_com=8'b00000000; endcase //扫描第三位数码管 //扫描第四位数码管 //扫描第五位数码管 //扫描第二位数码管
case(scan_led_com)//位选 3'b000: begin shujv<=y1;p=0;end 3'b001:begin shujv<=y2;p=1;end 3'b010: begin shujv<=y3;p=0;end 3'b011: begin shujv<=y4;p=1;end endcase case(shujv) //段选 //扫描第一位数码管时把数据赋值给 shujv //扫描第二位数码管时把数据赋值给 shujv //扫描第三位数码管时把数据赋值给 shujv //扫描第四位数码管时把数据赋值给 shujv 3'b000:seg_date=7'b1000000;//显示 0 3'b001:seg_date=7'b1111001;//显示 1 3'b010:seg_date=7'b0100100;//显示 2 3'b101:seg_date=7'b0010010;//显示 5 default: seg_date=7'b0000000; endcase end endmodule
分享到:
收藏