这应该是最简单的处理方式了。
/**********************************
(1)实现一四人抢答器,有人抢答成功后,其他人再抢答无效;
(2)通过蜂鸣器响1秒来提示抢答成功,并在数码管上显示抢答者的序号;
(3)主持人通过按键清除抢答信息,并开始 30 秒的答题倒计时,当倒计时
结束时,通过蜂鸣器响 1 秒来提示回答问题时间到,此时可以开始新一轮的抢答
************************************/
module qiangda(rst,clk,ina,inb,inc,ind,judge,clk_1hz,wei,duan,beep,wei1,duan1,clk_1khz)
input clk,clk_1hz
input ina,inb,inc,ind,judge
output[3:0] wei
output[7:0] duan
input rst,clk_1khz
output [3:0] wei1
output [7:0] duan1
output beep
reg[3:0] wei
reg[7:0] duan
reg flag
reg [5:0] shi,ge,data
reg [4:0] count
reg [3:0] wei1
reg [7:0] duan1
reg beep
reg yu
reg [1:0] count3
always @(posedge clk)
begin
if(!rst) //系统复位,个人认为复位不够完整
begin
yu = 0
end
if(!judge) //主持人控制按键
begin
flag=0 //允许抢答
wei=4'b1111 //数码管全不亮
//【个人认为分成duan1和duan,wei1和wei的数码管数据总线不经济】
duan=8'hff
yu=1 //重新开始倒计时
end
else
begin
if(ge==6'b000000&&shi==6'b000000) //处于等待状态,实际上是等主持人按键(!judge),
else
begin
if(!ina) //若a抢答
begin
if(!flag) //若无人抢答成功
begin
wei=4'b1101
duan=8'hf9 //数码管显示1,代表a抢答成功
flag=1 //抢答标志位有效
end
end
else if(!inb) //b抢答处理电路
begin
if(!flag)
begin
wei=4'b1101
duan=8'ha4 //数码管显示2,代表b抢答成功
flag=1
end
end
else if(!inc)
begin
if(!flag)
begin
wei=4'b1101
duan=8'hb0 //数码管显示3
flag=1
end
end
else if(!ind)
begin
if(!flag)
begin
wei=4'b1101
duan=8'h99 //数码管显示4
flag=1
end
end
end
end
end
always@(posedge clk_1hz or negedge rst)
begin
if(!rst)
begin
count = 0
end
else if(count >= 5'd30) //计时达到30秒,停止计时
count = count
else if(yu==1) //触发条件yu=1时,重新开始计数【那不是变成从30开始数?感觉该段有些问题】
count = count+5'b1
end
//以下always过程块为shi和ge的译码电路,完成倒计时功能
always @(count)
begin
if(count>=5'b10101) //count>20时
begin
shi = 5'b00000 //shi=0
ge = 5'b11110-count //ge = 30-count
end
else if(count>=5'b01011) //10<count<=20时
begin
shi=5'b00001 //shi=1
ge=5'b10100-count //ge = 20-count
end
else if(count>=5'b00001) //0<count<=10时
begin
shi=5'b00010 //shi=2
ge=5'b01010-count //ge = 10-count
end
else //其它情况,i.e. count = 0
begin
shi=5'b00011 //shi=3
ge=5'b0 //ge = 0
end
end
//以下always过程块为蜂鸣器发声驱动电路
always@(posedge clk_1hz)
if(flag|(shi==0&&ge==0)) //flag==1,有人抢答成功
//shi==0&&ge==0,倒计时结束
begin //上述两种情况下蜂鸣器响一秒
if(count3==2'b1)
begin
beep<=0
count3<=count3
end
else
begin
beep<=1
count3<=count3+2'b1
end
end
else
begin
beep<=0
count3<=0
end
//以下always过程块是数码管动态刷新电路,动态显示倒计时信息(shi和ge)
always @(clk_1khz)
begin
if(!rst)
wei1 = 4'b0000
else if(clk_1khz)
begin
wei1=4'b0111
data=ge
end
else
begin
wei1=4'b1011
data=shi
end
end
always @(data) //数字显示译码,共阳极数码管(duan1)
begin
case(data)
6'b000000: duan1=8'b1100_0000
6'b000001: duan1=8'b1111_1001
6'b000010: duan1=8'b1010_0100
6'b000011: duan1=8'b1011_0000
6'b000100: duan1=8'b1001_1001
6'b000101: duan1=8'b1001_0010
6'b000110: duan1=8'b1000_0010
6'b000111: duan1=8'b1111_1000
6'b001000: duan1=8'b1000_0000
6'b001001: duan1=8'b1001_0000
default:duan1=8'b1111_1111
endcase
end
endmodule
是由代码控制的。蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此要让蜂鸣器发出不同的声音,采用 PWM 原理改变基极的脉冲宽度即可,也就是前面提到的,不同音符的一个周期所对应不同宽度脉冲。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)