module seg(
input clk,
input[1:0] key,
output reg[7:0] segment,
output reg[2:0] wei,
output reg PWM
);
reg clk_key;
reg[14:0] segment_scancnt;
reg[22:0] key_count;//2^23=8_388_608
reg[6:0] dis;//2^7=128
reg[12:0] key_cnt = 2400,cnt;//2^13=8192
parameter PWM_cnt = 4800;//10kHz
parameter div_key = 5_280_000;//--->T=220ms
always @(posedge clk)//按键消抖时钟
begin
if(key_count == div_key)
begin
key_count <= 0;
clk_key <= ~clk_key;
end
else
key_count <= key_count + 1'b1;
end
always @(posedge clk_key)//按键+/-
begin
if(key == 2'b01)
begin
key_cnt = key_cnt + 6'd48;//百分之一可调
end
if(key == 2'b10)
begin
key_cnt = key_cnt - 6'd48;//百分之一可调
end
if(key_cnt > PWM_cnt)
begin
key_cnt = 0;
end
if(key_cnt == 13'd8192)
begin
key_cnt = PWM_cnt;
end
end
always @(posedge clk)//分频10kHz-PWM波
begin
if(cnt >= PWM_cnt)
begin
cnt = 0;
end
if(cnt < key_cnt)
begin
PWM = 1;
end
else
PWM = 0;
cnt = cnt + 1'b1;
end
always @(posedge clk)
begin
segment_scancnt <= segment_scancnt + 1'b1;
end
always @(segment_scancnt)//位选扫描
begin
case(segment_scancnt[14:13])
2'b00:
wei <= 3'b011;
2'b01:
wei <= 3'b101;
2'b10:
wei <= 3'b110;
default:wei <= 3'b111;
endcase
end
always @(wei)//段选
begin
case(wei)
3'b011:
segment <= display(key_cnt/48/100);
3'b101:
segment <= display(key_cnt/48%100/10);
3'b1110:
segment <= display(key_cnt/48%10);
default:segment <= display(key_cnt%10);
endcase
end
function[7:0] display;//其中不能包含非阻塞赋值
input[3:0] number;
case(number)
4'b0000:display = 8'b00111111;
4'b0001:display = 8'b00000110;
4'b0010:display = 8'b01011011;
4'b0011:display = 8'b01001111;
4'b0100:display = 8'b01100110;
4'b0101:display = 8'b01101101;
4'b0110:display = 8'b01111101;
4'b0111:display = 8'b00000111;
4'b1000:display = 8'b01111111;
4'b1001:display = 8'b01101111;
default:display = 8'b00000000;//共阴极数码显示
endcase
endfunction
endmodule