laitimes

51 MCU Study Notes 12 SPI Interface 1302 clock is used

author:Programming circles

1. Introduction to DS1302

1. Features

The DS1302 is a real-time clock (RTC) chip manufactured by Maxim Integrated.

RTC chips are used in integrated circuits for time and date in computers and other electronic devices, and are commonly used in applications such as electronic clocks, timers, temperature loggers, etc.

Some of the features of the DS1302 are:

  1. Real-time clock function: provides time data such as year, month, day, hour, minute, and second.
  2. Serial interface: Communicates with the microcontroller via a serial interface such as SPI.
  3. Low-power design: It has the characteristics of low power consumption, and can run stably for a long time under the condition of battery power.
  4. Built-in crystal oscillator: An integrated crystal oscillator eliminates the need for an external crystal oscillator.
  5. Battery backup: Battery backup is supported to keep the clock running, and the time data can be kept even when the main power supply is off.
  6. Temperature compensation: With temperature compensation function, it can improve the accuracy of the clock.

Typically used with a microcontroller or microcontroller, the DS1302 communicates through a serial interface and reads and writes registers to configure and read time data.

DS1302 operates at 2.0~5.5V.

2. Trickle charging

Trickle charging is a low-power charging method that prevents the battery from overcharging and damage by limiting the amount of charging current.

The DS1302 incorporates a trickle-charge circuit that recharges the chip's internal backup battery at an appropriate rate by limiting the charging current while the mains is powering the mains supply. Once the battery is fully charged, the charging circuit automatically stops charging to prevent overcharging.

When the mains power goes down, the DS1302 automatically supplies power from a backup battery, keeping the clock and date functions up and running. The backup battery is typically a smaller lithium battery that provides enough power to maintain the basic functions of the DS1302 for several years.

3. API introduction

The DS1302 real-time clock chip has a serial interface and typically communicates using a 3- or 4-wire SPI (Serial Peripheral Interface). The following are the main interfaces of the DS1302:

Clock Data & Control Lines:

  • CE (Chip Enable): A chip-enabled line that enables communication on the DS1302.
  • IO (Data I/O): A data input/output line used to exchange data with a microcontroller.
  • SCLK (Serial Clock): A serial clock line used for synchronous data transmission.

Power Cord:

  • VCC: Chip-powered positive electrode.
  • GND: chip ground wire.

Battery backup connection:

  • VBAT: Battery backup positive, used to back up clock data.
  • GND (BAT): Spare battery ground wire.
51 MCU Study Notes 12 SPI Interface 1302 clock is used

2. Register introduction

1. Control Registers

51 MCU Study Notes 12 SPI Interface 1302 clock is used
  • BIT7 MSB,1时 ,0时 对DS1302 入
  • BIT6 0: Clock/Calendar, 1 RAM Data
  • BIT5~BIT1: Input and output registers
  • BIT0 LSB, write at 0 and read at 1.

2. Time registers

register D7 D6 D5 D4 D3 D2 D1 D0
1 RAM/CK A4 A3 A2 A1 A0 R/W
second 1 0/1
minute 1 1 0/1
hour 1 1 0/1
sun 1 1 1 0/1
moon 1 1 0/1
week 1 1 1 0/1
year 1 1 1 0/1

3. Calendar/Clock Registers

BCD code format.

Register name Value range D7 D6 D5 D4 D3 D2 D1 D0
seconds register 00-59 CH Ten digits of seconds Single digits of seconds
Sub-registers 00-59 Ten digits of points Fractional units
Hour register 01-12 or 00-23 12/24 a/p HR Units of hours
Day register 01-31 Ten of the day Day in the single digits
Monthly registers 01-12 1/0 The single digit of the month
Register of the week 01-07 Day of the week
Year register 01-99 Ten of the year Year in the single digits
Write protection registers WP=1 protection
Slow charging registers TCS TCS TCS TCS DS DS RS RS
Clock burst register

