数码之家

 找回密码
 立即注册
搜索
查看: 3963|回复: 6

对“用DS3231做一个四位2.3寸数码管时钟(开源)” 程序升级

[复制链接]
发表于 2019-9-21 19:47:21 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 waxkj 于 2019-9-22 20:09 编辑

https://www.mydigit.cn/forum.php?mod=viewthread&tid=17495

充分利用DS3231片内资源,增加显示:星期,和温度,增加递减按键,改变单片机任意引脚驱动段位,本人水平也十分有限,感觉亮度不太理想,望高手给看看如何改!
个人只是在原作者程序上稍加修改,只做个个人学习用途。贴程序如下。怎么安排星期,时间,温度的位置那就是你自己的事了。com8我只是用来驱动“℃”的,对应段位全部链接在一起,用一个PNP来驱动,这样可以和全部的数码管随外界光线变化亮度一致。

#include <12c5a60s2.h>
#include"ds3231.h"


unsigned char code tab[]=
//{0xBE,0x06,0xDA,0xCE,0x66,0xEC,0xFC,0x86,0xFE,0xEE,0x00};//0-9,共阴
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
//{0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x80}、、带小数点

#define ADC_POWER   0X80
#define ADC_FLAG    0X10
#define ADC_START   0X08
#define ADC_SPEED0         0X00         //540 CLOCKS
#define ADC_SPEED1  0X02         //360 CLOCKS
#define ADC_SPEED2  0X04         //180 CLOCKS
#define ADC_SPEED3  0X06         //90  CLOCKS

unsigned char hour,min,week,flash;
unsigned char ch=0x05;
bit sec;//1HZ秒点闪烁
uchar TC,TB;
unsigned char j,i;

#define        com1        P11
#define        com2        P12
#define        com3        P13
#define        com4        P10
#define        com5        P14
#define        com6        P16
#define        com7        P17
#define        com8        P03
#define        seg8        P20
#define        seg2        P21
#define        seg3        P22
#define        seg4        P23
#define        seg5        P24
#define        seg6        P25
#define        seg7        P26
#define        seg1        P27

//sbit bit5=P1^4;
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^3;

unsigned char year,mon,day,wenduh,wendul,wendu,bright=0;
unsigned char dig1,dig2,dig3,dig4,dig5,dig6,dig7,col_flag;



void led_off(void)        //51开发板数码管,位选低电平导通。
{
        com1=com2=com3=com4=com5=com6=com7=com8=0;
}
void set_seg(unsigned char dat_led)
{
        seg1=dat_led&0x01;
        seg2=dat_led&0x02;
        seg3=dat_led&0x04;
        seg4=dat_led&0x08;
        seg5=dat_led&0x10;
        seg6=dat_led&0x20;
        seg7=dat_led&0x40;
        seg8=col_flag;
}
void display(unsigned char a,b,c,e)
{
static unsigned char i=0;
        led_off();
        seg1=seg2=seg3=seg4=seg5=seg6=seg7=seg8=0;
        
        
        if(dig1=a/16)dig1=a/16;else dig1=10;
        dig2=a%16;
        dig3=b/16;
        dig4=b%16;
        dig5=c;
        dig6=e/10;
        dig7=e%10;
        switch(i)//每次显示一个COM
        {
                case 0:        set_seg(tab[dig1]);col_flag=sec;com1=1;break;
                 case 1:        set_seg(tab[dig2]);col_flag=sec;com2=1;break;
                case 2:        set_seg(tab[dig3]);col_flag=0;com3=1;break;
                 case 3:        set_seg(tab[dig4]);col_flag=0;com4=1;break;
                case 4:        set_seg(tab[dig5]);col_flag=0;com5=1;break;
                case 5:        set_seg(tab[dig6]);col_flag=0;com6=1;break;
                case 6:        set_seg(tab[dig7]);col_flag=0;com7=1;com8=1;break;
    default:break;
        }
if(++i>=7)  i=0;        
}

void delay(unsigned int z)
{
        unsigned int x,y;
        for(x=z;x>0;x--)
        for(y=900;y>0;y--);
}
void Ttemp_read()

