STC8H Development (Thirteen): I2C driving DS3231 high-precision real-time clock chip

Publisher:快乐飞翔Latest update time:2022-07-21 Source: csdnKeywords:DS3231 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Introduction to DS3231

DS3231 is a high-precision I2C real-time clock chip, and the I2C bus address is fixed to 0xD0


Built-in temperature compensated crystal oscillator (TCXO) to reduce crystal frequency drift caused by temperature changes, with an error of ±0.432s/Day in the range of [-40°C, 85°C].

Seconds, minutes, hours, weekday, date, month, year, leap year compensation, counting year interval is [1990, 2190]

Two programmable alarms that can repeat weekly or daily

Square wave output

Power supply 2.3V – 5.5V (typical: 3.3V)

Operating current 200 – 300 μA

Standby current 110 – 170 μA

Battery operating current 70 – 150 μA

Time hold battery current 0.84 – 3.5 μA


DS3231 pinout and typical circuit

32KHz - 32.768KHz output (50% duty cycle), open drain output, requires a pull-up resistor, can be left open if not used.

VCC

INT/SQW - Active low interrupt or square wave output (1Hz, 4kHz, 8kHz or 32kHz)

RST - Active low reset pin

GND

VBAT - Backup Power Supply

SDA - I2C Data

SCL - I2C Clock

ZS-042 Module

The most common DS3231 on Taobao is the ZS-042 module, which integrates a CR2032 battery holder and an AT24C32 8K-byte EEPROM storage, the latter of which can be accessed through the same I2C bus.


CR2032 Battery Holder

Provides backup power to the DS3231 when power is interrupted


Onboard AT24C32 EEPROM

The memory chip is AT24C32, with a capacity of 32K Bit = 4K Byte. The address can be modified by shorting A0/A1/A2. According to the data sheet of 24C32, these three bits correspond to the fifth to seventh bits of the 7-bit I2C address.


1 0 1 0 A2 A1 A0 R/W


A0 to A2 are pulled up by internal resistors. Open circuit is 1, short circuit is 0. Different combinations can generate 8 different addresses. The default address corresponding to full open circuit is 0xAE.


Using STC8H3K to drive DS3231

wiring

All three pairs of contacts of AT24C32 remain open


P32   -> SCL

P33   -> SDA

GND   -> GND

3.3V  -> VCC


Sample Code

Code download address


Gitee https://gitee.com/iosetting/fw-lib_-stc8/tree/master/demo/i2c/ds3231

GitHub https://github.com/IOsetting/FwLib_STC8/tree/master/demo/i2c/ds3231

The code will set the DS3231 time to 2022-07-10 14:21:10, and then display the time every second in hexadecimal format.


20-07-0A 0E:15:1E 00 00␍␊

20-07-0A 0E:15:1F 00 00␍␊

20-07-0A 0E:15:20 00 00␍␊

20-07-0A 0E:15:21 00 00␍␊

20-07-0A 0E:15:22 00 00␍␊


Initialize the I2C interface

Using P32 and P33


void I2C_Init(void)

{

    // Master mode

    I2C_SetWorkMode(I2C_WorkMode_Master);

    /**

     * I2C clock = FOSC / 2 / (__prescaler__ * 2 + 4)

    */

    I2C_SetClockPrescaler(0x1F);

    // Switch alternative port

    I2C_SetPort(I2C_AlterPort_P32_P33);

    // Start I2C

    I2C_SetEnabled(HAL_State_ON);

}


void GPIO_Init(void)

{

    // SDA

    GPIO_P3_SetMode(GPIO_Pin_3, GPIO_Mode_InOut_QBD);

    // SCL

    GPIO_P3_SetMode(GPIO_Pin_2, GPIO_Mode_Output_PP);

}


Basic I2C interface reading and writing methods

#define DS3231_I2C_ADDR                 0xD0


uint8_t DS3231_Write(uint8_t reg, uint8_t dat)

{

    return I2C_Write(DS3231_I2C_ADDR, reg, &dat, 1);

}


uint8_t DS3231_MultipleRead(uint8_t reg, uint8_t *buf, uint8_t len)

{

    return I2C_Read(DS3231_I2C_ADDR, reg, buf, len);

}


Conversion between BCD code and HEX

uint8_t DS3231_Hex2Bcd(uint8_t hex)

{

    return (hex % 10) + ((hex / 10) << 4);

}


uint8_t DS3231_Bcd2Hex(uint8_t bcd)

{

    return (bcd >> 4) * 10 + (bcd & 0x0F);

}


Reading time

Read the time and convert it to HEX, using a uint8_t array with the following structure:


/**

    uint8_t year;

    uint8_t month;

    uint8_t week;

    uint8_t date;

    uint8_t hour;

    uint8_t minute;

    uint8_t second;

    DS3231_HourFormat_t format;

    DS3231_AmPm_t am_pm;

 */


Reading the time from the DS3231


uint8_t DS3231_GetTime(uint8_t *t)

