找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5436|回复: 8
收起左侧

求程序 三个独立按键的时钟

[复制链接]
ID:160104 发表于 2017-1-5 13:33 | 显示全部楼层 |阅读模式
设置三个独立按键,第一个用来选择设置时间的“秒”或“分”或“时”。第二个键按一次数码管数字加一,第三个键按一次数码管数字减一。。。数码管要八位的,第1,2位显示小时(从左向右),第3,6位显示“-”,第4,5位显示分钟,第7,8位显示秒。 谁会??
回复

使用道具 举报

ID:7485 发表于 2017-1-5 15:43 | 显示全部楼层
出题目,问谁会不会?
回复

使用道具 举报

ID:152682 发表于 2017-1-5 19:05 | 显示全部楼层
我会!但我不选择帮你!有在这里等消息的时间!花两个小时足以搞完了!自己去学吧!论坛资料很多!
回复

使用道具 举报

ID:140489 发表于 2017-1-20 10:02 | 显示全部楼层
/*********************************************************************************

这个符合你的要求 ,仿真 实物都通过
**********************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

//#define W P0                                                                          //位选
//#define D P0                                                                        //段选

/*sbit IO=P1^1;                                                                          //数据口
sbit SCLK=P1^0;                                                                         //控制数据时钟
sbit RST=P1^2;                                                                          //使能端、复位端   */
                                                                                                                                  

sbit sclk = P1^0;
sbit dio = P1^1;
sbit ce = P1^2;
sbit wela = P2^7;
sbit dula = P2^6;



sbit s1=P3^0;                                                                        //按键 加
sbit s2=P3^1;                                                                        //按键 减
sbit s3=P3^3;                                                                        //按键 选择
bit flag;//是否读取时间的标志位

char knum=0,snum,fnum;

char shi,fen,miao;

bit miao_flag;
uchar miao_num,ss;


/***********写时分秒地址************/
#define write_shi  0x84
#define write_fen  0x82
#define write_miao 0x80
/***********读时分秒地址************/
#define read_shi  0x85
#define read_fen  0x83
#define read_miao 0x81
uchar d[]={ 0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F};                //共阴不带小数点

uchar dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
                                };//        共阴带小数点

//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};                //共阳带小数点

//uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90};                //共阳不带小数点
//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};                //共阳带小数点         */

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=120;y>0;y--);
}

/*uchar code table[]={

                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义

                         };
void display(uchar shi10,shi,fen10,fen,miao10,miao)
{
        dula=1;
        P0=table[shi10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfe;
        wela=0;
        delay(1);

        dula=1;
        P0=table[shi]|0x80;         //         table[shi]|0x80, table[shi]或0x80就可以显示小数点
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfd;
        wela=0;
        delay(1);

        dula=1;
        P0=table[fen10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xfb;
        wela=0;
        delay(1);

        dula=1;
        P0=table[fen]|0x80;
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xf7;
        wela=0;
        delay(1);

        dula=1;
        P0=table[miao10];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xef;
        wela=0;
        delay(1);

        dula=1;
        P0=table[miao];
        dula=0;
        P0=0xff;
        wela=1;
        P0=0xdf;
        wela=0;
        delay(1);
}  */                  


void t0_init()  //定时50ms一个中断
{
   
  TMOD=0X01;
  TH0=(65536-45872)/256;
  TL0=(65536-45872)%256;
  EA=1;
  ET0=1;
  TR0=1;

}

void temer1() interrupt 1
{
  TH0=(65536-45872)/256;
  TL0=(65536-45872)%256;
  ss++;
  if(ss==20)
  ss=0;

}

