找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3942|回复: 4
打印 上一主题 下一主题
收起左侧

数码管电子钟不能调时,咋整啊!

[复制链接]
跳转到指定楼层
楼主
程序如下:

#include <STC12C2052AD.H> //STC头文件

/**********************************************************************************************/
//“程序开发调试设置项”
#define DY_LI            9     //设置LED显示的亮度(值域:1~9)
#define DY_DELAY        12     //设置每一个点显示的时间长度(1~20)
/**********************************************************************************************/
sbit    DY_KEY = P3 ^ 7; //按键1

sbit    DY_LED1_L1    =P3 ^ 0; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_L2    =P3 ^ 1; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_L3    =P3 ^ 2; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_L4    =P3 ^ 3; //设置LED点阵屏连接的I/O口

sbit    DY_LED1_H1    =P1 ^ 0; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H2    =P1 ^ 1; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H3    =P1 ^ 2; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H4    =P1 ^ 3; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H5    =P1 ^ 4; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H6    =P1 ^ 5; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H7    =P1 ^ 6; //设置LED点阵屏连接的I/O口
sbit    DY_LED1_H8    =P1 ^ 7; //设置LED点阵屏连接的I/O口

#define DY_P1M0SET        0x00 //设置I/O口工作方式//00000000(左到右,高到低位)
#define DY_P1M1SET        0xff //设置I/O口工作方式//00101000
#define DY_P3M0SET        0x00 //设置I/O口工作方式//00000000
#define DY_P3M1SET        0x00 //设置I/O口工作方式//10010100

bit PD;//秒点显示标志
unsigned char MENU;//菜单切换标志位
data unsigned char  DY_PWM,bn, cou  = 0, TIME_YY,TIME_MO,TIME_DD,TIME_WW,TIME_HH,TIME_MM,TIME_SS;//设置时、分、秒存放区
data bit DAY_BIT = 0;//天数增加标志位(用于日期进位的启动)
unsigned int aa;
unsigned char code disdata[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40 //无小数点数码管段码表(0~9)
};
/*********************************************************************************************/
void delay (unsigned int a){ // 用于点扫描的延时
    unsigned int i;
    while( a-- != 0){
        for(i = 0; i < DY_DELAY; i++);
    }                     
}
/*********************************************************************************************/

