51单片机入门项目:多功能电子时钟

本项目里的电子时钟总共有三个功能:

①显示时分秒

②显示日期

③显示闹钟。(时钟的值等于闹钟设置的时间时,蜂鸣器响一分钟。)

其中,显示功能是通过两个4位一体数码管来实现的。为了节省单片机引脚,我们用3-8译码器来控制单位8段数码管的输出。
同时,我们用四个按键来实现时间设置和任务切换。

按键一实现数字增,达到最大值保持不变;

按键二实现数字减,减到最小值保持不变;

按键三实现光标移动,在时分秒或年月日之间来回切换,从而保证对每一位进行增减操作;

按键四实现功能切换。

这个项目涉及到了定时器中断,数码管显示原理,按键检测等知识。作为一个入门项目,它有助于大家更好的理解和掌握关于51单片机的基本知识。

废话少说,直接上结果:

51单片机入门项目:多功能电子时钟

项目源码:
#include<REG52.h>

#define uint unsigned int
#define uchar unsigned char

sbit k1 = P3 ^ 1;
sbit k2 = P3 ^ 0;
sbit k3 = P3 ^ 2;
sbit k4 = P3 ^ 3;


sbit key1 = P2 ^ 2;
sbit key2 = P2 ^ 3;
sbit key3 = P2 ^ 4;

sbit beep = P2 ^ 5;

bit flag1, flag2, flag3, flag4;

uchar table[] = {0x3f, 0x30, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x80};
uchar hour = 10, minute = 5, second = 30; //设置时分秒初始值
uchar al_hour = 12, al_minute = 30; //设置闹钟初始值
uint year = 2023, month = 11, day = 26; //设置年月日初始值
uchar set_mode = 0, mode = 0;

void Timer0Init(void)       //1000微秒@11.0592MHz
{
    TMOD &= 0xF0;       //设置定时器模式
    TMOD |= 0x01;       //设置定时器模式
    TL0 = 0x66;     //设置定时初值
    TH0 = 0xFC;     //设置定时初值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0 = 1;
    EA = 1;
    PT0 = 0;
}

void delay(uint i)
{
    while (i)
    {
        i--;
    }
}


//显示时分秒
void show_time()
{
    uint i;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
        case 0:
            key3 = 0;
            key2 = 0;
            key1 = 0;
            P0 = table[second % 10];
            break;
        case 1:
            key3 = 0;
            key2 = 0;
            key1 = 1;
            P0 = table[second / 10];
            break;
        case 2:
            key3 = 0;
            key2 = 1;
            key1 = 0;
            P0 = table[10];
            break;
        case 3:
            key3 = 0;
            key2 = 1;
            key1 = 1;
            P0 = table[minute % 10];
            break;
        case 4:
            key3 = 1;
            key2 = 0;
            key1 = 0;
            P0 = table[minute / 10];
            break;
        case 5:
            key3 = 1;
            key2 = 0;
            key1 = 1;
            P0 = table[10];
            break;
        case 6:
            key3 = 1;
            key2 = 1;
            key1 = 0;
            P0 = table[hour % 10];
            break;
        default:
            key3 = 1;
            key2 = 1;
            key1 = 1;
            P0 = table[hour / 10];
        }
        delay(100);
        P0 = 0x00;
    }
}

//显示年月日
void show_date()
{
    uint i;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
        case 0:
            key3 = 0;
            key2 = 0;
            key1 = 0;
            P0 = table[day % 10];
            break;
        case 1:
            key3 = 0;
            key2 = 0;
            key1 = 1;
            P0 = table[day / 10];
            break;
        case 2:
            key3 = 0;
            key2 = 1;
            key1 = 0;
            P0 = table[month % 10];
            delay(100);
            P0 = table[11];
            break;
        case 3:
            key3 = 0;
            key2 = 1;
            key1 = 1;
            P0 = table[month / 10];
            break;
        case 4:
            key3 = 1;
            key2 = 0;
            key1 = 0;
            P0 = table[year % 10];
            delay(100);
            P0 = table[11];
            break;
        case 5:
            key3 = 1;
            key2 = 0;
            key1 = 1;
            P0 = table[year % 100 / 10];
            break;
        case 6:
            key3 = 1;
            key2 = 1;
            key1 = 0;
            P0 = table[year / 100 % 10];
            break;
        default:
            key3 = 1;
            key2 = 1;
            key1 = 1;
            P0 = table[year / 1000];
        }
        delay(100);
        P0 = 0x00;
    }
}

//显示闹钟
void show_alarm()
{
    uint i;
    for (i = 0; i < 6; i++)
    {
        switch (i)
        {
        case 0:
            key3 = 0;
            key2 = 1;
            key1 = 1;
            P0 = table[al_minute % 10];
            break;
        case 1:
            key3 = 1;
            key2 = 0;
            key1 = 0;
            P0 = table[al_minute / 10];
            break;
        case 2:
            key3 = 1;
            key2 = 0;
            key1 = 1;
            P0 = table[10];
            break;
        case 3:
            key3 = 1;
            key2 = 1;
            key1 = 0;
            P0 = table[al_hour % 10];
            break;
        default:
            key3 = 1;
            key2 = 1;
            key1 = 1;
            P0 = table[al_hour / 10];
        }
        delay(100);
        P0 = 0x00;
    }
}

