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,防止编译器优化出错。
相关推荐
ss27327 分钟前
AI时代首先数据库-PostgreSQL实战笔记 | 22 PostgreSQL实例与集群
数据库·笔记·postgresql
ss27328 分钟前
AI时代首先数据库-PostgreSQL实战笔记 | 21 PostgreSQL进程与内存架构介绍
数据库·笔记·postgresql
无敌贵点大王39 分钟前
从寄存器层面重学STM32(2)——RCC和时钟树
stm32·单片机·嵌入式硬件
小黄人软件1 小时前
桌面需要整理吗?有工具自动分类
学习
玄芯散人1 小时前
【元婴·103】GPIO深度:复用、上下拉、翻转速度
单片机·嵌入式硬件
老衲不用@飘柔1 小时前
SFP与SFP+学习知识整理
学习
X54先生(人文科技)2 小时前
社会嵌入式终身学习机器与修复时代-ELR架构和技术演化探讨
人工智能·深度学习·学习·架构·开源协议
电子云与长程纠缠2 小时前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
syagain_zsx3 小时前
BRpc 二次封装:Channel 管理、服务管理与回调工厂
c++·学习·程序人生·rpc·谷歌
其实防守也摸鱼3 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全