找回密码
 立即注册
查看: 73|回复: 2

点亮四位数码管学习

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:83
  • 最近打卡:2025-09-18 08:48:47
已绑定手机

10

主题

71

回帖

236

积分

中级会员

积分
236
发表于 2025-9-8 09:56:34 | 显示全部楼层 |阅读模式
点亮四位数码管学习,数码管从0000-9999显示,间隔1秒,外加一个输出口
截图202509080953217849.jpg
截图202509080954058762.jpg

dicengPCB

dicengPCB
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:83
  • 最近打卡:2025-09-18 08:48:47
已绑定手机

10

主题

71

回帖

236

积分

中级会员

积分
236
发表于 2025-9-8 09:56:46 | 显示全部楼层
#include <STC8H.H>
#include <intrins.h>

// 数码管段引脚定义(共阳极)
sbit SEG_D = P1^5;  // D段连接P1.5
sbit SEG_G = P1^3;  // G段连接P1.3
sbit SEG_C = P1^4;  // C段连接P1.4
sbit SEG_A = P5^4;  // A段连接P5.4
sbit SEG_E = P1^6;  // E段连接P1.6
sbit SEG_F = P1^7;  // F段连接P1.7
sbit SEG_B = P1^2;  // B段连接P1.2

// 数码管位选引脚(低电平有效)
sbit DIGIT_QIAN = P3^6;  // 千位通过P3.6控制
sbit DIGIT_BAI  = P3^7;  // 百位通过P3.7控制
sbit DIGIT_SHI  = P1^0;  // 十位通过P1.0控制
sbit DIGIT_GE   = P1^1;  // 个位通过P1.1控制

// 共阳极数码管段码表(0-9)
unsigned char code SEG_TABLE[] = {
    0x3F, // 0
    0x06, // 1
    0x5B, // 2
    0x4F, // 3
    0x66, // 4
    0x6D, // 5
    0x7D, // 6
    0x07, // 7
    0x7F, // 8
    0x6F  // 9
};

// 全局变量
unsigned char qian_num = 0;  // 千位数字,初始为0
unsigned char bai_num = 0;   // 百位数字,初始为0
unsigned char shi_num = 0;   // 十位数字,初始为0
unsigned char ge_num = 0;    // 个位数字,初始为0
unsigned int  timer_count = 0;   // 定时器计数(用于1秒更新)
unsigned char scan_count = 0;    // 扫描计数(用于高频刷新)
bit           update_flag = 0;   // 更新标志

// 定时器0初始化(0.05ms中断)
void Timer0_Init(void) {
    TMOD = 0x01;                // 定时器0工作在方式1
    TH0 = (65536 - 50) / 256;   // 0.05ms中断初值(12MHz晶振)
    TL0 = (65536 - 50) % 256;
    ET0 = 1;                    // 允许定时器0中断
    EA = 1;                     // 允许总中断
    TR0 = 1;                    // 启动定时器0
}

// 端口初始化
void Port_Init(void) {
    // 配置段选和位选引脚为推挽输出
    P1M0 = 0xA7;  // P1.0-P1.7推挽输出
    P1M1 = 0x00;
    P5M0 = 0x10;  // P5.4推挽输出
    P5M1 = 0x00;
   
    // 配置百位和千位控制引脚为推挽输出
    P3M0 = 0xC0;  // P3.6(千位)和P3.7(百位)推挽输出
    P3M1 = 0x00;
   
    // 初始关闭所有数码管
    DIGIT_QIAN = 1;
    DIGIT_BAI = 1;
    DIGIT_SHI = 1;
    DIGIT_GE = 1;
}

// 设置数码管段码
void Set_Segment(unsigned char num) {
    unsigned char seg_code = SEG_TABLE[num];
   
    // 共阳极数码管:段码位为1时,对应引脚输出0点亮
    SEG_A = (seg_code & 0x01) ? 0 : 1;
    SEG_B = (seg_code & 0x02) ? 0 : 1;
    SEG_C = (seg_code & 0x04) ? 0 : 1;
    SEG_D = (seg_code & 0x08) ? 0 : 1;
    SEG_E = (seg_code & 0x10) ? 0 : 1;
    SEG_F = (seg_code & 0x20) ? 0 : 1;
    SEG_G = (seg_code & 0x40) ? 0 : 1;
}

// 快速动态扫描显示四位数字
void Fast_Scan_Display(void) {
    // 关闭所有位选,防止串扰
    DIGIT_QIAN = 1;
    DIGIT_BAI = 1;
    DIGIT_SHI = 1;
    DIGIT_GE = 1;
   
    // 循环扫描千位、百位、十位、个位
    switch(scan_count % 4) {
        case 0:  // 显示千位
            Set_Segment(qian_num);
            DIGIT_QIAN = 0;
            break;
        case 1:  // 显示百位
            Set_Segment(bai_num);
            DIGIT_BAI = 0;
            break;
        case 2:  // 显示十位
            Set_Segment(shi_num);
            DIGIT_SHI = 0;
            break;
        case 3:  // 显示个位
            Set_Segment(ge_num);
            DIGIT_GE = 0;
            break;
    }
}

// 定时器0中断服务程序(高频刷新+计时)
void Timer0_ISR(void) interrupt 1 {
    // 重装载初值(0.05ms)
    TH0 = (65536 - 50) / 256;
    TL0 = (65536 - 50) % 256;
   
    // 每0.05ms执行一次快速扫描
    scan_count++;
    Fast_Scan_Display();
   
    // 累计20000次中断为1秒(0.05ms * 20000 = 1000ms)
    if (timer_count < 20000) {
        timer_count++;
    } else {
        timer_count = 0;
        update_flag = 1;  // 置位更新标志
    }
}

// 更新数字(从0000递增到9999后循环到0000继续)
void Update_Number(void) {
    ge_num++;                // 个位先加1
    if (ge_num > 9) {        // 个位满10
        ge_num = 0;          // 个位归零
        shi_num++;           // 十位加1
        if (shi_num > 9) {   // 十位满10
            shi_num = 0;     // 十位归零
            bai_num++;       // 百位加1
            if (bai_num > 9) {  // 百位满10
                bai_num = 0;    // 百位归零
                qian_num++;     // 千位加1
                if (qian_num > 9) {  // 千位满10(达到9999)
                    // 循环到0000重新开始
                    qian_num = 0;
                    bai_num = 0;
                    shi_num = 0;
                    ge_num = 0;
                }
            }
        }
    }
}

void main(void) {
    Port_Init();      // 初始化端口
    Timer0_Init();    // 初始化定时器
   
    while (1) {
        // 主循环处理数字更新,显示由定时器中断控制
        if (update_flag) {
            update_flag = 0;
            Update_Number();
        }
    }
}
   
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:83
  • 最近打卡:2025-09-18 08:48:47
已绑定手机

10

主题

71

回帖

236

积分

中级会员

积分
236
发表于 2025-9-8 09:57:36 | 显示全部楼层
烧录文件

四位 - 0000-9999.hex

1.43 KB, 下载次数: 2

烧录文件

回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-18 14:13 , Processed in 0.106510 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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