{

    uint8_t res;

    res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_SECOND, buff, 7);

    if (res != HAL_OK)

    {

        return res;

    }

    t[0] = DS3231_Bcd2Hex(buff[6]) + ((buff[5] >> 7) & 0x01) * 100; // year

    t[1] = DS3231_Bcd2Hex(buff[5] & 0x1F);                          // month

    t[2] = DS3231_Bcd2Hex(buff[3]); // week

    t[3] = DS3231_Bcd2Hex(buff[4]); // date

    t[7] = (buff[2] >> 6) & 0x01; // 12h/24h

    t[8] = (buff[2] >> 5) & 0x01; // am/pm

    if (t[7] == DS3231_FORMAT_12H)

    {

        t[4] = DS3231_Bcd2Hex(buff[2] & 0x1F); // hour

    }

    else

    {

        t[4] = DS3231_Bcd2Hex(buff[2] & 0x3F); // hour

    }

    t[5] = DS3231_Bcd2Hex(buff[1]); // minute

    t[6] = DS3231_Bcd2Hex(buff[0]); // second

    return HAL_OK;

}


Setting the time

First check the time values, then write them in by address


uint8_t DS3231_SetTime(uint8_t *t)

{

    uint8_t res, reg;


    // Time validation

    if (t[0] > 200) t[0] = 200; // year


    if (t[1] == 0) t[1] = 1; // month

    else if (t[1] > 12) t[1] = 12;


    if (t[2] == 0) t[2] = 1; // week

    else if (t[2] > 7) t[2] = 7;


    if (t[3] == 0) t[3] = 1; // date

    else if (t[3] > 31) t[3] = 31;


    if (t[7] == DS3231_FORMAT_12H)

    {

        if (t[4] > 12) t[4] = 12; // hour

    }

    else if (t[7] == DS3231_FORMAT_24H)

    {

        if (t[4] > 23) t[4] = 23; // hour

    }


    if (t[5] > 59) t[5] = 59; // minute

    if (t[6] > 59) t[6] = 59; // second


    res = DS3231_Write(DS3231_REG_SECOND, DS3231_Hex2Bcd(t[6]));

    if (res != HAL_OK) return res;


    res = DS3231_Write(DS3231_REG_MINUTE, DS3231_Hex2Bcd(t[5]));

    if (res != HAL_OK) return res;


    if (t[7] == DS3231_FORMAT_12H)

    {

        reg = (uint8_t)((1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));

    }

    else

    {

        reg = (0 << 6) | DS3231_Hex2Bcd(t[4]);

    }

    res = DS3231_Write(DS3231_REG_HOUR, reg);

    if (res != HAL_OK) return res;


    res = DS3231_Write(DS3231_REG_WEEK, DS3231_Hex2Bcd(t[2]));

    if (res != HAL_OK) return res;


    res = DS3231_Write(DS3231_REG_DATE, DS3231_Hex2Bcd(t[3]));

    if (res != HAL_OK) return res;


    if (t[0] >= 100)

    {

        res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]) | (1 << 7));

        if (res != HAL_OK) return res;

        return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0] - 100));

    }

    else

    {

        res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]));

        if (res != HAL_OK) return res;

        return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0]));

    }

}


Read and write AT24C32 in ZS-042 module

Refer to the previous article STC8H Development (XII): I2C drive AT24C08, AT24C32 series EEPROM storage


reference

Discussion of DS3231 module ZS-042, analyzing the battery charging problem and modification when powered by 5V https://forum.arduino.cc/t/zs-042-ds3231-rtc-module/268862/24

AT24C reading and writing https://www.likecs.com/show-204385163.html

Keywords:DS3231 Reference address:STC8H Development (Thirteen): I2C driving DS3231 high-precision real-time clock chip

Previous article:STC8H Development (XIV): I2C driver for RX8025T high-precision real-time clock chip
Next article:STC8H Development (XII): I2C drive AT24C08, AT24C32 series EEPROM storage

Recommended ReadingLatest update time:2024-11-23 06:47

DS3231 high precision clock module program
 I really wanted a clock module, but it was too troublesome to solder it myself, so I just bought it on TB to save time.   Module parameters:   1. Size: 38mm (length) * 22mm (width) * 14mm (height)   2.Weight: 8g   3. Working voltage: 3.3--5.5V   4. Clock chip: high-precision clock chip DS3231   5. Clock acc
[Microcontroller]
51 MCU I2C bus driver
The SI2I2C bus is a serial bus launched by PHLIPS. It is a high-performance serial bus with bus arbitration and high- and low-speed device synchronization functions required by multi-host systems. The I2C bus has only two bidirectional signal lines, one is the data line SDA, and the other is the clock line SCL. 1.I2
[Microcontroller]
51 MCU I2C bus driver
I2C (24C64) Driver
 /* ******************************************************************** ******************************************************************** */ //Summary: When SCL is high, the data on SDA is valid //Transmitted data SCL = 1; SDA = 1 or SDA = 0 requires stable data //Start signal SCL = 1; SDA = 1 --- 0 //Stop signal
[Microcontroller]
A brief discussion of I2C bus (IV) -- Example of IIC driver file for STM8
This example provides the IIC driver file source code of the STM8S103F core board. It has no problems after personal testing. The blogger uses it to drive AT24C256 and electronic compass MMC5883MA. The IIC communication rate is 100kHz, and the timing delay time can be adjusted. Paste the source code directly: IIC.
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号