DS1302的原理与编程

本文介绍了如何利用DS1302时钟芯片实现时间显示和计时功能,通过C语言编程控制寄存器操作,结合独立按键切换模式,以及在主函数和中断处理中管理时间更新和数码管显示。
摘要由CSDN通过智能技术生成

我们要实现时间显示并且按s加,计时模式并且用独立按键控制两种不同模式

一、原理

在DS1302内部有时钟寄存器

就是寄存时分秒等的寄存器,就是我们需要用的

可以看到它的原理图上端链接两个vcc,左边两个分别连接晶振,一个接地,一个复位,一个与IAPF2K61S2相连,一个是时钟。

我们需要的就是通过控制其中的寄存器来得到我们需要的时分秒

二、编程

就需要给到的DS1302.c/.h了

void Write_Ds1302(unsigned  char temp) 
{
    unsigned char i;
    for (i=0;i<8;i++)         
    { 
        SCK=0;
        SDA=temp&0x01;
        temp>>=1; 
        SCK=1;
    }
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;     _nop_();  
     Write_Ds1302(address);    
     Write_Ds1302(dat);        
     RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
     unsigned char i,temp=0x00;
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;    _nop_();
     Write_Ds1302(address);
     for (i=0;i<8;i++)     
     {        
        SCK=0;
        temp>>=1;    
         if(SDA)
         temp|=0x80;    
         SCK=1;
    } 
     RST=0;    _nop_();
     SCK=0;    _nop_();
    SCK=1;    _nop_();
    SDA=0;    _nop_();
    SDA=1;    _nop_();
    return (temp);            
}
 

在使用DS1302时我们需要先清零,之后把复位端拉高,产生时钟上升沿,最后才能读取或写入数据,一定要先读或写对应的地址,之后再读或写需要的数据。

在读取中我们需要先写对应地址,找到对应寄存器之后再读取数据。

注意:上升沿是写入,下降沿是读取

再去写设置和读取函数

在写对应时分秒时需要用到设置,先定义中间变量,之后把wp复位允许写入,之后把给定的数组里,三位分别把数分开,转换成16进制,再存入寄存器对应时分秒的位置,最后再把wp赋值1禁止写入。

读取函数,先读取寄存器里的地址,把对应数存到中间变量里,再存入数组中去。

主函数

void main()
{
    Cls_Peripheral();
    Timer1Init();
    EA=1;
    Set_Rtc(ucRtc);
    

    while(1)
    {
        Key_Proc();
        Seg_Proc();
        LED_Proc(); 
    }
}


void tm1_isr() interrupt 3
{   
    if(++Key_Slow_Down==10)Key_Slow_Down=0;//¼õËÙ
    if(++Seg_Slow_Down==500)Seg_Slow_Down=0;    
    
    if(++ms_count==1000)//¼Ç¼ÔËÐÐʱ¼ä
    {
        s_count++;
        ms_count=0;
    }
    
    Seg_Disp(seg_buf,pos);//Ë¢ÐÂÏÔʾ
    if(++pos==8) pos=0;
    
    Led_Disp(ucLed);
}

先设置,再在while里放三个进程,中断里先延迟,再进行毫秒叠加秒,显示对应数组里的数和LED灯。


void Key_Proc(void)//¾ØÕó°´¼ü´¦Àí
{
    if(Key_Slow_Down)return;//¼õËÙ³ÌÐò
    Key_Slow_Down=1;
    
    Key_Value=Key_Read_BTN();        //¶ÁÈ¡°´¼ü°´ÏµıàºÅ
    Key_Down=Key_Value & (Key_Old^Key_Value);//£¡ 0000^0101=0101&0101=0101,Èç¹û°´¼ü·¢ÉúϽµÑصı仯£¬Êä³ö½á¹ûºÍ±¾´Î°´¼üÊýÖµÏàͬ(ʵ¼ÊÖÐÓÐϽµÑØÌø±ä¾ÍÊÇ°´ÏÂÁ˼üÅÌ)
                                                                                     //£¡ 0101^0101=0000&0101=0000,Èç¹ûÒ»Ö±±£³Ö²»±ä£¬Êä³ö½á¹ûΪ0
    Key_Old=Key_Value;//Key_OldΪÉÏÒ»¸ö״̬£¬Ñ­»·Ò»´Î°ÑÏÂÒ»¸ö״̬¸³Öµ¸øÉÏÒ»´Î£¬ÓÃÓÚÅжÏ
    
    if(Key_Down)//Èç¹û°´Ï¼üÅ̺󣬽«¼üÅ̶ÔÓ¦µÄÖµ¸³Öµ¸øÏÔʾ±ê־λ
    {
            if(++Running_State==2) Running_State=0;
    }
}    

void Seg_Proc(void)//ÏÔʾ´¦Àí
{
    if(Seg_Slow_Down)return;//¼õËÙ³ÌÐò
    Seg_Slow_Down=1;
    
    
    switch(Running_State)
        {
            case 0:
                            Read_Rtc(ucRtc);
                            sprintf(seg_string,"%02d_%02d_%02d",(unsigned int)ucRtc[0],(unsigned int)ucRtc[1],(unsigned int)ucRtc[2]);//½«ÒªÏÔʾµÄÊýÖµ´òÓ¡µ½×Ö·û´®ÖÐ
                            break;
            case 1:
                            sprintf(seg_string,"-----%03d",(unsigned int)s_count);
                            break;
        }    
    Seg_Tran(seg_string,seg_buf);
}

void Led_Proc(void)
{
        switch(Running_State)
        {
            case 0:
                    ucLed=0x0f;
                    break;
            case 1:
                    ucLed=0xf0;
                    break;
        }
        
}

led里是放入两种模式对应led的亮灭

key是放入 定义按键,设置两种状态0,1。

seg放入数码管显示根据两种状态分别显示两种状态1是设置好的时分秒,2是计数器。

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值