DS3231SN

news/2024/12/5 9:40:55/

Maxim Integrated新型实时时钟(RTC) DS3231,内部集成了TCXO、RTC和32.768kHz晶体,并采用低成本、标准型、16引脚SOIC封装DS3231是低成本、高精度I²C实时时钟(RTC),具有集成的温补晶振(TCXO)和晶体。该器件包含电池输入端,断开主电源时仍可保持精确的计时。集成晶振提高了器件的长期精确度,并减少了生产线的元件数量。DS3231提供商用级和工业级温度范围,采用16引脚300mil的SO封装。

RTC保存秒、分、时、星期、日期、月和年信息。少于31天的月份,将自动调整月末的日期,包括闰年的修正。时钟的工作格式可以是24小时或带/AM/PM指示的12小时格式。提供两个可设置的日历闹钟和一个可设置的方波输出。地址与数据通过I²C双向总线串行传输。

精密的、经过温度补偿的电压基准和比较器电路用来监视VCC状态,检测电源故障,提供复位输出,并在必要时自动切换到备份电源。另外,/RST监视引脚可以作为产生µP复位的手动输入。

关键特性

0°C至+40°C范围内精度为±2ppm
-40°C至+85°C范围内精度为±3.5ppm
为连续计时提供电池备份输入
工作温度范围
商用级:0°C至+70°C
工业级:-40°C至+85°C
低功耗
实时时钟产生秒、分、时、星期、日期、月和年计时,并提供有效期到2100年的闰年补偿
两个日历闹钟
可编程方波输出
高速(400kHz) I²C接口
工作在3.3V
数字温度传感器输出:精度为±3°C
老化修正寄存器
/RST输出/按钮复位去抖输入
做了块板子,用ds3231sn时钟芯片,板子其它部分都做好了,昨天网上找了一个stm32驱动ds3231的程序,我用的430单片机,按照程序修改了一下,却死活读取不到正确时间。貌似通讯不对,可是时序延时是完全按照网上的程序的。为什么会这样?附原理图。
补充:在仿真时,时间读取函数里面,仿真看到年月日时分秒都是0。/****************************************************/
把代码贴出来吧:

///
/*
DS3231.C文件
*/

#include"ds3231sn.h"
#define SETIIC_SCL P1OUT |= BIT7 
#define CLRIIC_SCL P1OUT &=~BIT7 

#define SETIIC_SDA P1OUT |= BIT6
#define CLRIIC_SDA P1OUT &=~BIT6

#define IIC_SDA (P1IN&BIT6)
_calendar_obj calendar;
#define DS3231_WriteAddress 0xD0   
#define DS3231_ReadAddress  0xD1
//-------------------------------------------------------------------
unsigned char BCD2HEX(unsigned char val)
{
    unsigned char i;
    i= val&0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;
    return i;
}

unsigned short B_BCD(unsigned char val)
{
  unsigned char i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
    P1DIR |= BIT7;P1DIR |= BIT6;
    SETIIC_SDA;//释放IIC总线的数据线。
    SETIIC_SCL;//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
     P1DIR |= BIT6;
     SETIIC_SDA;//拉高数据线
     delay_us(1);
     SETIIC_SCL;//拉高时钟线
     delay_us(5);
     CLRIIC_SDA;//在时钟线为高电平时,拉低数据线,产生起始信号。
     delay_us(5);
     CLRIIC_SCL;//拉低时钟线
     delay_us(2);
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线
    CLRIIC_SDA;//拉低数据线
    delay_us(4);
    SETIIC_SCL;//拉高时钟线。
    delay_us(5);
    SETIIC_SDA;//时钟时线为高电平时,拉高数据线,产生停止信号。
    delay_us(4);
}
//-------------------------------------------------------------------
unsigned char IIC_Tack(void)
{//接收应答信号函数
    unsigned char timnu=0;//定义一个位变量,来暂存应答状态。
    P1DIR &=~ BIT6;
    SETIIC_SDA;//释放数据总线,准备接收应答信号。
    delay_us(1);
    SETIIC_SCL;//拉高时钟线。
    delay_us(1);
    while(IIC_SDA==1)//读取应答信号的状态。
    {
      timnu++;
      if(timnu>250)
      {
        IIC_stop();
        return 1;//返回应答信号的状态,0表示应答,1表示非应答。
      }
    }
    CLRIIC_SCL;//拉低时钟线。
    return 0;//返回应答信号的状态,0表示应答,1表示非应答。
}
//产生ACK应答
void IIC_Ack(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        CLRIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}
//不产生ACK应答                    
void IIC_NAck(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        SETIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}                
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数
    unsigned char i;
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
    for(i=0;i<8;i++)
    {              
                if((Data&0x80)>>7)
                   SETIIC_SDA;
                else
                   CLRIIC_SDA;
                Data<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                SETIIC_SCL;//拉高时钟线。
                delay_us(2); 
                CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
                delay_us(2);
    }
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte(unsigned char ack)
{//从IIC总线读取一个字节的数据函数
    unsigned char i;
    unsigned char Data=0;       //定义一个缓冲寄存器。
    P1DIR &=~ BIT6;
    for(i=0;i<8;i++)//有8位数据
    {
        CLRIIC_SCL;//拉低时钟线,为读取下一位数据做准备。
        delay_us(2);
        SETIIC_SCL;//拉高时钟线,为读取下一位数据做准备。
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。

        if(IIC_SDA==1)//如果数据线为高平电平。
            Data++;delay_us(1);
    }
     if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    delay_us(5);
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答.
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Waddr)
{//从任意地址读取一个字节数据函数
    unsigned char Data;//定义一个缓冲寄存器。
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_ReadAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    Data=IIC_read_byte(1);//写入数据。
    IIC_stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}
