51单片机 proteus 米字型数码管14seg _mpx4

用单片机51和proteus仿真 设计控制14段LED数码管(米字型数码管14seg _mpx4)的显示。数码管显示4位字符(数字或字母),显示内容可
从左往右依次显示一位字符,显示间隔800毫秒。对第二位字符进行
顺时针逐段显示,显示间隔 500毫秒。之后四位字符共同闪烁,闪烁间隔600毫秒,闪烁2次后,四位字符共同保持显示状态。(时间采用定时器,不要用定时函数)

以下为单片机51的程序代码:

#include <reg51.h>

#define LED P0 // 数码管连接在P0口

// 数码管显示的字符编码
unsigned char code LED_CHAR[] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, // 0~9
    0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71 // A~F
};

// 定义计时器初值
#define T0_INIT_VALUE 65536-50000 // 50ms
#define T1_INIT_VALUE 65536-10000 // 10ms

// 定义计时器计数器
unsigned int t0_count = 0;
unsigned int t1_count = 0;

// 定义显示字符、显示位置和显示方式
unsigned char display_char[4] = {0, 0, 0, 0}; // 显示字符
unsigned char display_pos = 0; // 显示位置
unsigned char display_mode = 0; // 显示方式

// 定时器0中断处理函数,用于控制数码管显示间隔
void timer0_isr() interrupt 1 {
    TH0 = T0_INIT_VALUE / 256;
    TL0 = T0_INIT_VALUE % 256;
    
    // 控制数码管显示间隔
    if (t0_count < 100) {
        t0_count++;
    } else {
        t0_count = 0;
        
        // 显示下一个字符
        if (display_mode == 0) {
            LED = LED_CHAR[display_char[display_pos]];
            display_pos = (display_pos + 1) % 4;
        } else if (display_mode == 1) {
            // 顺时针逐段显示
            unsigned char i;
            for (i = 0; i < 14; i++) {
                LED = LED_CHAR[i];
                delay(50);
            }
        } else if (display_mode == 2) {
            // 四位字符共同闪烁
            unsigned char i;
            for (i = 0; i < 2; i++) {
                LED = 0x00;
                delay(300);
                LED = LED_CHAR[display_char[0]];
                delay(300);
                LED = LED_CHAR[display_char[1]];
                delay(300);
                LED = LED_CHAR[display_char[2]];
                delay(300);
                LED = LED_CHAR[display_char[3]];
                delay(300);
            }
            LED = LED_CHAR[display_char[0]] | LED_CHAR[display_char[1]] | LED_CHAR[display_char[2]] | LED_CHAR[display_char[3]];
            display_mode = 3;
        }
    }
}

// 定时器1中断处理函数,用于计时
void timer1_isr() interrupt 3 {
    TH1 = T1_INIT_VALUE / 256;
    TL1 = T1_INIT_VALUE % 256;
    
    // 计时器计数器加1
    t1_count++;
}

// 延时函数,用于控制数码管顺时针逐段显示和闪烁
void delay(unsigned int t) {
    unsigned int i;
    for (i = 0; i < t; i++) {
        // 等待计时器1计时完成
        while (t1_count < 1);
        t1_count = 0;
    }
}

void main() {
    // 初始化定时器0和定时器1
    TMOD = 0x11; // 定时器0工作在模式1,定时器1工作在模式1
    TH0 = T0_INIT_VALUE / 256;
    TL0 = T0_INIT_VALUE % 256;
    TH1 = T1_INIT_VALUE / 256;
    TL1 = T1_INIT_VALUE % 256;
    TR0 = 1; // 启动定时器0
    TR1 = 1; // 启动定时器1
    ET0 = 1; // 允许定时器0中断
    ET1 = 1; // 允许定时器1中断
    EA = 1; // 允许中断
    
    // 初始化显示字符和显示方式
    display_char[0] = 1;
    display_char[1] = 2;
    display_char[2] = 3;
    display_char[3] = 4;
    display_mode = 0;
    
    while (1) {
        // 按下按钮切换显示方式
        if (P1 == 0x01) {
            display_mode = (display_mode + 1) % 3;
            delay(1000);
        }
    }
}

在仿真中,可以使用proteus中的米字型数码管14seg_mpx4和按钮模拟按键。将数码管连接在单片机的P0口,将按钮连接在单片机的P1口。仿真结果如下:

仿真结果