蓝桥杯单片机外设驱动-1


单片机外设驱动-DS1302

介绍:

什么是DS1302?


   DS1302是美国DALLAS公司推出的高性能、低功耗的实时时钟,附加31字节的静态RAM,采用SP三线接口与MCU进行同步通信,并可采用突发方式一次传送多个字节的时钟参数和RAM数据。时钟计数功能,可以对秒、分钟、小时、月、星期、年的计数,年计数可达到2100 年。
   简单来说,DS1302的使用方法和我们平时使用电子手表差不多,你可以设定时间,也可以读取时间,只不过这些工作是通过SPI接口有MCU去完成而已。
   在DS1302中有两块存储器:日历时钟寄存器和今天RAM存储器。前者用于记录实时时间,后者用于记录其他数据。对于基本计时应用,重点关注的是日历时钟寄存器。设定时间参数就是往这些寄存器写入内容,读取实时时间也是从这些寄存器读出数据。

芯片参数:

1.芯片功能

  • 实时时钟计算年、月、日、时、分、秒、星 期,直到 2100 年,并有闰年调节功能
  • 31 x 8 位 通用暂存 RAM
  • 串行输入输出,使管脚数最少
  • 2.0V 至 5.5V 宽电压范围操作
  • 在 2.0V 时工作电流小于 300nA
  • 读写时钟或 RAM 数据时有单字节或多字节(脉冲串模式)数据传送方式
  • 8 管脚 DIP 封装或可选的 8 管脚表面安装 SO 封装
  • 简单的 3 线接口
  • 与 TTL 兼容 (VCC = 5V)
  • 可选的工业温度范围:-40°C to +85°C

2.引脚说明

DS1302采用三线接口的双向数据通信接口。

RST:片引脚,低电平有效
SCLK:时钟芯片,为通信提供时钟源
I/O:为数据输入输出引脚,用于传输及接收数据
VCC1:连接到备用电源,VCC2:主电源失效时保持时间和日期数据


参考电路

1302

上图为CT107D平台的电路原理图

控制程序

1.日历时钟寄存器

DS1302有关日历和时钟的寄存器有12个,而我们用其中的7个就已经足够了。

日历时钟寄存器

什么是BCD码?

用十六进制来表示十进制。
例:十六进制数0x15的值为十进制的21,而BCD码表示的是整数15。
这在一会我们编程的时候需要用到。

2.接口时序的实现

DS1302的基本操作实际上非常简单,只有两个操作:设定时间参数读取实时时间

时序图

控制字都是从最低位开始输出的。在控制字输入后的下一个SCLK时钟信号的上升沿,数据被写入DS1302,数据的输入从最低位开始;在控制字指令输入后的下一个SCLK时钟信号的下降沿,数据从DS1302读出,数据的读出也是从最低位到最高位。


单字节写的时序:

单字节写

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参数配置

//读寄存器
unsigned char code READ_RTC_ADDR[7] =  {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
//写寄存器
unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

void DS1302_Config()
{
    unsigned char n;
    Write_Ds1302_Byte(0x8E,0x00);        //允许向内存写入数据
    for (n=0; n<7; n++)                  //写入时间参数
    {
        Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME[n]); 
    }
    Write_Ds1302_Byte(0x8E,0x80);        //禁止向内存写入数据
}

Write_Ds1302_Byte函数中的0x8E,0X00,0X80又是什么意思呢?
其实对照着寄存器写入格式就能够清晰的理解:

往0x8E(写寄存器)里面写入数据,而数据则为0X00,0X80
WP为0时,可对任何的时钟或RAM寄存器进行写操作。
WP为1时,禁止对任一寄存器进行写操作。

寄存器表

DS1302时间数据读取

void DS1302_ReadTime()
{
    unsigned char n;
    for (n=0; n<7; n++)                    //读时间参数
    {
        TIME[n] = Read_Ds1302_Byte(READ_RTC_ADDR[n]);
    }
}

DS1302时间显示到数码管

unsigned char TIME[7] = {0x30, 0x50, 0x23, 0x17, 0x02, 0x06, 0x18};

void display_time()
{
    DS1302_ReadTime();
    updateLed(0,TIME[2]/16);
    updateLed(1,TIME[2]%16);    
    updateLed(2,11);
    updateLed(3,TIME[1]/16);
    updateLed(4,TIME[1]%16);    
    updateLed(5,11);
    updateLed(6,TIME[0]/16);
    updateLed(7,TIME[0]%16);    
}

值得注意的是:这里显示到数码管是按照高四位低四位分别显示的,所以用/16取高四位,%16取低四位。
至于数码管驱动之后会写文章

实验效果

实验效果


文章作者: Rb菌
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rb菌 !
  目录