3. Introduction to BCD code

The BCD (Binary-Coded Decimal) code is a numerical encoding method used to represent the binary form of decimal numbers. In BCD encoding, each decimal number (0 to 9) is represented by a 4-digit binary number. This encoding makes it easier for computers to process decimal numbers.

The basic principle of BCD code is to represent each bit of a decimal number as a binary number, for example, the decimal number 45 is represented by BCD encoding:

  • The BCD code for number 4 is 0100
  • The BCD code for the number 5 is 0101

Therefore, the BCD code for the number 45 is 0100 0101.

There are several common ways to represent BCD codes:

  1. 8421 code: Each decimal number is represented by a 4-digit binary number ranging from 0000 to 1001. The name of this encoding comes from the weights on each bit, which are 8, 4, 2, and 1, respectively. For example, the BCD encoding of decimal number 7 is 0111.
  2. 2421 yards: Similar to 8421 yards, but in the first four numbers, 9 is represented as 1001 instead of 1000. The purpose of this encoding is to simplify the implementation of BCD addition.
  3. Excess-3 code: On the basis of 8421 codes, 3 is added to each number. For example, the 8421 code of the number 0 is 0000, and the addition of 3 becomes 0011.

The DS1302 real-time clock chip uses 8421 codes (also known as 8421BCD codes)

4. DS1302 timing

1. Read the timing

Single-byte read:

51 MCU Study Notes 12 SPI Interface 1302 clock is used
  • CE: High Level Enabled
  • SCLK: Clock
  • IO: Read data
  • I/O is set to input
  • Write on the rising edge of the clock, from low to high;
  • The first byte is the write instruction
  • I/O is set to output
  • The latter byte is a read operation
  • When the write is complete, it reads on the next clock falling edge;

2. Write timings

Single-byte write:

51 MCU Study Notes 12 SPI Interface 1302 clock is used

Fifth, realization

1. Hardware schematic

51 MCU Study Notes 12 SPI Interface 1302 clock is used

The following code shows the time in the digital tube.

2. DS1302.H

//
// 时钟芯片
//

#ifndef LESSON11_DS1302_H
#define LESSON11_DS1302_H
#include <reg52.h>
#include "types.h"

sbit DS1302_CE = P3^5;
// 时钟口
sbit DS1302_CLK = P3^6;
// IO 口
sbit DS1302_IO = P3^4;

/**
* 写入一个字节
*/
void ds1302_write_byte(u8 addr, u8 dat);
/**
* 读取一个字节
*/
u8 ds1302_read_byte(u8 addr);

//变量声明
extern u8 gDS1302_TIME[7];//存储时间

void ds1302_init(void);
void ds1302_read_time(void);
#endif //LESSON11_DS1302_H
           

3. ds1302.c

//
// 时钟芯片
//
#include "ds1302.h"
#include "intrins.h"

// DS1302写入和读取的地址命令
u8 gREAD_RTC_ADDR[7] = {
    0x81,   // 二进制  1000 0001 , 表示: 1000 0000 读取秒
    0x83,   // 1000 0011 读取分 
    0x85,   // 1000 0101 读取时
    0x87,   // 1000 0111 读取日
    0x89,   // 1000 1001 读取月
    0x8b,   // 1000 1011 读取星期
    0x8d    // 1000 1101 读取年
    };
u8 gWRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
// DS1302 初始化要写入的时间
u8 gDS1302_TIME[7] = {
    0x47,   // 秒
    0x56,   // 分
    0x15,   // 时
    0x20,   // 日
    0x03,   // 月
    0x05,   // 星期
    0x24    // 年
    };

