1. 实验目的
- 掌握 IO 口驱动 LED 的基本方法;
- 理解数码管动态扫描原理,利用人眼视觉暂留实现多位显示;
- 使用定时器 0 中断实现秒计时,并在数码管上显示计数值。
2. 硬件电路
plaintext
LED(共阳极)
5V → LED阳极 → LED阴极 → 220Ω电阻 → P2.x
2位共阴极数码管
P0.0~P0.7 → 数码管 a~g、dp(P0 接 8 位上拉排阻)
P1.0 → 数码管个位位选
P1.1 → 数码管十位位选
3. 核心代码
c
#include <reg52.h>
sbit EN1 = P1^0;
sbit EN2 = P1^1;
// 共阴极段码 0~9
unsigned char code seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
volatile unsigned char cnt=0;
unsigned int num=0;
void delay(unsigned int t)
{
while(t--);
}
// 动态扫描显示两位数字
void display(unsigned int n)
{
unsigned char shi = n/10;
unsigned char ge = n%10;
EN1=1; P0=seg[ge]; delay(400); EN1=0;
EN2=1; P0=seg[shi]; delay(400); EN2=0;
}
// 定时器0中断 50ms@12M
void Timer0_ISR(void) interrupt 1
{
TH0=0x3C; TL0=0xAF;
cnt++;
if(cnt >= 20){
cnt = 0;
num++;
}
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0=0x3C; TL0=0xAF;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void main(void)
{
Timer0_Init();
while(1)
{
P2 = 0xFE; // P2.0的LED点亮
display(num);
}
}
4. 实验现象
- P2.0 LED 保持点亮;
- 数码管每秒数值加 1;
- 动态扫描必须加短暂延时,否则数码管过暗看不清。
5. 踩坑小结
- P0 口无上拉排阻,数码管亮度不足;
- 定时器模式 1 中断,必须手动重装 TH0、TL0 初值;
- 被中断修改的全局变量建议加
volatile,防止编译器优化出错。