void display(uchar shi,uchar fen,uchar miao)                          //显示函数
{
        //        if(miao%2==0)
                if(ss<=10)                 //        这里写为ss<=10,第三位数码管显示“— ”闪烁与 第六位数码管显示“= ”
                {                                  //闪烁相反,一个亮时,另一个灭
            wela=1;
                P0=0xfb;
                wela=0;

                dula=1;
        //        P0=0x40;          //第三位数码管显示“— ”
               
                P0=0x09;          //第三位数码管显示“= ”
                dula=0;
                P0=0xff;
                delay(1);
       
                }

                else
                {
                wela=1;
                P0=0xfb;
                wela=0;

                dula=1;
                P0=0;          //第三位数码管不显示
                dula=0;
                P0=0xff;
                delay(1);       
                }
       
        //        if(miao%2==0)         //if(miao%2==0) 1秒闪烁1次
                if(ss>=10)                 //if(ss>=10)闪烁频率可调
                {
                wela=1;
                P0=0xdf;
                wela=0;
                dula=1;
                P0=0x40;          //第六位数码管显示“— ”
                dula=0;
                P0=0xff;

                delay(1);
                }

                else
                {
                wela=1;
                P0=0xdf;
                wela=0;
                dula=1;
                P0=0;          //第六位数码管不显示
                dula=0;
                P0=0xff;

                delay(1);
                }
       
       
        if(knum==0)
        {
                snum=30;
                fnum=30;
        }
       
        if(knum==1)
        {
                fnum++;
                snum=30;
        }
       
        if(knum==2)
        {
                snum++;
                fnum=30;
        }
       
       
        if(snum>=30)
        {       
                if((shi/10)<1)         //如果小时十位小于1,
                {
                wela=1;
                P0=0xfe;
                wela=0;

                dula = 1;
                P0=0xff;           // 小时十位就不显示
                dula = 0;
                }
               
                else
                {
                wela=1;
                P0=0xfe;
                wela=0;

                dula=1;
                P0=d[shi/10];
                dula=0;
                P0=0xff;
                delay(1);
                }
          
         /*  if(miao%2==0)                                                        //小数点闪烁
                {
                        wela=1;
                        P0=0xfd;
                        wela=0;

                        dula=1;
                        P0=d[shi%10];                 //时的个位,P0=d[shi%10]时的个位小数点不亮
                        dula=0;                                 //时的个位,P0=dd[shi%10]时的个位小数点亮
                        P0=0xff;
                        delay(1);
                       
                       
                }  */
               
        //        else
        //        {
                        wela=1;
                        P0=0xfd;
                        wela=0;

                        dula=1;
                        P0=d[shi%10];                        //时的个位,P0=d[shi%10]时的个位小数点闪烁
                        dula=0;                                        // 时的个位,P0=dd[shi%10]时的个位小数点不闪烁
                        P0=0xff;
                        delay(1);
               
                       
        //        }
            
               
       
       
                if(snum==60)
                        snum=0;
        }               
       
       
        if(fnum>=30)
        {
                wela=1;
                P0=0xf7;
                wela=0;

                dula=1;
                P0=d[fen/10];
                dula=0;
                P0=0xff;
                delay(1);
               
               
                wela=1;
                P0=0xef;
                wela=0;

                dula=1;
                P0=d[fen%10];
                dula=0;
                P0=0xff;
                delay(1);
       
               
                if(fnum==60)
                        fnum=0;
        }
                wela=1;
                P0=0xbf;
                wela=0;

            dula=1;
                P0=d[miao/10];                           //秒十位
                dula=0;
                P0=0xff;
                delay(1);
       

                wela=1;
                P0=0x7f;
                wela=0;

                dula=1;
                P0=d[miao%10];                         //秒个位
                dula=0;
                P0=0xff;
                delay(1);
       
               
       
       
}  



void write_1302(uchar add,dat)                 //写函数  qx
{
        uchar i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        _nop_();
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        temp=dat;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        ce=0;
        sclk=0;
}
uchar read_1302(uchar add)                                   //读函数                qx
{
        uchar dat,dat1,i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if(dio)
                    dat|=0x80;
                if(i<7)
                        dat>>=1;
                sclk=1;
        }
        dat1=dat/16;
        dat=dat%16;
        dat=dat1*10+dat;  
        ce=0;
        sclk=0;
        return dat;
}                                 