/**
* 写入一个字节
*/
void ds1302_write_byte(u8 addr, u8 dat){
    u8 i;
    
    // 使能脚复位
    DS1302_CE = 0;
    _nop_();
    // 时钟脚复位
    DS1302_CLK = 0;
    _nop_();
    // 使能脚置高
    DS1302_CE = 1;
    _nop_();
    // 从低位开始写入
    for(i=0; i<8; i++){
        // 先发送地址
        DS1302_IO = addr & 0x01;
         // 右移一位
        addr >>= 1;

        // SLK 上升沿写入
        DS1302_CLK = 1;
        _nop_();
        DS1302_CLK = 0;
        _nop_();
    }
    // 写入数据
    for(i=0; i<8; i++){
        // 先发送数据
        DS1302_IO = dat & 0x01;
        // 右移一位
        dat >>= 1;
        // SLK 上升沿写入
        DS1302_CLK = 1;
        _nop_();
        DS1302_CLK = 0;
        _nop_();
    }
    // 复位
    DS1302_CE = 0;
    _nop_();
}
/**
* 读取一个字节
*/
u8 ds1302_read_byte(u8 addr){
    u8 i;
    u8 temp = 0;
    u8 value = 0;
    // 使能脚复位
    DS1302_CE = 0;
    _nop_();
    // 时钟脚复位
    DS1302_CLK = 0;
    _nop_();
    // 使能脚置高
    DS1302_CE = 1;
    _nop_();
    // 从低位开始写入
    for(i=0; i<8; i++){
        // 先发送地址
        DS1302_IO = addr & 0x01;
        // 右移一位
        addr >>= 1;
        // SLK 上升沿写入
        DS1302_CLK = 1;
        _nop_();
        DS1302_CLK = 0;
        _nop_();
    }
    // 读取数据
    for(i=0; i<8; i++){
        temp = DS1302_IO;
        value = (temp << 7) | (value >> 1);
        // SLK 下降沿读取
        DS1302_CLK = 1;
        _nop_();
        DS1302_CLK = 0;
        _nop_();
    }
    // 复位
    DS1302_CE = 0;
    _nop_();

    // 释放时钟
    DS1302_CLK = 1;

    _nop_();
    DS1302_IO = 0;
    _nop_();
    DS1302_IO = 1;
    _nop_();
    return value;
}
/**
* ds1302初始化
*/
void ds1302_init(void){
    u8 i = 0;
    // 写入禁止写保护
    ds1302_write_byte(0x8e, 0x00);
    // 写数据
    for(i=0; i<7; i++){
        ds1302_write_byte(gWRITE_RTC_ADDR[i], gDS1302_TIME[i]);
    }
    // 写入启用写保护
    ds1302_write_byte(0x8e, 0x80);
}
/**
* 写入时间
*/
void ds1302_read_time(void){
	u8 i=0;
	for(i=0;i<7;i++)
	{
		gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);	
	}	
}
           

4. bench.c

#include <reg52.h>
#include "led_utils.h"
#include "common_utils.h"
#include "timer_utils.h"
#include "uart_utils.h"
#include "key_utils.h"
#include "eeprom_utils.h"
#include "segment_display_utils.h"
#include "ds1302.h"


/**
* @brief 主函数
*/
main()
{
	u8 time_buf[8];
	// 关闭所有led
	led_all_off();
	uart_init(0xFA);
	ds1302_init(); 
	
	while(1)
	{
		ds1302_read_time();
		uart_send(u8_to_hex(gDS1302_TIME[2]));
		time_buf[0]=gDS1302_TIME[2]/16;
		time_buf[1]=gDS1302_TIME[2]&0x0f;
		time_buf[2]=0x10;
		time_buf[3]=gDS1302_TIME[1]/16;
		time_buf[4]=gDS1302_TIME[1]&0x0f;
		time_buf[5]=0x10;
		time_buf[6]=gDS1302_TIME[0]/16;
		time_buf[7]=gDS1302_TIME[0]&0x0f;

		segment_show_u8_array(time_buf);
	}
}
           

The code of this article is open source at

https://gitee.com/xundh/learn51

Read on