51 单片机 LED 流水灯 + 数码管动态扫描学习笔记(STC89C52)

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,防止编译器优化出错。
相关推荐
祖力551 小时前
51单片机(中断、定时器、PWM)
单片机·嵌入式硬件·51单片机
扎陵半导体1 小时前
电子系统中的隔离芯片:关键作用与性能指标
单片机·嵌入式硬件·国产芯片·隔离器·隔离芯片·光隔
zzzll11111 小时前
LLM 学习第 24 课:Agent Harness
前端·人工智能·学习
智者知已应修善业1 小时前
【如何将此图变为000到101就返回】2026-4-7
驱动开发·经验分享·笔记·硬件架构·硬件工程
jianqiang.xue1 小时前
ESP-IDF保姆级入门38|电源管理与锂电池充电全解:充电拓扑/电源路径控制/充放电保护/电量检测/低功耗策略,掌握嵌入式电池供电系统设计
单片机·嵌入式·esp32
wixzjsh2 小时前
51单片机学习笔记|最小系统、中断、定时器+数码管动态扫描实现0~9999计数器
笔记·学习·51单片机
平头哥AI2 小时前
Day 21 _ error 是个普通值_errors.New 与 fmt.Errorf 造出来,沿调用栈抛到 main 接住
后端·学习·golang·go
snow@li2 小时前
服务器运维: k3s 安装及配置的完整操作笔记
笔记
ECT-OS-JiuHuaShan2 小时前
哲学是迭代学,数学是拓扑学
开发语言·人工智能·学习·算法·机器学习·php·拓扑学