/*****************************************************************************/
void dis_off (void){
    P1 = ~DY_P1M1SET; //关所有显示
    P3 = ~DY_P3M1SET;
    delay(10-DY_PWM);
}
/*********************************************************************************************/
void displayHH1 (unsigned char d){ //第1列横向显示程序
    unsigned char i;
    i = d & 0x01;
    if(i == 0x01){
        DY_LED1_L1 = 0;DY_LED1_H1 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x02;
    if(i == 0x02){
        DY_LED1_L1 = 0;DY_LED1_H2 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x04;
    if(i == 0x04){
        DY_LED1_L1 = 0;DY_LED1_H3 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x08;
    if(i == 0x08){
        DY_LED1_L1 = 0;DY_LED1_H4 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x10;
    if(i == 0x10){
        DY_LED1_L1 = 0;DY_LED1_H5 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x20;
    if(i == 0x20){
        DY_LED1_L1 = 0;DY_LED1_H6 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x40;
    if(i == 0x40){
        DY_LED1_L1 = 0;DY_LED1_H7 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x80;
    if(i == 0x80){
        DY_LED1_L1 = 0;DY_LED1_H8 = 1;}delay(DY_PWM);dis_off();
}
/*********************************************************************************************/
void displayHH2 (unsigned char d){ //第2列横向显示程序
    unsigned char i;
    i = d & 0x01;
    if(i == 0x01){
        DY_LED1_L2 = 0;DY_LED1_H1 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x02;
    if(i == 0x02){
        DY_LED1_L2 = 0;DY_LED1_H2 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x04;
    if(i == 0x04){
        DY_LED1_L2 = 0;DY_LED1_H3 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x08;
    if(i == 0x08){
        DY_LED1_L2 = 0;DY_LED1_H4 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x10;
    if(i == 0x10){
        DY_LED1_L2 = 0;DY_LED1_H5 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x20;
    if(i == 0x20){
        DY_LED1_L2 = 0;DY_LED1_H6 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x40;
    if(i == 0x40){
        DY_LED1_L2 = 0;DY_LED1_H7 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x80;
    if(i == 0x80){
        DY_LED1_L2 = 0;DY_LED1_H8 = 1;}delay(DY_PWM);dis_off();
                                
}
/*********************************************************************************************/
void displayHH3 (unsigned char d){ //第3列横向显示程序
    unsigned char i;
    i = d & 0x01;
    if(i == 0x01){
        DY_LED1_L3 = 0;DY_LED1_H1 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x02;
    if(i == 0x02){
        DY_LED1_L3 = 0;DY_LED1_H2 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x04;
    if(i == 0x04){
        DY_LED1_L3 = 0;DY_LED1_H3 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x08;
    if(i == 0x08){
        DY_LED1_L3 = 0;DY_LED1_H4 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x10;
    if(i == 0x10){
        DY_LED1_L3 = 0;DY_LED1_H5 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x20;
    if(i == 0x20){
        DY_LED1_L3 = 0;DY_LED1_H6 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x40;
    if(i == 0x40){
        DY_LED1_L3 = 0;DY_LED1_H7 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x80;
    if(i == 0x80){
        DY_LED1_L3 = 0;DY_LED1_H8 = 1;}delay(DY_PWM);dis_off();

}
/*********************************************************************************************/
void displayHH4 (unsigned char d){ //第4列横向显示程序
    unsigned char i;
    i = d & 0x01;
    if(i == 0x01){
        DY_LED1_L4 = 0;DY_LED1_H1 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x02;
    if(i == 0x02){
        DY_LED1_L4 = 0;DY_LED1_H2 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x04;
    if(i == 0x04){
        DY_LED1_L4 = 0;DY_LED1_H3 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x08;
    if(i == 0x08){
        DY_LED1_L4 = 0;DY_LED1_H4 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x10;
    if(i == 0x10){
        DY_LED1_L4 = 0;DY_LED1_H5 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x20;
    if(i == 0x20){
        DY_LED1_L4 = 0;DY_LED1_H6 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x40;
    if(i == 0x40){
        DY_LED1_L4 = 0;DY_LED1_H7 = 1;}delay(DY_PWM);dis_off();
    i = d & 0x80;
    if(i == 0x80){
        DY_LED1_L4 = 0;DY_LED1_H8 = 1;}delay(DY_PWM);dis_off();
}  
/*********************************************************************************************/
void diplay_data (unsigned char l,unsigned char d){
        switch (l){//显示的列位置        
                case 1://            
                    displayHH1(d); //将显示数据送入        
                    break;//        
                case 2://            
                    displayHH2(d); //将显示数据送入        
                    break;//        
                case 3://            
                    displayHH3(d); //将显示数据送入        
                    break;//        
                case 4://            
                    displayHH4(d); //将显示数据送入        
                    break;//        
        }
}
/*********************************************************************************************/
bit IsLeapYear(void){    //计算本年是否是润年
    unsigned int a;
    a = 2000+TIME_YY;//加2000表示成完整的年
    if((a%4==0 && a%100!=0)||(a%400==0)){ //润年的计算公式
            return 1;//是润年返回1
        }else{
             return 0;//不是润年返回0
        }
}
/**********************************************************************************************/   
void month_day(void){  
    unsigned char mon_day[]={31,28,31,30,31,30,31,31,30,31,30,31};
    TIME_DD++;//天加1
    TIME_WW++;//星期值加1
    if(TIME_WW > 7){
        TIME_WW = 1;//时期值限定
    }
    if(TIME_DD > mon_day[TIME_MO-1]){//检查天是否大于当月的最大值
        if(IsLeapYear()&&TIME_MO==2){ //计算本月是否是润年的2月份
            TIME_DD = 29;//如果是润年又是2月,则天为29
        }else{
            TIME_DD = 1; //否则就等于1
            TIME_MO++;//月加1
            if(TIME_MO > 12){
                TIME_MO = 1; //如果月大于12则月等于1
                TIME_YY++;//年加1 (公历年无限积加)
            }
        }
    }
}

/*********************************************************************************************/

void xianshi()    {

                    for(aa=0;aa<1000;aa++){
                    diplay_data (3,disdata[TIME_MM/10]);
                    diplay_data (4,disdata[TIME_MM%10]);
                    if(PD){
                    diplay_data (1,disdata[TIME_HH/10]);
                    diplay_data (2,disdata[TIME_HH%10]);
                    }else{
                    diplay_data (1,disdata[TIME_HH/10]);
                    diplay_data (2,disdata[TIME_HH%10]+0x80);           
                         }
                         }                                   
                    for(aa=1000;aa<2000;aa++){
                    diplay_data (1,disdata[TIME_MO/10]);
                     diplay_data (2,disdata[TIME_MO%10]);
                    diplay_data (3,disdata[TIME_DD/10]);
                    diplay_data (4,disdata[TIME_DD%10]);
                            }
                        
                    for(aa=2000;aa<3000;aa++){
                     diplay_data (2,disdata[10]);               
                    diplay_data (3,disdata[TIME_WW]);
                    diplay_data (4,disdata[10]);
                    if(aa==3000)
                        aa=0;  
                          }
                        }                 

/*********************************************************************************************/
void init (void){ //上电初始化
    P1M0 = DY_P1M0SET;
    P1M1 = DY_P1M1SET;
    P3M0 = DY_P3M0SET;
    P3M1 = DY_P3M1SET;
    dis_off();
    DY_PWM = DY_LI;
    TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
    TH0 = 0x3c;          // 预置产生50ms时基信号   
    TL0 = 0xb0;   
    TH1=0x3c;
    TL1=0xb0;
    EA = 1;    //中断总开关
    ET0 = 1;             // 定时/计数器0允许中断   
    TR0 = 1;             // 开闭定时/计数器0   
    ET1 = 1;             // 定时/计数器0允许中断   
    TR1 = 1;             // 开闭定时/计数器0   
    TIME_DD = 19; //时间在首次使用的值,之后会在EEPROM自动记录上一天的值
    TIME_MO    = 7; //初始时间:2009年5月18日周一,20时13分40秒
    TIME_YY = 17;
    TIME_WW = 3;
    TIME_HH    = 22;
    TIME_MM = 40;
    TIME_SS = 0;
}
/*********************************************************************************************/
void main (void){ //主程序
    unsigned char s;
    init();
    MENU=0;
    s=0;
    aa=0;
    while (1){
                if(DAY_BIT == 1){ //检查天数是否更新,是则计算公历
            month_day();//计算公历日期   
            DAY_BIT = 0;//计算完成后将日期变更标志位置0
                     }
               if(MENU==0)    //显示正常走时主界面
            xianshi();

            if(DY_KEY==0){
                EA = 0;    //中断总开关
                TR1 = 0;             // 关闭定时/计数器
                s++;
                if(s>200){
                    s=0;MENU++;
                    while(DY_KEY==0){
                        diplay_data (1,disdata[TIME_HH/10]);
                        diplay_data (2,disdata[TIME_HH%10]);
                    }
                }
            }//长短按键处理//长按转到MENU1
            if(DY_KEY==1 && s>10 && s<200){s=0;DY_PWM++;if(DY_PWM>4)DY_PWM=1;}//短按设置亮度
            
        }
        if(MENU==1){//设置时间:小时
            diplay_data (1,disdata[TIME_HH/10]);
            diplay_data (2,disdata[TIME_HH%10]);
            diplay_data (3,0x80);
            diplay_data (4,0x80);

            if(DY_KEY==0){

                s++;
                if(s>200){
                    s=0;MENU++;
                    while(DY_KEY==0){
                        diplay_data (3,disdata[TIME_MM/10]);
                        diplay_data (4,disdata[TIME_MM%10]);
                    }
                }
            }//长短按键处理//长按转到MENU1
            if(DY_KEY==1 && s>10 && s<200){s=0;TIME_HH++;if(TIME_HH>23)TIME_HH=0;}//短按设置亮度

        }
        if(MENU==2){//设置时间:分钟
            diplay_data (3,disdata[TIME_MM/10]+0x80);
            diplay_data (4,disdata[TIME_MM%10]+0x80);

            if(DY_KEY==0){
                s++;
                if(s>200){
                    s=0;MENU=0;
                    while(DY_KEY==0){
                        diplay_data (1,disdata[TIME_HH/10]);
                        diplay_data (2,disdata[TIME_HH%10]);
                        diplay_data (3,disdata[TIME_MM/10]);
                        diplay_data (4,disdata[TIME_MM%10]);
                    }
                }
            }//长短按键处理//长按转到MENU1
            if(DY_KEY==1 && s>10 && s<200){s=0;TIME_MM++;TIME_SS=0;if(TIME_MM>59)TIME_MM=0;}//短按设置亮度
        
            }            
        }
/**********************************************************************************************/   
void tiem0(void) interrupt 1{   // T/C0中断服务程序(产生50ms时基信号)   
    cou++;                      // 软计数器加1   
    if(cou > 19){                 // 计数值到100(1s)   
        cou = 0;               // 软计数器清零   
        TIME_SS++;                 // 秒计数器加1(进位10ms*100=1s)   
        PD =~ PD;                //秒点闪烁
        if(TIME_SS > 59){          // 秒计数值到60   
           
            TIME_SS = 0;           // 秒计数器清零   
            TIME_MM++;             // 分计数器加1(进位60s=1m)  
            if(TIME_MM > 59){      // 分计数到60   
                TIME_MM = 0;       // 分计数器清零   
                TIME_HH++;         // 时计数器加1(进位60m=1h)   
                if(TIME_HH > 23){  // 时计数到23   
                    TIME_HH = 0;   // 时计数器清零
                    DAY_BIT = 1;    //天增加标志位

                }  
            }   
        }   
    }   
    TH0 = 0x3c;                // 重置定时常数   
    TL0 = 0xb0;   
}
/**********************************************************************************************/   
void tiem1(void) interrupt 3{   // T/C0中断服务程序(产生50ms时基信号)   
    TH1=0x3c;
    TL1=0xb0;
        aa++ ;
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2017-7-20 21:57 | 只看该作者
本帖最后由 zl2168 于 2017-7-21 21:24 编辑

实例91  具有校正功能的时钟1302(LCD1602显示)
实例91 带校正时钟1302(LCD1602显示).rar (52.68 KB, 下载次数: 4)

Proteus仿真,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1,书中电路和程序设计有详细说明,程序语句条条有注解。仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。


回复

使用道具 举报

板凳
ID:111634 发表于 2017-7-20 21:58 | 只看该作者
本帖最后由 zl2168 于 2017-7-20 23:00 编辑

实例93  具有校正功能的时钟1302(LED数码管显示)
实例93 带校正时分秒的时钟1302(6位LED数码管显示).rar (732.75 KB, 下载次数: 4)

Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。


回复

使用道具 举报

地板
ID:111634 发表于 2017-7-20 21:59 | 只看该作者
本帖最后由 zl2168 于 2017-7-20 22:58 编辑

实例94  模拟电子钟(由80C51定时器产生秒时基)
实例94 模拟电子钟(由80C51定时器产生秒时基).rar (43.05 KB, 下载次数: 4)

Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行书中电路和程序设计有详细说明,程序语句条条有注解。仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。




回复

使用道具 举报

5#
ID:221185 发表于 2017-7-20 23:47 | 只看该作者
谢谢!我去参考下,我的那个程序哪里有冲突,能帮忙看看嘛?谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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