一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1546|回复: 7
收起左侧

使用15单片机8位DS1302时钟,共阳数码管直驱不用三极管

[复制链接]
发表于 2019-12-16 14:17 | 显示全部楼层 |阅读模式
数码管段选接P2,位选接P1.加上按键,蜂鸣器,1302,正好使用了单片机全部IO口。如果亮度不足,可以在P1口加245或573扩流。
#include"ds1302.h"
#include"e2prom.h"
#define uchar unsigned char
#define uint unsigned int


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

sbit beep=P3^4;

bit S_flag;
uchar k1num,k4num,Al_num,Sh_num,num,shi,fen,miao;
char A_shi,A_fen,A_miao,S_shi,S_fen,S_miao;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0xbf,0xff,0x88,0xc7,0x89};
void delayms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void Time0_init()
{
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;
        TR0=1;
}
void Display(uchar shi1,uchar shi2,uchar fen1,uchar fen2,uchar miao1,uchar miao2)
{
        P1=0x01;
        P2=table[shi1];
        delayms(2);

        P1=0x02;
        P2=table[shi2];
        delayms(2);
        P2=table[11];//消隐

        P1=0x04;
        P2=table[10];//间隔       
        delayms(2);
        P2=table[11];//消隐

        P1=0x08;
        P0=table[fen1];       
        delayms(2);

        P1=0x10;
        P2=table[fen2];
        delayms(2);
        P2=table[11];//消隐


        P1=0x20;
        P2=table[10];//间隔
        delayms(2);
        P2=table[11];//消隐


        P1=0x40;
        P2=table[miao1];
        delayms(2);

        P1=0x80;
        P2=table[miao2];       
        delayms(2);
        P2=table[11];//消隐
                       
}
void Shan_Display()
{
        switch(k4num)
                {
                        case 1:        //开闹钟时间显示
                                switch(Al_num)
                                {
                                        case 1: //小时闪烁
                                                if(S_flag)
                                                        Display(11,11,A_fen/10,A_fen%10,12,13);
                                                else
                                                        Display(A_shi/10,A_shi%10,A_fen/10,A_fen%10,12,13);                       
                                                break;
                                        case 2: //分钟闪烁
                                                if(S_flag)
                                                        Display(A_shi/10,A_shi%10,11,11,12,13);
                                                else
                                                        Display(A_shi/10,A_shi%10,A_fen/10,A_fen%10,12,13);                       
                                                break;
                                        default :
                                                        Display(A_shi/10,A_shi%10,A_fen/10,A_fen%10,12,13);                       
                                }
                                break;
                        case 2:         //关闹钟时间显示
                                switch(Sh_num)
                                {
                                        case 1: //小时闪烁
                                                if(S_flag)
                                                        Display(11,11,S_fen/10,S_fen%10,5,14);
                                                else
                                                        Display(S_shi/10,S_shi%10,S_fen/10,S_fen%10,5,14);                       
                                                break;
                                        case 2:  //分钟闪烁
                                                if(S_flag)
                                                        Display(S_shi/10,S_shi%10,11,11,5,14);
                                                else
                                                        Display(S_shi/10,S_shi%10,S_fen/10,S_fen%10,5,14);                       
                                                break;
                                        default : Display(S_shi/10,S_shi%10,S_fen/10,S_fen%10,5,14);                       
                                }
                                break;
                        default: //当前时间显示
                                switch(k1num)
                                {
                                        case 1: //小时闪烁
                                                if(S_flag)
                                                        Display(11,11,now[1]/16,now[1]%16,now[0]/16,now[0]%16);
                                                else
                                                        Display(now[2]/16,now[2]%16,now[1]/16,now[1]%16,now[0]/16,now[0]%16);                       
                                                break;
                                        case 2: //分钟闪烁
                                                if(S_flag)
                                                        Display(now[2]/16,now[2]%16,11,11,now[0]/16,now[0]%16);
                                                else
                                                        Display(now[2]/16,now[2]%16,now[1]/16,now[1]%16,now[0]/16,now[0]%16);                       
                                                break;
                                        case 3: //秒闪烁
                                                if(S_flag)
                                                        Display(now[2]/16,now[2]%16,now[1]/16,now[1]%16,11,11);
                                                else
                                                        Display(now[2]/16,now[2]%16,now[1]/16,now[1]%16,now[0]/16,now[0]%16);                       
                                                break;
                                        default : Display(now[2]/16,now[2]%16,now[1]/16,now[1]%16,now[0]/16,now[0]%16);                       
                                }
               
                }
}
void Mode_keyscan()
{
        if(k4==0)
        {
                delayms(10);
                if(k4==0)
                {
                        k4num++;
                        if(k4num>=3)k4num=0;
                        switch(k4num)
                        {
                                case 1:k1num=0;
                                        break;
                                case 2:Al_num=0;
                                        break;
                                default:Sh_num=0;
                        }
               
                        while(!k4);
               
                }

        }
}
void Move_keyscan()
{
        if(k1==0)
        {
                delayms(10);
                if(k1==0)
                {
                        if(k4num==0)
                        {
                                k1num++;
                                if(k1num>=4)k1num=0;
                        }
                        else if(k4num==1)
                        {
                                Al_num++;
                                if(Al_num>=3)Al_num=0;
                        }
                        else if(k4num==2)
                        {
                                Sh_num++;
                                if(Sh_num>=3)Sh_num=0;
                        }
                        while(!k1);
               
                }

        }
}
void Add_keyscan()
{       
    if(k2==0)
        {
                delayms(10);
                if(k2==0)
                {
                        switch(k4num)
                        {
                                case 1:
                                        switch(Al_num)
                                        {
                                                case 1:       
                                                        A_shi++;
                                                        if(A_shi>=24)
                                                                A_shi=0;                               
                                                        while(!k2);
                                                        SectorErase(0x2000);
                                                        byte_write(0x2000,A_shi);
                                                        break;
                                                case 2:       
                                                        A_fen++;
                                                        if(A_fen>=60)
                                                                A_fen=0;
                                                        while(!k2);
                                                        SectorErase(0x2200);
                                                        byte_write(0x2200,A_fen);
                                                        break;       
                                                               
                                        }
                                        break;
                                case 2:
                                        switch(Sh_num)
                                        {
                                                case 1:       
                                                        S_shi++;
                                                        if(S_shi>=24)
                                                                S_shi=0;                               
                                                        while(!k2);
                                                        SectorErase(0x2400);
                                                        byte_write(0x2400,S_shi);
                                                        break;
                                                case 2:       
                                                        S_fen++;
                                                        if(S_fen>=60)
                                                                S_fen=0;
                                                        while(!k2);
                                                        SectorErase(0x2600);
                                                        byte_write(0x2600,S_fen);
                                                        break;       
                                                               
                                        }
                                        break;
                                default:
                                        switch(k1num)
                                        {
                                                uchar dat ;
                                                case 1:       
                                                        dat=DS1302_ReadData(0x85);
                                                        shi=dat+1;
                                                        if((shi&0x0f)>9)shi=shi+6;
                                                        if(shi>=0x24)shi=0;
                                                        while(!k2);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作       
                                                        DS1302_WriteData(0x84,shi);
                                                        DS1302_WriteData(0x8e, 0x80);//写保护                       
                                                        break;
                                                case 2:       
                                                        dat=DS1302_ReadData(0x83);
                                                        fen=dat+1;
                                                        if((fen&0x0f)>9)fen=fen+6;
                                                        if(fen>=0x60)fen=0;
                                                        while(!k2);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作       
                                                        DS1302_WriteData(0x82,fen);
                                                        DS1302_WriteData(0x8e, 0x80);//写保护                       
                                                        break;       
                                                case 3:       
                                                        dat=DS1302_ReadData(0x81);
                                                        miao=dat+1;
                                                        if((miao&0x0f)>9)miao=miao+6;
                                                        if(miao>=0x60)miao=0;
                                                        while(!k2);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作       
                                                        DS1302_WriteData(0x80,miao);
                                                        DS1302_WriteData(0x8e, 0x80);//写保护                       
                                                        break;               
                                        }
                                        break;
                       
                        }       
                }
               
        }       
       
}
void Reduce_keyscan()
{       
    if(k3==0)
        {
                delayms(10);
                if(k3==0)
                {
                        switch(k4num)
                        {
                                case 1:
                                        switch(Al_num)
                                        {
                                                case 1:       
                                                        A_shi--;
                                                        if(A_shi==-1)
                                                                A_shi=23;                               
                                                        while(!k3);
                                                        SectorErase(0x2000);
                                                        byte_write(0x2000,A_shi);
                                                        break;
                                                case 2:       
                                                        A_fen--;
                                                        if(A_fen==-1)
                                                                A_fen=59;
                                                        while(!k3);
                                                        SectorErase(0x2200);
                                                        byte_write(0x2200,A_fen);
                                                        break;                       
                                        }
                                        break;
                                case 2:
                                        switch(Sh_num)
                                        {
                                                case 1:       
                                                        S_shi--;
                                                        if(S_shi==-1)
                                                                S_shi=23;                               
                                                        while(!k3);
                                                        SectorErase(0x2400);
                                                        byte_write(0x2400,S_shi);
                                                        break;
                                                case 2:       
                                                        S_fen--;
                                                        if(S_fen==-1)
                                                                S_fen=59;
                                                        while(!k3);
                                                        SectorErase(0x2600);
                                                        byte_write(0x2600,S_fen);
                                                        break;               
                                        }
                                        break;
                        default:
                                        switch(k1num)
                                        {
                                                uchar dat ;
                                                case 1:       
                                                        dat=DS1302_ReadData(0x85);
                                                        if(dat==0)
                                                                shi=0x23;
                                                        else
                                                                shi=dat-1;
                                                        if((shi&0x0f)>9)shi=shi-6;
                                                        while(!k3);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作
                                                        DS1302_WriteData(0x84,shi);       
                                                        DS1302_WriteData(0x8e, 0x80);//写保护               
                                                        break;
                                                case 2:       
                                                        dat=DS1302_ReadData(0x83);
                                                        if(dat==0)
                                                                fen=0x59;
                                                        else
                                                                fen=dat-1;
                                                        if((fen&0x0f)>9)fen=fen-6;
                                                        while(!k3);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作
                                                        DS1302_WriteData(0x82,fen);       
                                                        DS1302_WriteData(0x8e, 0x80);//写保护               
                                                        break;       
                                                case 3:       
                                                        dat=DS1302_ReadData(0x81);
                                                        if(dat==0)
                                                                miao=0x59;
                                                        else
                                                                miao=dat-1;
                                                        if((miao&0x0f)>9)miao=miao-6;
                                                        while(!k3);
                                                        DS1302_WriteData(0x8e, 0x00);//允许写操作
                                                        DS1302_WriteData(0x80,miao);
                                                        DS1302_WriteData(0x8e, 0x80);//写保护                       
                                                        break;               
                                        }
                                        break;
                        }       
                }
               
        }       
       
}
void AL_SHRead()
{
        A_shi=byte_read(0x2000);
        A_fen=byte_read(0x2200);
        S_shi=byte_read(0x2400);
        S_fen=byte_read(0x2600);
}
void AL_SHCheck()
{
        uchar j;
        if(((now[2]/16-A_shi/10)|(now[2]%16-A_shi%10)|(now[1]/16-A_fen/10)|(now[1]%16-A_fen%10))==0)
        {

                for(j=0;j<5;j++)
                {
                        beep=0;
                        delayms(500);
                        beep=1;
                        delayms(500);
                }

        }
        else if(((now[2]/16-S_shi/10)|(now[2]%16-S_shi%10)|(now[1]/16-S_fen/10)|(now[1]%16-S_fen%10))==0)
        {       
               
        }
                               
}
void main()
{
        Time0_init();
        DS1302_Initial();
//        DS1302_SetTime(init);
        AL_SHRead();
        while(1)
        {
                DS1302_GetTime(now);
                Mode_keyscan();
                Move_keyscan();
                Add_keyscan();
                Reduce_keyscan();
                Shan_Display();
                AL_SHCheck();               
        }
}
void time0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        num++;
        if(num>=10)
        {
                num=0;
                S_flag=!S_flag;
        }
               
}


0808.JPG

新建文件夹.rar

39.41 KB, 下载次数: 10, 下载积分: 一乐金币 -1

发表于 2019-12-17 22:09 | 显示全部楼层
哇噢,辛苦了
发表于 2019-12-18 14:23 | 显示全部楼层
直接用单片机驱动多位LED数码管,会不会功耗过大?

点评

不会的,实验证明,把单片机的强推挽模式打开后,驱动0.8寸数码管亮度完全够用,  详情 回复 发表于 2019-12-29 15:42
发表于 2019-12-19 10:05 | 显示全部楼层
收藏了
发表于 2019-12-27 22:33 | 显示全部楼层
都是好玩
发表于 2019-12-28 09:32 | 显示全部楼层
精度怎么样?
 楼主| 发表于 2019-12-29 15:42 来自手机 | 显示全部楼层
3AG1 发表于 2019-12-18 14:23
直接用单片机驱动多位LED数码管,会不会功耗过大?

不会的,实验证明,把单片机的强推挽模式打开后,驱动0.8寸数码管亮度完全够用,
发表于 2020-5-20 02:59 | 显示全部楼层
直接用单片机驱动多位LED数码管,会不会功耗过大?

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-27 07:37 , Processed in 0.070486 second(s), 49 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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