找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5741|回复: 0
收起左侧

注释详细的单片机数码管时钟程序

[复制链接]
ID:75005 发表于 2015-3-21 16:42 | 显示全部楼层 |阅读模式
#include <reg51.h>

#define uchar unsigned char
#define uint  unsigned int
uchar hour=23,min=59,sec=45;        //定义小时、分钟和秒变量
uchar count_10ms;                         //定义10ms计数器
sbit        K1 = P3^2;                        //定义K1键
sbit        K2 = P3^3;                        //定义K2键
sbit        K3 = P3^4;                        //定义K3键
sbit        K4 = P3^5;                        //定义K4键
sbit  BEEP=P3^7;                        //定义蜂鸣器
bit K1_FLAG=0;                                //定义按键标志位,当按下K1键时,该位置1,K1键未按下时,该位为0。
uchar code bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选表,用来选择哪一只数码管进行显示
uchar code seg_data[]={0x28, 0x7E, 0xA2, 0x62, 0x74, 0x61, 0x21, 0x7A, 0x20, 0x60,0xff};//0,1,2,3,4,5,6,7,8,9,关显示,数码管码表
                                                        //0~F、熄灭符和字符"-"的显示码(字形码)
uchar disp_buf[8];                                //定义显示缓冲单元
/********以下是延时函数********/
void Delay_ms(uint xms)                               
{
        uint i,j;
        for(i=xms;i>0;i--)                              //i=xms即延时约xms毫秒
                for(j=110;j>0;j--);
}
/*********以下是蜂鸣器响一声函数********/
void  beep()
{
  BEEP=0;                       //蜂鸣器响
  Delay_ms(100);
  BEEP=1;                   //关闭蜂鸣器
  Delay_ms(100);   
}
/********以下是走时转换函数,负责将走时数据转换为适合数码管显示的数据********/       
void conv(uchar in1,in2,in3)                //形参in1、in2、in3接收实参hour、min、sec传来的数据
{
        disp_buf[0] =in1/10;                        // 小时十位
        disp_buf[1] = in1%10;                // 小时个位
        disp_buf[3] = in2/10;                // 分钟十位
        disp_buf[4] = in2%10;                // 分钟个位
        disp_buf[6] = in3/10;                // 秒十位
        disp_buf[7] = in3%10;                // 秒个位
        disp_buf[2] = 17;                        // 第3只数码管显示"-"(在 seg_data表的第17位)
        disp_buf[5] = 17;                        // 第6只数码管显示"-"
}

/********以下是显示函数********/
void Display()
{
        uchar tmp;                                //定义显示暂存
        static uchar disp_sel=0;                //显示位选计数器,显示程序通过它得知现正显示哪个数码管,初始值为0
        tmp=bit_tab[disp_sel];                //根据当前的位选计数值决定显示哪只数码管
        P2=tmp;                                //送P2控制被选取的数码管点亮
        tmp=disp_buf[disp_sel];                //根据当前的位选计数值查的数字的显示码
        tmp=seg_data[tmp];                        //取显示码
        P0=tmp;                                //送到P0口显示出相应的数字
        disp_sel++;                                //位选计数值加1,指向下一个数码管
        if(disp_sel==8)                       
        disp_sel=0;                                //如果8个数码管显示了一遍,则让其回0,重新再扫描
}
/********以下是定时器T0中断函数, 用于数码管的动态扫描********/
void timer0() interrupt 1
{
        TH0 = 0xf8;TL0 = 0xcc;                //重装计数初值,定时时间为2ms       
        Display();                                //调显示函数
}
/********以下是定时器T1中断函数, 用于产生用于产生秒、分钟和小时信号********/
void timer1() interrupt 3
{
        TH1 = 0xdc;TL0 = 0x00;                //重装计数初值,定时时间为10ms
        count_10ms++;                        //10ms计数器加1
        if(count_10ms >= 100)               
        {
                count_10ms = 0;                //计数100次后恰好为1s,此时10ms计数器清0
                sec++;                                //秒加1
                if(sec == 60)
                {
                        sec = 0;
                        min++;                //若到60秒,分钟加1
                        if(min ==60)
                        {
                                min = 0;
                                hour++;                //若到60分钟,小时加1
                                if(hour ==24)
                                {
                                        hour = 0;min=0;sec=0; //若到24小时,小时、分钟和秒单元清0
                                }
                        }
                }
        }
}       
/********以下是按键处理函数,用来对按键进行处理********/
void  KeyProcess()
{
        TR1=0;                                //若按下K1键,则定时器T1关闭,时钟暂停
        if(K2==0)                                //若按下K2键
         {
                Delay_ms(10);                //延时去抖
                if(K2==0)
                {
                        while(!K2);                //等待K2键释放
                        beep();
                        hour++;                //小时调整
                        if(hour==24)
                        {
                                hour = 0;
                        }
                }
        }
        if(K3==0)                                //若按下K3键
         {
                Delay_ms(10);
                if(K3==0)
                {
                        while(!K3);                //等待K3键释放
                        beep();
                           min++;                //分钟调整
                        if(min==60)
                        {
                                min = 0;
                        }               
                }
        }
        if(K4==0)                                //若按下K4键
         {
                Delay_ms(10);
                if(K4==0)
                {
                        while(!K4);                //等待K4键释放
                        beep();
                        TR1=1;                //调整完毕后,时钟恢复走时
                        K1_FLAG=0;                //将K1键按下标志位清0
                }
        }       
}
/*********以下是定时器T0/T1初始化函数********/
void  timer_init()
{
        TMOD = 0x11;                        // 定时器0, 1工作模式1, 16位定时方式
        TH0 = 0xf8;TL0 = 0xcc;                //装定时器T0计数初值,定时时间为2ms
        TH1 = 0xdc;TL1 = 0x00;                // 装定时器T1计数初值,定时时间为10ms
        EA=1;ET0=1;ET1=1;                        //开总中断和定时器T0、T1中断
        TR0 = 1;TR1 = 1;                        //启动定时器T0、T1
}
/********以下是主函数********/       
void main(void)
{
        P0 = 0xff;
        P2 = 0xff;
        timer_init();                                        //调定时器T0、T1初始化函数
        while(1)
        {
                if(K1==0)                                //若K1键按下
                {
                        Delay_ms(10);                //延时10ms去抖
                        if(K1==0)
                        {
                                while(!K1);                //等待K1键释放
                                beep();                //蜂鸣器响一声
                                K1_FLAG=1;                //K1键标志位置1,以便进行时钟调整
                        }
                }
                if(K1_FLAG==1)KeyProcess();                        //若K1_FLAG为1,则进行走时调整       
                conv(hour,min,sec);                                                //调走时转换函数               
        }
}



回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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