使用51单片机编写计时器(分钟,秒钟分离版)

针对网络上大部分例程序只有倒计时秒 , 无法一眼看出还剩多少时间,因此做考试计时器不具备实用性。

因此,编写一个 分钟,秒钟分离的版本,方便考生的时间控制。

/*==================================================================
编写时间:                      2022.04.21
设计目标:
四位共阴极数码管, 前两位为分钟后两位为秒钟。
设定时间为90分钟,开机后开始倒计时。

硬件电路设计:
数码管使用4个NPN三极管驱动,基极通过1K电阻连接STC89C51的
P1.0-P1.4 口。发射极共地,集电极接数码管阴极。
数码管数据位分别通过电阻限流后同STC89C51的P0口连接。
单片机晶振11.0592Mhz。

软件逻辑设计:
1.利用T0中断函数,计数到200次,发送1秒标志Flage,
2.数码管驱动函数(LedDriver)在接收到 Flage后,进行倒计时计算,并将数据传递给显示函数(LedShow)。
3.显示函数(LedShow)在收到时间数据后,进行数据分离,并写入数码管缓存。
4.数码管刷新函数(LedScan)利用数码管缓存的数据进行刷新动态显示。

Others You Need To Know:
为保证准确性, 取能被机器周期除尽的最小数值5ms
得出TMOD 16位寄存器初始值:60928 设定值:0xEE00;
================================================================*/
#include<reg52.h>  //对寄存器配置的头文件。

sbit LEDS1 = P1 ^ 0;
sbit LEDS2 = P1 ^ 1;
sbit LEDS3 = P1 ^ 2;
sbit LEDS4 = P1 ^ 3;

unsigned int Tcount = 5400;  //时间计数 设定90分钟 5400秒

bit Flage = 0;

unsigned char code LedChar[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
unsigned char LedBuf[] = {0x00, 0x00, 0x00, 0x00};

void LedCharDriver();
void LedScan();
void LedShow(unsigned int i);

void main()
{
/*======================
    初始数码管
=======================*/
    LEDS1 = 0;
    LEDS2 = 0;
    LEDS3 = 0;
    LEDS4 = 0;
/*=======================
    配置定时器
========================*/
    EA = 1;
    TMOD = 0x01;
    TH0 = 0xEE;
    TL0 = 0x00;
    ET0 = 1;
    TR0 = 1;
    while(1)
    {
        LedCharDriver();
    }
}

/*==================================
数码管驱动函数,进行倒计时并传递数据
===================================*/

void LedCharDriver()
{
    if(Flage == 1)
    {
        Flage = 0;
        Tcount--;
        if(Tcount <= 0) //设定时间90分钟, 5400秒。
        {
            Tcount = 5400;
        }
        LedShow(Tcount);  //传递剩余时间到显示函数
    }
}
/*============================================
数码管显示函数,递数据分离,并写入缓存LedBuf中
=============================================*/
void LedShow(unsigned int i)
{
    unsigned char j, k;
    unsigned char min = 0;
    unsigned char sec = 0;

    min = i / 60;
    sec = i % 60;

    for(j = 0; j < 2; j++)
    {
        LedBuf[j] = LedChar[sec % 10];
        sec = sec / 10;
    }
    for(k = 2; k < 4; k++)
    {
        LedBuf[k] = LedChar[min % 10];
        min = min / 10;
    }
}
/*==================================
数码管动态刷新,带消隐
==================================*/
void LedScan()
{
    static unsigned char i = 0;
    P0 = 0x00;
    switch (i)
    {
    case 0:
        LEDS4 = 0;
        LEDS1 = 1;
        i++;
        P0 = LedBuf[0];
        break;
    case 1:
        LEDS1 = 0;
        LEDS2 = 1;
        i++;
        P0 = LedBuf[1];
        break;
    case 2:
        LEDS2 = 0;
        LEDS3 = 1;
        i++;
        P0 = LedBuf[2];
        break;
    case 3:
        LEDS3 = 0;
        LEDS4 = 1;
        i=0;
        P0 = LedBuf[3];
        break;
    default :
        break;
    }
}
/*=================================
中断函数,用于计时,同时刷新数码管
===================================*/
void InterruputTimer0() interrupt 1
{
    static unsigned char cnt = 0;
    TH0 = 0xEE;
    TL0 = 0x00;
    cnt++ ;
    if(cnt >= 200)
    {
        cnt = 0;
        Flage = 1;
    }
    LedScan();
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值