数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 857|回复: 12

[C51] 分享3元8角的AT89S51试验板让它运转如飞,助你玩转数码管

[复制链接]
发表于 2025-6-21 09:12:01 | 显示全部楼层 |阅读模式
本帖最后由 段智刚 于 2025-6-21 15:26 编辑

可能是某个项目废板,元件不缺但是坏的,当时顺手买一个闲时画出草图,无意间找到坏件改个程序好使了,又购10片修好,仅有一片缺划显示,学到不少够用一阵了。程序还不能独立编写,有瑕疵给指点指点


include <reg51.h>//100秒流水灯程序,加入蜂鸣功能
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

// 共阳数码管段选码(P2口)
uchar code seg_table[] = {
    0x84, // 0
    0x9F, // 1
    0xA1, // 2
    0x91, // 3
    0x9A, // 4
    0xD0, // 5
    0xC0, // 6
    0x9D, // 7
    0x80, // 8
    0x90  // 9
};

// 位选(P1.0-P1.2)
sbit BIT_100 = P1^0;  // 百位
sbit BIT_10 = P1^1;   // 十位
sbit BIT_1 = P1^2;    // 个位
sbit fengming=P3^4;
// LED灯(P0口,高电平点亮)
uchar led_count = 0;   // 记录999秒触发次数

// 定时器0中断变量
uint count = 0;        // 50ms计数
uint sec = 0;          // 秒数(0-999)

// 延时函数(12MHz晶振)
void delay_ms(uint ms) {
    uint i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++);
}

// 数码管动态显示(带高位消隐)
void display(uint num) {
    uchar bai, shi, ge;
    bai = num / 100;
    shi = num % 100 / 10;
    ge = num % 10;

    // 显示百位(若为0且不是个位数则不显示)
    BIT_100 = 0;
    BIT_10 = 1;
    BIT_1 = 1;
    if (num >= 100) {
        P2 = seg_table[bai];
    } else {
        P2 = 0xFF;  // 不显示
    }
    delay_ms(2);

    // 显示十位(若为0且不是个位数则不显示)
    BIT_100 = 1;
    BIT_10 = 0;
    BIT_1 = 1;
    if (num >= 10) {
        P2 = seg_table[shi];
    } else {
        P2 = 0xFF;  // 不显示
    }
    delay_ms(2);

    // 显示个位(始终显示)
    BIT_100 = 1;
    BIT_10 = 1;
    BIT_1 = 0;
    P2 = seg_table[ge];
    delay_ms(2);
}

void main() {
    uchar i;

    // 初始化
    P0 = 0x00;  // LED全灭(高电平点亮)
    P1 = 0xFF;  // 位选关闭
    P2 = 0xFF;  // 段选关闭
    fengming=0;
    // 上电LED闪烁两次(全亮→全灭→全亮→全灭)
    for (i = 0; i < 2; i++) {
        P0 = 0xFF;  // LED全亮
        delay_ms(500);
        P0 = 0x00;  // LED全灭
        delay_ms(500);
    }

    // 定时器0初始化(50ms中断一次)
    TMOD = 0x01;    // 定时器0,模式1
    TH0 = 0x3C;     // 50ms定时(12MHz)
    TL0 = 0xB0;
    ET0 = 1;        // 允许定时器0中断
    EA = 1;         // 开总中断
    TR0 = 1;        // 启动定时器0

    while (1) {
        display(sec);  // 显示当前秒数(0-999)

        // 999秒触发LED闪烁
        if (sec == 999) {
            led_count++;  // 触发次数+1
            sec = 0;      // 秒数归零
            fengming=1;
            delay_ms(250);
               fengming=0;                    // 熄灭
      

            // 第1-8次:依次点亮P0.0-P0.7
            if (led_count <= 8) {
                P0 = (1 << (led_count - 1));  // 高电平点亮对应LED
               
            }
            // 第9次:全灭并重置计数
            else if (led_count == 9) {
                P0 = 0x00;
                led_count = 0;
            }
        }
    }
}

// 定时器0中断服务函数
void timer0() interrupt 1 {
    TH0 = 0x3C;  // 重装初值
    TL0 = 0xB0;
    count++;

    if (count >= 2) {  // 20*50ms = 1s
        count = 0;
        sec++;
        if (sec > 999) sec = 0;  // 999秒后归零
    }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 2家元 +42 收起 理由
jf201006 + 12 謝謝分享
家睦 + 30

查看全部打赏

 楼主| 发表于 2025-6-22 07:51:10 | 显示全部楼层
本帖最后由 段智刚 于 2025-6-22 07:55 编辑

带屏的好价格,不知利用如何,AT89S52我也存货
下载器就是常见的10元左右买的AVR fighter,驱动软件安装在XP系统无难度,在win10上费点功夫。刚开始以为老版硬件不适应新系统,买了一个新版问题解决后,老版一样用,新版就睡觉了,老版用坏再说

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-24 09:26:54 | 显示全部楼层
xiaocake 发表于 2025-6-23 23:27
你这个硬件叫USBASP,AVR fighter是烧写软件。

张冠李戴了,初学还是没分开
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-5 08:05:09 | 显示全部楼层
longkou1 发表于 2025-7-5 02:39
这个片子有点老,研究明白搞个维修还是可以的

才过流水灯,最近练习数码管。还有按键,蜂鸣器,功率管,外中断定时器都用上是不是个小产品了。原机是坏的,画图修好也是信心满满
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-19 22:17 , Processed in 0.156000 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表