2.计数器-点亮数码管

**

实验内容(一)

**

1.手工绘制的RTL结构图:

手工绘制的RTL结构图

2.Quartus生成的RTL

Quartus生成的RTL

实验原理:

整个计数器一共有3个模块组成:
    (1)第一模块为生成基准信号的cnt_sync模块,为使计数数值变化的时间间隔是1秒 ,所以定义一个常数MAX_VAL为50000000,当计数器的计数值等于这个常数时,OV溢出1,从而产生1s的时间间隔;
    (2)第二模块为cnt_en_0to9带使能的计数器模块,当使能信号EN有效时,此模块开启,计数器开始从
    0 1 … 6  0 1… 7     0 1 … 8   0 1 … 9   0 1 … 6  ……   开始循环计数;
    (3)第三模块为dec_4to9的译码器模块,让译码器的输入端连接上一级计数器的输出端,根据8段数码管的编码原理进行编码,从而点亮LED数码管。

以下分别为不同RTL的展开图:

(1)cnt_sync生成基准信号模块

这里写图片描述

(2)cnt_en_0to9带使能的计数模块

这里写图片描述

(3)dec_4to9模块

这里写图片描述

3.SignalTap截图

这里写图片描述

4.代码片模块

/
//生成基准信号模块
module cnt_sync(
CLK,//时钟,上升沿有效
RST,//异步复位,低电平有效
CNTVAL,//输出的计数值信号
OV);//计数溢出信号,计数值为最大值时该信号为1

//电路编译参数,最大计数值
parameter MAX_VAL=50_000_000;

input CLK;
input RST;
output [32-1:0] CNTVAL;
output OV;

reg [32-1:0] CNTVAL;
reg OV;

always @ (posedge CLK or negedge RST)
begin
if(!RST)
CNTVAL <= 0;
else begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL +1’b1;
end

end
always @ (CNTVAL)
begin
if(CNTVAL == MAX_VAL)
OV = 1’b1;
else
OV = 1’b0;
end

endmodule

//
//cnt_rst带有使能的计数器模块
module cnt_en_0to9(
CLK,//时钟,上升沿有效
EN,//输入的计数使能,高有效
CNTVAL);//输出的计数值信号

input CLK;
input EN;
output [3:0] CNTVAL;

reg [3:0] CNTVAL;
reg [3:0] MAX_CNT=6;

always @ (posedge CLK)
begin
if(EN) begin//使能信号开启,执行计数功能
if(CNTVAL < MAX_CNT)
CNTVAL <= CNTVAL +1’b1;
else begin
CNTVAL <= 0;//计数到最大值,下一计数值清零
MAX_CNT <= MAX_CNT + 1’b1;
if(MAX_CNT >= 9)
MAX_CNT <= 6;
end
end
else begin
CNTVAL <= CNTVAL ;//当使能信号无效时,计数值保持不变
end

end
endmodule

///
//译码器模块
module dec_4to9( //数码管的输出最大为0-9
IN,//译码器的输入
OUT);//译码器的输出

input [3:0] IN;
output [7:0] OUT;

reg [7:0] OUT;//有8段数码管

always @ (IN)
begin
case(IN)
4’h0: OUT= 8’hc0;
4’h1: OUT= 8’hf9;
4’h2: OUT= 8’ha4;
4’h3: OUT= 8’hb0;
4’h4: OUT= 8’h99;
4’h5: OUT= 8’h92;
4’h6: OUT= 8’h82;

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要了解数码管的共阳极和共阴极的区别。共阳极数码管的所有阳极都连接在一起,而阴极是分开控制的。因此,要点亮数码管上的某一位,需要将该位对应的阴极接地,同时将对应的阳极输出高电平。 以下是51单片机控制共阳极数码管实现四位计数器的基本步骤: 1. 定义数码管的引脚和对应的端口,如: ``` sbit DIG1 = P1^0; // 数码管第一位 sbit DIG2 = P1^1; // 数码管第二位 sbit DIG3 = P1^2; // 数码管第三位 sbit DIG4 = P1^3; // 数码管第四位 sbit DIO = P2^0; // 数据线 sbit CLK = P2^1; // 时钟线 ``` 2. 定义数码管的显示字符集,即对应数字的 LED 点阵,如: ``` unsigned char code LEDChar[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 }; ``` 3. 编写数码管显示函数,根据需要显示的数字将对应的 LED 点阵输出到数据线上,如: ``` void Display(unsigned char num, unsigned char dig){ unsigned char i; DIO = 0; // 数据线清零 for(i = 0; i < dig; i++){ // 循环控制位选 CLK = 0; // 时钟线清零 if(i == num){ // 根据需要显示的数字选择 LED 点阵输出 DIO = LEDChar[i]; } CLK = 1; // 时钟线置高 DIO = 0; // 数据线清零 } } ``` 4. 编写主函数,实现四位计数器的功能。首先需要定义计数器的变量,然后在循环中控制计数器的变化,并将计数器每一位的数字显示到对应的数码管上,如: ``` void main(){ unsigned int cnt = 0; unsigned char cnt0, cnt1, cnt2, cnt3; while(1){ cnt++; // 计数器加1 cnt0 = cnt % 10; // 取个位数字 cnt1 = cnt / 10 % 10; // 取十位数字 cnt2 = cnt / 100 % 10; // 取百位数字 cnt3 = cnt / 1000 % 10; // 取千位数字 DIG1 = 0; // 数码管第一位接地 Display(cnt0, 1); // 显示个位数字 DIG1 = 1; // 数码管第一位输出高电平 DIG2 = 0; // 数码管第二位接地 Display(cnt1, 2); // 显示十位数字 DIG2 = 1; // 数码管第二位输出高电平 DIG3 = 0; // 数码管第三位接地 Display(cnt2, 3); // 显示百位数字 DIG3 = 1; // 数码管第三位输出高电平 DIG4 = 0; // 数码管第四位接地 Display(cnt3, 4); // 显示千位数字 DIG4 = 1; // 数码管第四位输出高电平 delay(10); // 延时10ms,控制计数速度 } } ``` 以上是共阳极数码管实现四位计数器的基本步骤,可以根据需要进行修改和扩展。注意在实际连接数码管时需要根据具体型号和引脚定义进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值