TA的每日心情 | 开心 2019-11-19 11:07 |
---|
签到天数: 226 天 连续签到: 1 天 [LV.7]常住居民III
|
【MAXII_EPM240T100_CPLD】实验五 8只数码管显示计数器
创建工程:shumagTest;文件夹:shumagTest;顶层工程文件:shumagTest;工程名称:shumagTest;
子模块2个:计数控制模块:countCtrl;数码管设置模块:paraOpti;
数码设置模块有3个子程:数码管控制:paraCtrl;数码管编码:paraCode;数码管扫描:paraScan;
牵涉到的PIN:数码管扫描COM_PIN:95,92,89,87,85,83,78,77。数码管段码PIN:91,90,88,86,84,82,81,76。需要关闭的LED_PIN:49,50,51,52,53,54,55,56——不是必须的。
当然还是拿来主义,按照实际修改一下适合实际开发板——我的开发板有8只数码管,管脚完全不一样,可能改动非常大,已有心理准备,下边开始编程。
一、主模块shumagTest——就是顶层描述文档,只连接了2个子模块
module shumagTest(
input CLK,
input RSTn,
output [7:0]SMG_Data, //8段数码管段选
output [7:0]Scan_Sig, //8个数码管选择——6个改为8个
output [7:0]led//8个LED备选
);
wire [31:0]Number_Sig;
countCtrl U1(
.CLK( CLK ),
.RSTn( RSTn ),
.Number_Sig( Number_Sig )//output->U2
);
paraOpti U2(
.CLK( CLK ),
.RSTn( RSTn ),
.Number_Sig( Number_Sig ), //input - from U1
.SMG_Data( SMG_Data ), //output->top
.Scan_Sig( Scan_Sig ) //output->top
);
endmodule
二、计数模块,完成计数功能
//数码管位控程序-8位->直接位控,为了速度快点,将100mS改为1mS,但T100MS变量名称没有改
module countCtrl(
input CLK,
input RSTn,
output [31:0]Number_Sig
);
//
parameter T100MS = 17'd49_999; //100ms的计数 23'd4_999_999||改为1mS,因为8个数码管
//
reg [7:0] led;
reg [16:0] C1;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
begin
C1 <= 17'd0;
led <= 8'b11111111;
end
else if( C1 == T100MS )
C1 <= 17'd0;
else
C1 <= C1 + 1'b1;
//
reg [7:0]i;
reg [31:0]rNum;
reg [31:0]rNumber;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
begin
i <= 8'd0;
rNum <= 32'd0;
rNumber <= 32'd0;
end
else
case( i )
0:
if( C1 == T100MS )
begin rNum[3:0] <= rNum[3:0]+1'b1;i<=i+1'b1; end //个位的计数
1:
if( rNum[3:0] > 4'd9 )
begin rNum[7:4] <= rNum[7:4] + 1'b1; rNum[3:0]<= 4'd0; i <= i + 1'b1; end //此位>9, 进位
else i <= i + 1'b1;
2:
if( rNum[7:4] > 4'd9 )
begin rNum[11:8] <= rNum[11:8] + 1'b1;rNum[7:4] <= 4'd0; i <= i + 1'b1; end//此位>9, 进位
else i <= i + 1'b1;
3:
if( rNum[11:8] > 4'd9 )
begin rNum[15:12] <= rNum[15:12] + 1'b1;rNum[11:8] <= 4'd0; i <= i + 1'b1; end//此位>9, 进位
else i <= i + 1'b1;
4:
if( rNum[15:12] > 4'd9 )
begin rNum[19:16] <= rNum[19:16] + 1'b1;rNum[15:12] <= 4'd0; i <= i + 1'b1; end//此位>9, 进位
else i <= i + 1'b1;
5:
if( rNum[19:16] > 4'd9 )
begin rNum[23:20] <= rNum[23:20] + 1'b1;rNum[19:16] <= 4'd0; end //此位>9, 进位
else i <= i + 1'b1;
6:
if( rNum[23:20] > 4'd9 )
begin rNum[27:24] <= rNum[27:24] + 1'b1;rNum[23:20] <= 4'd0; end //此位>9, 进位
else i <= i + 1'b1;
7:
if( rNum[27:24] > 4'd9 )
begin rNum[31:28] <= rNum[31:28] + 1'b1;rNum[27:24] <= 4'd0; end //此位>9, 进位
else i <= i + 1'b1;
8:
if( rNum[31:28] > 4'd9 )
begin rNum <= 4'd0; i <= i + 1'b1; end//此位>9, 全部清0
else i <= i + 1'b1;
9:
begin rNumber <= rNum; i <= 8'd0; end
endcase
//
assign Number_Sig = rNumber;
//
endmodule
三、8个段码LED设置模块,就是连接调用段码计数的3个子程序
module paraOpti(
input CLK,
input RSTn,
input [31:0]Number_Sig,
output [7:0]SMG_Data,
output [7:0]Scan_Sig
);
wire [3:0]Number_Data;
//
paraCtrl U1(
.CLK( CLK ),
.RSTn( RSTn ),
.Number_Sig( Number_Sig ), //input<-top
.Number_Data( Number_Data ) //output->U2
);
//
paraCode U2(
.CLK( CLK ),
.RSTn( RSTn ),
.Number_Data( Number_Data ), //input<-U2
.SMG_Data( SMG_Data ) //output->top
);
//
paraScan U3(
.CLK( CLK ),
.RSTn( RSTn ),
.Scan_Sig( Scan_Sig ) //output->top
);
//
endmodule
四、8段数码管0-9段显定义0~9
module paraCode(
input CLK,
input RSTn,
input [3:0]Number_Data,
output [7:0]SMG_Data
);
//此处需要按照自己的开发板来设计段显的8bit数
parameter _0 = 8'b0010_0010, _1 = 8'b1110_1110, _2 = 8'b0100_0011,_3 = 8'b1100_0010, _4 = 8'b1000_1110, _5 = 8'b1001_0010,_6 = 8'b0001_0010, _7 = 8'b1110_1010, _8 = 8'b0000_0010,_9 = 8'b1000_0010;
//
reg [3:0]rSMG;
reg [7:0]led;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
//begin
rSMG <= 8'b11111111;
// led <= 8'b11111111;
//end
else
case( Number_Data )
4'd0 : rSMG <= _0;
4'd1 : rSMG <= _1;
4'd2 : rSMG <= _2;
4'd3 : rSMG <= _3;
4'd4 : rSMG <= _4;
4'd5 : rSMG <= _5;
4'd6 : rSMG <= _6;
4'd7 : rSMG <= _7;
4'd8 : rSMG <= _8;
4'd9 : rSMG <= _9;
endcase
assign SMG_Data = rSMG;
endmodule
五、段码扫描定位显示,计数发生在哪个数码管位产生变化
module paraScan(
input CLK,
input RSTn,
output [7:0]Scan_Sig
);
parameter T1MS = 12'd4999; //16'd49999,改为0.1mS
//
reg [11:0]C1;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
C1 <= 12'd0;
else if( C1 == T1MS )
C1 <= 12'd0;
else
C1 <= C1 + 1'b1;
//
reg [7:0]i;
reg [7:0]rScan;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
begin
i <= 8'd0;
rScan <= 8'b1000_0000;
end
else
case( i )
0:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b0111_1111; //第一个数码选通
1:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b1011_1111; //第二个数码选通
2:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b1101_1111; //第三个数码选通
3:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b1110_1111; //第四个数码选通
4:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b111_0111; //第五个数码选通
5:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b1111_1011; //第六个数码选通
6:
if( C1 == T1MS ) i <= i + 1'b1;
else rScan <= 8'b1111_1101; //第七个数码选通
7:
if( C1 == T1MS ) i <= 8'd0;
else rScan <= 8'b1111_1110; //第八个数码选通
endcase
//
assign Scan_Sig = rScan;
endmodule
六、8个数码管显示控制
module paraCtrl(
input CLK,
input RSTn,
input [31:0]Number_Sig,
output [7:0]Number_Data
);
parameter T1MS = 12'd4999; //1ms计数 16'd49999||实际减少为0.1mS 注意这个只是T100M的1/8,必须的
//
reg [15:0]C1;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
C1 <= 16'd0;
else if( C1 == T1MS )
C1 <= 16'd0;
else
C1 <= C1 + 1'b1;
/******************************************/
reg [7:0]i;
reg [3:0]rNumber;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
begin
i <= 4'd0;
rNumber <= 4'd0;
end
else
case( i )
0:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[31:28]; //十万位数码管显示
1:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[27:24]; //十万位数码管显示
2:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[23:20]; //十万位数码管显示
3:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[19:16]; //万位数码管显示
4:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[15:12]; //千位数码管显示
5:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[11:8]; //百位数码管显示
6:
if( C1 == T1MS ) i <= i + 1'b1;
else rNumber <= Number_Sig[7:4]; //十位数码管显示
7:
if( C1 == T1MS ) i <= 4'd0;
else rNumber <= Number_Sig[3:0]; //低位数码管显示
endcase
/******************************************/
assign Number_Data = rNumber;
/******************************************/
endmodule
经过大约20多次的修改编译,下载测试总算开始出现转机,到此程序为止,已经编译了大约40多次&mdash;&mdash;真应了修改程序不如自己编的这句码农经典。程序模块见图51,
Files中可以看到6file:///D:UsersADMINI~1AppDataLocalLowBaiduBAIDUP~2dictDefaultE7015B~1.PNG个程序模块
管脚绑定见图52,
管脚绑定一定要正确,否则8段LED显示出乱、8个LED段码管位置也不对!
输出结果见照片53。
程序中写了关闭下边的LED代码,但注释了,显示结果不错,因为太快了,后3位就成了8字。实际上肉眼看,右2位显示8,有3位开始可以看到数字蹦的。
程序改的还有一点点小小的问题,由于改的地方太多了,也记不住都改了那些地方和那些代码,只能先这样了,有时间自己编代码吧。 |
|