{
        char duwenduh,duwendul;
        write_ds3231(0x0e,0x20); //采集温度
        duwenduh=read_ds3231(0x11)-4;//读取温度高位
        duwendul=read_ds3231(0x12);//读取温度低位
        wenduh=duwenduh;
        wendul=duwendul;
}



void ADC_init()
{
  P1ASF=0x20;//把P1.5设为AD输入
        ADC_RES=0;
        ADC_RESL=0;
        ADC_CONTR = ADC_POWER | ADC_SPEED2 | ch;
        delay(1);
}

void keyscan()
{
        unsigned char temp;
        if(!k1)//按键按下
        {
                delay(12);
            if(!k1)
                {
                        while(!k1);
                        j++;
                        if(j>7) j=0;
                }
        }

        if(!k2)
        {
                delay(12);
                if(!k2)
                {
                        while(!k2);
                        switch(j)
                        {
                                case 0: break;
                                case 1:
                                {
                                        temp=read_ds3231(2);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=24)temp=0;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x02,temp);
                                        hour=read_ds3231(2);
                                        break;
                                }
                                case 2:
                                {
                                        temp=read_ds3231(1);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=60)temp=0;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x01,temp);
                                        min=read_ds3231(1);
                                        break;
                                }
                                case 3:
                                {
                                        write_ds3231(0x00,0);
                                        min=read_ds3231(0);
                                        break;        
                                }
                                case 4:
                                {
                                        temp=read_ds3231(0x06);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=99)temp=18;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x06,temp);
                                        year=read_ds3231(0x06);
                                        break;
                                }
                                case 5:
                                {
                                        temp=read_ds3231(0x05);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=13)temp=1;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x05,temp);
                                        mon=read_ds3231(0x05);
                                        break;
                                }
                                case 6:
                                {
                                        temp=read_ds3231(0x04);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=32)temp=1;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x04,temp);
                                        day=read_ds3231(0x04);
                                        break;
                                }
                                case 7:
                                {
                                        temp=read_ds3231(0x03);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp++;
                                        if(temp>=8)temp=1;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x03,temp);
                                        week=read_ds3231(0x03);
                                        break;
                                }
                        }
                }
        }
        if(!k3)
        {
                delay(2);
                if(!k3)
                {
                        while(!k3);
                        switch(j)
                        {
                                case 0: break;
                                case 1:
                                {
                                        temp=read_ds3231(2);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=0)temp=23;
          temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x02,temp);
                                        hour=read_ds3231(2);
                                        break;
                                }
                                case 2:
                                {
                                        temp=read_ds3231(1);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=0)temp=59;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x01,temp);
                                        min=read_ds3231(1);
                                        break;
                                }
                                case 3:
                                {
                                        write_ds3231(0x00,0);
                                        min=read_ds3231(0);
                                        break;        
                                }
                                                                case 4:
                                {
                                        temp=read_ds3231(0x06);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=17)temp=99;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x06,temp);
                                        year=read_ds3231(0x06);
                                        break;
                                }
                                case 5:
                                {
                                        temp=read_ds3231(0x05);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=0)temp=12;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x05,temp);
                                        mon=read_ds3231(0x05);
                                        break;
                                }
                                case 6:
                                {
                                        temp=read_ds3231(0x04);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=0)temp=31;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x04,temp);
                                        day=read_ds3231(0x04);
                                        break;
                                }
                                case 7:
                                {
                                        temp=read_ds3231(0x03);
                                         temp=((temp>>4)*10)+(temp&0x0f);
                                        temp--;
                                        if(temp<=0)temp=7;
                                        temp = ((temp/10)<<4)|(temp%10);
                                        write_ds3231(0x03,temp);
                                        week=read_ds3231(0x03);
                                        break;
                                }
}
}
}
}
void timer_init()
{
        TMOD=0x01;
        
        AUXR |= 0x80;                //定时器时钟1T模式
        //TMOD &= 0xF0;                //设置定时器模式
  P1M1=0x20;
        P1M0=0xff;
        P0M1=0x00;
        P0M0=0x0f;
        TH0=0xfB;
        TL0=0x92;
        ET0=1;
        TR0=1;
        //EX0=1;
//        IT0=1;
        EA=1;
}
void main()
{
        
        ADC_init();
        timer_init();
        DS3231_init();
        
        while(1)
        {   
                 keyscan();
                 Ttemp_read();

                        switch(j)
                        {                                       
                                 case 0:{ hour=read_ds3231(2); min= read_ds3231(1);week=read_ds3231(3);break;}
                                case 1:{ sec=1;if(flash)hour=read_ds3231(0x02);else hour=0xaa;  min=read_ds3231(1); break;}
                                case 2:{ sec=1;hour=read_ds3231(0x02); if(flash)min= read_ds3231(1);else min=0xaa;break;}
                                case 3:{ sec=1;hour=read_ds3231(0x02); if(flash)min= read_ds3231(0);else min=0xaa;break;}        
        case 4:{ sec=1;if(flash)hour=read_ds3231(0x06);else hour=0xaa;min=read_ds3231(5);break;}         
                          case 5:{ sec=1;hour=read_ds3231(0x06); if(flash)min= read_ds3231(5);else min=0xaa;break;}
                                case 6:{ sec=1;hour=read_ds3231(0x05); if(flash)min= read_ds3231(4);else min=0xaa;break;}
                                case 7:{ sec=1;hour=read_ds3231(0x04); if(flash)min= read_ds3231(3);else min=0xaa;break;}                                
                        }

                        ADC_CONTR = ADC_POWER | ADC_SPEED2 |ADC_START | ch;
                        delay(1);
/*
                        if      (ADC_RES<25 ) bright=9;
                        else if (ADC_RES<50 ) bright=8;
                        else if (ADC_RES<75 ) bright=7;
                        else if (ADC_RES<100) bright=6;
                        else if (ADC_RES<125) bright=5;
                        else if (ADC_RES<150) bright=4;
                        else if (ADC_RES<175) bright=3;
                        else if (ADC_RES<200) bright=2;
                        else if (ADC_RES<225) bright=1;
                        else                  bright=0;
                        
*/
                        bright=255-ADC_RES;
                        if(bright<=15)
                                bright=15;


        }
               
}