//设置时分秒的值
void set_time()
{
    if (k1 == 0)
    {
        if (flag1 == 0)
        {
            if (set_mode == 0 && hour < 24)
            {
                hour++;
            }
            if (set_mode == 1 && minute < 60)
            {
                minute++;
            }
            if (set_mode == 2)
            {
                second = 0;
            }
            flag1 = 1;
        }
    }
    if (k1 == 1)
    {
        flag1 = 0;
    }
    if (k2 == 0)
    {
        if (flag2 == 0)
        {
            if (set_mode == 0 && hour > 0)
            {
                hour--;
            }
            if (set_mode == 1 && minute > 0)
            {
                minute--;
            }
            if (set_mode == 2)
            {
                second = 0;
            }
            flag2 = 1;
        }
    }
    if (k2 == 1)
    {
        flag2 = 0;
    }
}

//设置年月日的值
void set_date()
{
    if (k1 == 0)
    {
        if (flag1 == 0)
        {
            if (set_mode == 0)
            {
                year++;
            }
            if (set_mode == 1 && month < 12)
            {
                month++;
            }
            if (set_mode == 2 && day < 30)
            {
                day++;
            }
            flag1 = 1;
        }
    }
    if (k1 == 1)
    {
        flag1 = 0;
    }
    if (k2 == 0)
    {
        if (flag2 == 0)
        {
            if (set_mode == 0)
            {
                year--;
            }
            if (set_mode == 1 && month > 1)
            {
                month--;
            }
            if (set_mode == 2 && day > 1)
            {
                day--;
            }
            flag2 = 1;
        }
    }
    if (k2 == 1)
    {
        flag2 = 0;
    }
}

//设置闹钟
void set_alarm()
{
    if (k1 == 0)
    {
        if (flag1 == 0)
        {
            if (set_mode == 0 && al_hour < 24)
            {
                al_hour++;
            }
            if (set_mode == 1 && al_minute < 60)
            {
                al_minute++;
            }
            if (set_mode == 2)
            {
                set_mode = 0;
            }
            flag1 = 1;
        }
    }
    if (k1 == 1)
    {
        flag1 = 0;
    }
    if (k2 == 0)
    {
        if (flag2 == 0)
        {
            if (set_mode == 0 && al_hour > 0)
            {
                al_hour--;
            }
            if (set_mode == 1 && al_minute > 0)
            {
                al_minute--;
            }
            if (set_mode == 2)
            {
                set_mode = 0;
            }
            flag2 = 1;
        }
    }
    if (k2 == 1)
    {
        flag2 = 0;
    }
}

//实现功能切换
void change_mode()
{
    if (k4 == 0)
    {
        if (flag4 == 0)
        {
            flag4 = 1;
            mode++;
            set_mode = 0;
            if (mode == 3) mode = 0;
        }
    }
    if (k4 == 1)
    {
        flag4 = 0;
    }
}

//移动光标位置,以便对每一位都能进行设置
void change_set()
{
    if (k3 == 0)
    {
        if (flag3 == 0)
        {
            flag3 = 1;
            set_mode++;
            if (set_mode == 3) set_mode = 0;
        }
    }
    if (k3 == 1)
    {
        flag3 = 0;
    }
}

//定时器中断函数,每1ms进入一次中断
void Timer0_Routine() interrupt 1
{
    static uint T0count;
    TL0 = 0x66;     //设置定时初值
    TH0 = 0xFC;     //设置定时初值
    T0count++;
    if (T0count == 1000)
    {
        T0count = 0;
        second++;
    }
    if (second == 60)
    {
        second = 0;
        minute++;
    }
    if (minute == 60)
    {
        minute = 0;
        hour++;
    }
    if (hour == 24)
    {
        second = 0;
        minute = 0;
        hour = 0;
    }


}


void main()
{
    Timer0Init();
    while (1)
    {
        change_mode();
        change_set();

        if (hour == al_hour && minute == al_minute)
        {
            beep = ~beep;
            delay(100);
        }

        P0 = 0x00;
        if (mode == 0)
        {
            beep = 0;
            show_time();
            set_time();
        }
        if (mode == 1)
        {
            beep = 0;
            show_date();
            set_date();
        }
        if (mode == 2)
        {
            beep = 0;
            show_alarm();
            set_alarm();
        }
    }
}

关于本项目的proteus 仿真文件我已经打包整理好了。如果你们需要的话,在评论区留言“求项目仿真资料”,我私信发给大家。

如果在操作过程中遇到什么问题,欢迎大家在评论区留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值