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,防止编译器优化出错。
相关推荐
喜欢打篮球的普通人25 分钟前
MiniMind 学习笔记(十二):Pretrain 实操——从版本梳理到 8GB 显卡上的真实训练
人工智能·笔记·学习
女神下凡1 小时前
芯参谋(26):DDR4_软件设计规范
arm开发·单片机·嵌入式硬件
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(87):VizoMem——把文本历史转化为可检索的视觉记忆
论文阅读·人工智能·学习·开源·github
坤坤子吖2 小时前
算法学习——高精度加减乘除
c++·笔记·学习·算法
HY小宝F2 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 03 · 网络基础:建立“包“的思维 —— 学习总结
网络·学习
dadaobusi2 小时前
学习:AXI协议
学习
xxwl5852 小时前
vue3的入门学习
前端·vue.js·学习
Joe_Wang53 小时前
【从0到1学习JVM · 21】既不浪费空间又没有碎片,标记整理算法到底慢在哪
jvm·学习·算法·垃圾回收·标记整理算法
Answer1st3 小时前
【HAL库】嵌入式思路(一)
笔记
AOI小白新手上路3 小时前
深度学习模块缝合方法论 · 人物蒸馏笔记
人工智能·笔记·深度学习