大实验2:用DS1302时钟芯片设计一个高精度时钟

发布时间 2023-07-26 20:19:07作者: zxkic

需求:

1.在LCD1602上面显示年,月,日,星期,时,分,秒,并且按秒更新动态显示

2.4个独立按键各有各的功能,按键1能够实现进入暂停;按键2实现数值增大;按键3实现数值减小;按键4设定为功能选择键

3.具有闹钟设定以及到时报警功能,报警响起时,按任何按键均可以取消报警

完成:

1.根据DS1302的特性,读取DS1302中保存的date信息。

2.按键1判定之后,LCD进入功能设置模式,按键4移动修改的位置,按键2实现增加,按键3实现减小。

3.闹钟功能需要不断减少DS1302中的数值。(暂时未实现)

 

 

DS1302芯片原理

DS1302内含有一个实时时钟/日历和31 字节静态RAM,通过简单的串行接口单片机进行通信。实时时钟/日历电路提供秒、分、时、日、日期、月、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。

通过三个管脚与单片机通信,SCLK,CE,I/O。

SCLK是时钟线

CE输入驱动高启动所有的数据传输。CE输入有两个功能。首先,CE打开控制逻辑,允许访问的移位寄存器的地址/命令序列。其次,CE提供了一个终止单字节或多字节数据传输方法。

I/O是数据线

 ps:SCLK为低电平时,CE才能置为高电平。

指令和地址字节:

第7位固定为1,如果是0则禁止对DS1302的写入,第6位为1则是读取或写入RAM区,为0则是读取或写入时钟,第1-5为是地址,第0位置1时对地址进行读取,第0位置0是对地址进行写入。

DS1302的时序逻辑

 

 

DS1302初始化需要将CE和SCLK都置0;

一旦进行工作,CE将保持高电平。

对地址的写入均采用上升沿,写字节和读字节的区别在于第二个数据,写字节是上升沿有效,读字节是下降沿有效。

同时,我们可以注意到,数据的传输是从低位到高位。

void DS1302_Init(){  //将DS1302_SCLK和DS1302_CE均置为0,实现初始化
    DS1302_SCLK = 0;
    DS1302_CE = 0;
}

void Write_byte(uchar address, byte){ //
    uchar i;
    address = address &0xfe;   //最后一位为0,表示写数据
    DS1302_CE = 1;  //开启片选
    for(i = 0;i<8;i++){
        DS1302_SCLK = 0;    
        DS1302_IO = address &(0x01<<i);
        DS1302_SCLK = 1;//上升沿写
    }
    for(i = 0;i<8;i++){
        DS1302_SCLK = 0;
        DS1302_IO = byte& (0x01<<i);
        DS1302_SCLK = 1;
    }
    DS1302_CE = 0; //释放
    
}

uchar Read_byte(uchar address){
    uchar i,dat;
    address = address |0x01;  //最后一位置为1,表示读数据
    for(i = 0;i<8;i++){
        DS1032_SCLK = 0;
        DS1302_IO = address &(0x01<<i);
        DS1302_SCLK = 1;//上升沿写
    }
    for(i = 0;i<8;i++){
        DS1032_SCLK = 0;
        DS1302_SCLK = 1;//上升沿写
        dat = DS1302_IO &(0x01<<i);
        
    }
    DS1302_CE = 0;
    return dat;
    
}

 

功能逻辑:

  1. 初始化:LCD1602,DS1302和定时器均需要初始化,在Init()函数中实现这三个功能的初始化
  2. 按下K1键时,需要暂停DS1302内部的计时,设定setflag为1,再按则设定setflag为0,根据setflag的值选择不同的操作:
    1.   setflag==0,则不干涉DS1302的计时,读取其内部时间
    2.   setflag==1,根据K2,K3,K4的按键值设定DS1302的时间,同时加上闪烁功能,最后写入到DS1302内部的时间数组中。
      1.   K4按下,将setplace自增,同时在对应的位置设定闪烁模式
      2.   K2按下,进行时间增加,同时约束时间范围
      3.        K3按下,时间减少,约束时间范围
      4.   完成时间设定之后,消除闪烁
      5.     DS1302写入时间数组DS1302_SetTime();
    3.   Show_Time()在LCD1602屏幕上,显示DS1302的时间