void Read_RTC(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_month=IIC_single_byte_read(0x05);  
  calendar.w_date=IIC_single_byte_read(0x04); 
  calendar.hour=IIC_single_byte_read(0x02);  
  calendar.min=IIC_single_byte_read(0x01);
  calendar.sec=IIC_single_byte_read(0x00);  
}
void Set_RTC(unsigned char yea,unsigned char mon,unsigned char da,unsigned char hou,unsigned char min,unsigned char sec)
{
  unsigned char temp=0;

  temp=B_BCD(yea);
  IIC_single_byte_write(0x06,temp);

  temp=B_BCD(mon);
  IIC_single_byte_write(0x05,temp);

  temp=B_BCD(da);
  IIC_single_byte_write(0x04,temp);

  temp=B_BCD(hou);
  IIC_single_byte_write(0x02,temp);

  temp=B_BCD(min);
  IIC_single_byte_write(0x01,temp);

  temp=B_BCD(sec);
  IIC_single_byte_write(0x00,temp);
}
void get_show_time(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_year=BCD2HEX(calendar.w_year);


  calendar.w_month=IIC_single_byte_read(0x05); 
  calendar.w_month=BCD2HEX(calendar.w_month);


  calendar.w_date=IIC_single_byte_read(0x04);  
  calendar.w_date=BCD2HEX(calendar.w_date);


  calendar.hour=IIC_single_byte_read(0x02); 
  calendar.hour&=0x3f;                   
  calendar.hour=BCD2HEX(calendar.hour);


  calendar.min=IIC_single_byte_read(0x01);
  calendar.min=BCD2HEX(calendar.min);


  calendar.sec=IIC_single_byte_read(0x00);
  calendar.sec=BCD2HEX(calendar.sec);
}
void DS3231_Initial()
{
    IIC_Init();
    IIC_single_byte_write(0x0e,0);
    delay_ms(2);
    IIC_single_byte_write(0x0f,0);
    delay_ms(2);
}
 
————————————————
版权声明:本文为CSDN博主「m0_37895072」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37895072/article/details/102979136


http://www.ppmy.cn/news/338100.html

相关文章

PVE7.1虚拟机安装黑群晖教程

本教程基于Proxmox VE&#xff08;PVE&#xff09;7.1虚拟机环境下安装群晖&#xff0c;兼容这块简单说明:Intel酷睿四代以下或者志强处理器建议安装Ds3615-3617-3266等版本&#xff0c;四代以上可以安装918-920等版本&#xff0c;如果你啥都不知道&#xff0c;安装Ds3615就对了…

旧电脑安装黑群晖(5.1-5022)

家里旧电脑闲来没用&#xff0c;安装家庭NAS黑群晖 1.下载黑群晖安装工具包&#xff1a;https://pan.baidu.com/s/12CeLJmc5iC4XdRdzzqMGoQ 2.使用ChipEasy检查并记录U盘的VID PID对应文件目录为&#xff1a;\黑群晖\相关软件\1)ChipEasy芯片无忧_V1.6_Beta3\ChipEasy芯片无忧…

黑群晖6.x安装教程

黑群晖6.x安装教程 黑群晖6.x安装教程产品知识常用黑群晖型号DS3615xs、DS916、DS3617xs、DS918 4个的区别黑群没洗白、洗半白、洗全白的区别 安装教程&#xff08;主要&#xff09;群晖6.2.3安装教程前提工作1、U盘&#xff08;8g&#xff09;2、引导文件系统文件相关操作工具…

51单片机 (十四)DS1302

1.DS1302介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称为时钟芯…

虚拟机ESXi6.7安装黑群晖教程

目录 1.下载ESXi安装包并制作ESXi安装优盘 2.在ESXi中配置SATA控制器直通 3.下载黑群晖引导文件 4.修改引导文件 5转换引导文件 6.创建黑群晖虚拟机 7.安装黑群晖系统 8.小结 1-下载ESXi安装包并制作ESXi安装优盘 首先去[VMWARE](https://www.vmware.com/cn.html)官网下…

51单片机——DS1302时钟

目录 1.前言 1.1 实验现象 2. DS1302的介绍 2.1 DS1302的引脚定义以及应用电路 2.2 DS1302内部结构 2.21 DS1302内部特殊寄存器 2.22 时序 2.3 BCD码 3.源码 3.1 main.c 3.2 DS1302.c 3.3 DS1302.h 3.4 LCD1602.c 3.5 Delay.c 3.6 Delay.h 1.前言 之前我们已经…

51-DS1302实时时钟

一、 DS1302是一种实时时钟的芯片&#xff1b; 实际中&#xff1a;当我们需要一种芯片时&#xff0c;我们获取芯片以后&#xff0c;首先需要拿到芯片的设计手册&#xff0c;明确芯片的功能&#xff0c;进一步去使用芯片的功能&#xff1b; BCD码&#xff1a;用四位二进制数表…

实时时钟芯片DS1307的使用及驱动代码

DS1307实时时钟芯片的介绍及驱动代码 目录 一、DS1307是什么&#xff1f; 二、DS1307的功能 三、DS1307的寄存器 四、代码 1.读出数据 2.写入数据 3.时间初始化设置 4.获取当前时间 五、注意事项 总结 一、DS1307是什么&#xff1f; DS1307是一款基于IIC总线接口的实…