void init_1302()                                                        //初始化函数 设置时间
{
        write_1302(0x8e,0x00);                                        //保护取消,可以进行读写操作
        write_1302(write_miao,0x57);       
        write_1302(write_fen,0x55);
        write_1302(write_shi,0x15);
        write_1302(0x8e,0x80);                                        //保护启动,不能进行读写操作
}         

void read_sf()
{
        shi=read_1302(read_shi);
        fen=read_1302(read_fen);
        miao=read_1302(read_miao);
        display(shi,fen,miao);
}

void keyscan()                                                                   //按键扫描函数
{                                                                                  
        if(s3==0)                                                                   //选择按键按下
        {
                delay(10);                                                        //延时
                if(s3==0)
                {
                        while(!s3)                                                //松手检测
                                display(shi,fen,miao);        //加上这句,按键按下就不会闪
                        knum++;
                        if(knum==1)                                                  //分闪烁
                        {
                                 write_1302(0x8e,0x00);                //保护取消
                                 write_1302(write_miao,0x80); //  write_1302(write_miao,0x80);
                       
                        }
                       
                       
                        if(knum==3)                                                   //时钟启动
                        {
                                knum=0;
                                write_1302(write_miao,0x00);
                                write_1302(0x8e,0x80);                //保护启动
                        }
                }
        }


        if(knum==1)                                                                //分钟调节
        {
                if(s1==0)                                                        //加
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen++;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==0x60)
                                        fen=0x00;
                                write_1302(write_fen,fen);        //写入1302
                                read_sf();                                        //读出时间,然后显示
                               
                               
                       
                        }
                  
                }
               
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen--;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==-1)
                                        fen=0x59;
                                write_1302(write_fen,fen);
                                read_sf();
                        }
                }

                       
        }
       
       
        if(knum==2)
        {
                if(s1==0)
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi++;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==0x24)
                                        shi=0x00;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                          display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi--;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==-1)
                                        shi=0x23;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
        }
}




void main()
{
        t0_init();
        init_1302();
        while(1)
        {
          
            read_sf();
            
            keyscan();
                write_1302(0x8e,0x00);

                shi=read_1302(0x85);
               
                fen=read_1302(0x83);
               
                miao=read_1302(0x81);       
                write_1302(0x8e,0x00);
               
                display(shi,fen,miao);

       
                }
       
       
}

回复

使用道具 举报

ID:111634 发表于 2017-1-21 13:09 | 显示全部楼层
给你介绍2个你要求的案例
实例94 模拟电子钟(由80C51定时器产生秒时基
先Proteus仿真一下,确认有效。
实例94 模拟电子钟(由80C51定时器产生秒时基).rar (43.05 KB, 下载次数: 24)
回复

使用道具 举报

ID:111634 发表于 2017-1-21 13:10 | 显示全部楼层
本帖最后由 zl2168 于 2017-1-21 13:11 编辑

实例93  具有校正功能的时钟1302(LED数码管显示)


Proteus仿真一下,确认有效。
实例93 带校正时分秒的时钟1302(6位LED数码管显示).rar (732.75 KB, 下载次数: 22)
回复

使用道具 举报

ID:111634 发表于 2017-1-21 13:14 | 显示全部楼层
你可比较一下上述2个案例与前面的程序,看那个容易理解(没有贬低前面程序的意图)。
回复

使用道具 举报

ID:140489 发表于 2017-1-22 09:07 | 显示全部楼层
zl2168 发表于 2017-1-21 13:14
你可比较一下上述2个案例与前面的程序,看那个容易理解(没有贬低前面程序的意图)。

上述2个案例虽好,但按键需要一个带自锁的,这样做实物不是很方便;做产品我还没有看到有人用自锁开关的
回复

使用道具 举报

ID:111634 发表于 2017-1-24 20:23 | 显示全部楼层
本帖最后由 zl2168 于 2017-1-24 20:28 编辑
lids 发表于 2017-1-22 09:07
上述2个案例虽好,但按键需要一个带自锁的,这样做实物不是很方便;做产品我还没有看到有人用自锁开关的

这个意见有一定道理,不过改起来也很简单。上述2例的精华就是按键控制,程序条条有注释,清晰简单,容易理解,特别是对初学者。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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