void timer0() interrupt 1
{
static unsigned char pwm=0;
        
        uchar flag;
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD=0x01;
  TH0=0xfb;
        TL0=0x92;
flag++;
        if(flag==255)
        {  
                TC++;
                flag=0;
                TB++;
                if(TB==28)
                {TB=0;        
                flash=!flash;}
         }

if(TC==46)         //        具体数据根据时钟频率调整,0.5秒换一次。
{
TC=0;
   sec=!sec;  
        }  
if(pwm<=bright)

  display(hour,min,week,wenduh);
else      
        led_off();
  pwm++;
if(pwm==255)
pwm=0;  

}









排列效果

排列效果

打赏

参与人数 3家元 +48 收起 理由
benli + 18 謝謝分享
zhkrid + 10 以資鼓勵
家睦 + 20

查看全部打赏

发表于 2019-9-21 20:06:44 来自手机浏览器 | 显示全部楼层
这个程序89c52能用么?
回复 支持 反对

使用道具 举报

发表于 2019-9-21 21:06:04 | 显示全部楼层
大佬,上个原理图学习一下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-21 21:46:39 | 显示全部楼层
触景情伤 发表于 2019-9-21 20:06
这个程序89c52能用么?

89C52需要改程序,1T的可以自动亮度。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-21 21:50:44 | 显示全部楼层
在路上795 发表于 2019-9-21 21:06
大佬,上个原理图学习一下。

原理图你参考原作者的吧,一样只是稍许增加。结合程序不难。
回复 支持 反对

使用道具 举报

发表于 2021-12-18 21:33:21 | 显示全部楼层
最近也作了一个倒计时器,不是时钟,但是也有时钟显示和按键处理。
全程不用延时程序。包括按键处理,都不要用延时程序。
回复 支持 反对

使用道具 举报

发表于 2021-12-19 13:51:20 来自手机浏览器 | 显示全部楼层
用这个大的数码管做个时钟,效果应该不错!
wechat_upload163989307861bec856d3070
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-23 18:11 , Processed in 0.109200 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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