求51单片机8位数码管计时器程序

img


按下按键1复位,按下按键2开始 ,51单片机8位数码管计时器 ,程序简便一些

花了一个小时写的,希望对你有用!


#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit D1 = P2^0;  // 数码管引脚定义
sbit D2 = P2^1;
sbit D3 = P2^2;
sbit D4 = P2^3;
sbit D5 = P2^4;
sbit D6 = P2^5;
sbit D7 = P2^6;
sbit D8 = P2^7;

sbit Key1 = P1^0;  // 按键引脚定义
sbit Key2 = P1^1;

uint ms;    // 毫秒计数器
uint sec;   // 秒计数器
uchar min;  // 分钟计数器
uchar hour; // 小时计数器

void delay(uint i) { // 短暂延时函数
    while(i--);
}

void DAC(uint n) { // 将数值DAC输出
    D1 = (n & 0x01);
    D2 = (n & 0x02) >> 1;
    D3 = (n & 0x04) >> 2;
    D4 = (n & 0x08) >> 3;
    D5 = (n & 0x10) >> 4;
    D6 = (n & 0x20) >> 5;
    D7 = (n & 0x40) >> 6;
    D8 = (n & 0x80) >> 7;
}

void display() { // 显示计时器数值
    DAC(hour / 10); // 输出小时的十位
    delay(50); // 短暂延时
    DAC(hour % 10); // 输出小时的个位
    delay(50);
    DAC(min / 10); // 输出分钟的十位
    delay(50);
    DAC(min % 10); // 输出分钟的个位
    delay(50);
    DAC(sec / 10); // 输出秒的十位
    delay(50);
    DAC(sec % 10); // 输出秒的个位
    delay(50);
}

void initTimer() { // 初始化定时器
    TMOD |= 0x01; // 设置定时器0为16位模式,使用定时器0的模式1
    TH0 = 0xFC; // 计时1ms,从0xFC开始(65536-1000)计时
    TL0 = 0x18;
    ET0 = 1; // 允许定时器0中断
    TR0 = 1; // 启动定时器0
    EA = 1; // 打开总中断开关
}

void main() {
    initTimer(); // 初始化定时器
    while(1) {
        if (Key1 == 0) { // 如果按下了按键1,复位计时器
            ms = sec = min = hour = 0;
            display(); // 显示0
        }
        if (Key2 == 0) { // 如果按下了按键2,开始计时器
            while(1) {
                display(); // 显示计时器数值
                if (ms >= 1000) {
                    ms = 0;
                    sec++;
                    if (sec >= 60) {
                        sec = 0;
                        min++;
                        if (min >= 60) {
                            min = 0;
                            hour++;
                            if (hour >= 24) {
                                hour = 0;
                            }
                        }
                    }
                }
            }
        }
    }
}

void timer0() interrupt 1 { // 定时器0中断
    TH0 = 0xFC;
    TL0 = 0x18;
    ms++; // 每次中断毫秒计数器加1
}

#include <reg51.h>  // 使用51单片机,需要包含reg51.h头文件

sbit k1 = P3^0;      // 定义按键1连接的io口
sbit k2 = P3^1;      // 定义按键2连接的io口

unsigned long cnt = 0;  // 定义计时器变量,用于计数

// 数码管段选码表
unsigned char code digSeg[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90
};

// 数码管位选码表
unsigned char code digSel[] = {
    0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
};

// 显示一个数码
void showDight(unsigned char index, unsigned char data) {
    P2 = digSel[index];
    P0 = digSeg[data];
}

// 数码管全部显示0
void clearDisplay() {
    for (int i = 0; i < 8; i++) {
        showDight(i, 0);
    }
}

// 计时器中断处理函数
void timer() interrupt 1 {
    // 计算计时器的值
    cnt++;
    // 显示计时器的值
    for (int i = 0; i < 8; i++) {
        showDight(i, cnt % 10);
        cnt /= 10;
    }
}

void main() {
    TMOD = 0x01;   // 定时器0为模式1,使用中断
    TH0 = 0xFC;    // 52ms时钟周期,用于计时
    TL0 = 0x67;
    EA = 1;        // 开启总中断
    ET0 = 1;       // 开启定时器0中断
    TR0 = 1;       // 启动计时器0
    
    clearDisplay();  // 数码管全部显示0
    
    while (1) {
        if (k1 == 0) {     // 按键1按下,复位计时器
            TR0 = 0;
            cnt = 0;
            clearDisplay();
        }
        if (k2 == 0) {     // 按键2按下,开始计时器
            TR0 = 1;
        }
    }
}

该程序使用定时器0实现计时器功能。程序中使用TMOD寄存器设置定时器0为模式1,使用中断。定时器0的时钟周期设为52ms,用于计时。程序中使用TH0和TL0分别设置定时器0的高八位和低八位计数器的初值。程序中使用EA开启总中断,使用ET0开启定时器0中断,使用TR0启动计时器0。在定时器中断处理函数中,程序累加计时器变量cnt并通过showDight函数将计时器的值显示在数码管上。在主函数中,程序监听按键1和按键2的按下事件,按下按键1时清零计时器变量cnt并将所有数码管设置为0,按下按键2时开始计时。

下面是一个简单的51单片机8位数码管计时器程序,按下按键1复位,按下按键2开始计时,计时结束后自动停止并显示计时结果。



#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int

sbit KEY1 = P1^0;
sbit KEY2 = P1^1;

uchar code LED_CODE[] = {  // 数码管显示0~9的编码
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 
    0x6D, 0x7D, 0x07, 0x7F, 0x6F
};

uchar second = 0;  // 秒数
uchar minute = 0;  // 分钟数
bit start_flag = 0;  // 计时开始标志

void delay(uint n)  // 延时函数
{
    uint i, j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < 125; j++);
    }
}

void display(uchar num)  // 数码管显示函数
{
    P2 = LED_CODE[num];
}

void init_timer()  // 初始化计时器
{
    TMOD = 0x01;  // 定时器0工作在模式1(16位定时器)下
    TH0 = 0xFC;  // 定时器初值为65536-50000=15536,即500ms
    TL0 = 0x67;
    ET0 = 1;  // 允许定时器0中断
    TR0 = 1;  // 启动定时器0
    EA = 1;  // 允许中断
}

void main()
{
    uchar i;

    while (1)
    {
        if (KEY1 == 0)  // 按键1复位
        {
            second = 0;
            minute = 0;
            start_flag = 0;
            display(0);
            delay(100);
            continue;
        }

        if (KEY2 == 0)  // 按键2开始计时
        {
            start_flag = 1;
            delay(100);
        }

        if (start_flag)  // 计时开始
        {
            display(second % 10);  // 显示秒数个位
            delay(5);
            display(second / 10);  // 显示秒数十位
            delay(5);
            display(minute % 10);  // 显示分钟数个位
            delay(5);
            display(minute / 10);  // 显示分钟十位
            delay(5);

            if (second == 59)  // 计时结束
            {
                TR0 = 0;  // 停止定时器0
                start_flag = 0;  // 计时结束标志
            }
            else
            {
                second++;  // 秒数加1
                if (second == 60)  // 秒数进位
                {
                    second = 0;
                    minute++;
                }
            }
        }
    }
}

void timer0_isr() interrupt 1  // 定时器0中断函数
{
    TH0 = 0xFC;  // 重置定时器初值
    TL0 = 0x67;
}

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^