单片机学习小组
直播中

吴藩

10年用户 912经验值
擅长:可编程逻辑
私信 关注

求大佬分享基于DS3231时钟模块的stm32 Hal库程序分享

求大佬分享基于DS3231时钟模块的STM32 Hal库程序分享

回帖(1)

李玉鑫

2022-2-9 11:51:30
一、配置IO
/**
  /**
        ******************************************************************************
        * @file    bsp_i2c_ds3231.h  
        * @author  兲涳
        * @version V1.0
        * @date    2020-11-18
        * @brief   模拟i2c RTC(DS3231)应用函数bsp
        ******************************************************************************
        * @attention
        *
        ******************************************************************************
        */
          

  /******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
       
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_DS3231_H
#define        __I2C_DS3231_H

/* Includes ------------------------------------------------------------------*/


#ifdef _I2C_DS3231_PUBLIC_
#define PEXT
#else
#define PEXT extern
#endif


/* Exported types ------------------------------------------------------------*/
typedef struct
{
        u8  hour;
        u8  min;
        u8  sec;                       
        u32 year;
        u8  month;
        u8  day;
        u8  week;
        u16 temperature;
}_calendar_obj;       


/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/**************************I2C参数定义,I2C1或I2C2*****************************/




//#define        DS3231_I2C_GPIO_APBxClock_FUN   RCC_AHB1PeriphClockCmd
//#define   DS3231_I2C_GPIO_CLK             RCC_APB2Periph_GPIOC   
#define     DS3231_I2C_SCL_PORT             GPIOC  
#define     DS3231_I2C_SCL_PIN              GPIO_PIN_10
#define     DS3231_I2C_SDA_PORT             GPIOC
#define                DS3231_I2C_SDA_PIN                                GPIO_PIN_11


                                                                                         
#define         I2C_WR                0               
#define         I2C_RD                1


#define                I2C_SCL_1()                          HAL_GPIO_WritePin(DS3231_I2C_SCL_PORT, DS3231_I2C_SCL_PIN,GPIO_PIN_SET)               
#define         I2C_SCL_0()                          HAL_GPIO_WritePin(DS3231_I2C_SCL_PORT, DS3231_I2C_SCL_PIN,GPIO_PIN_RESET)               
#define         I2C_SDA_1()                   HAL_GPIO_WritePin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN,GPIO_PIN_SET)               
#define         I2C_SDA_0()                   HAL_GPIO_WritePin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN,GPIO_PIN_RESET)               
#define         I2C_SDA_READ()                HAL_GPIO_ReadPin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN)       


/* STM32 I2C 快速模式 */
#define             I2C_Speed                                                                                              400000  
/* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */
#define                                                 I2Cx_OWN_ADDRESS7                                                                                      0X0A   
/* DS3231 地址定义 */
#define                                                 DS3231_ADDRESS                                                                                                                  0xD0   

/* DS3231寄存器地址 */
                                                                                                                                                                       
#define                                                        DS3231_SECOND                                                                                                                         0x00    //秒
#define                                                 DS3231_MINUTE                                                                                                       0x01    //分
#define                                                 DS3231_HOUR                                                                                                         0x02    //时
#define                                                 DS3231_WEEK                                                                                                  0x03    //星期
#define                                                 DS3231_DAY                                                                                                   0x04    //日
#define                                                 DS3231_MONTH                                         0x05    //月
#define                                     DS3231_YEAR                                                           0x06    //年                                                                                          0x06    //年
/* 闹铃1 */                 
#define                                     DS3231_SALARM1ECOND                        0x07    //秒
#define                                                 DS3231_ALARM1MINUTE                        0x08    //分
#define                                     DS3231_ALARM1HOUR                          0x09    //时
#define                                                 DS3231_ALARM1WEEK                                                                                                   0x0A    //星期/日
/* 闹铃2 */
#define                                                 DS3231_ALARM2MINUTE                                                                                          0x0b    //分
#define                                                 DS3231_ALARM2HOUR                          0x0c    //时
#define                                                 DS3231_ALARM2WEEK                          0x0d    //星期/日

#define                                                 DS3231_CONTROL                             0x0e    //控制寄存器
#define                                                 DS3231_STATUS                              0x0f    //状态寄存器
#define                                                 BSY                                                                                                          2       //忙
#define                                                 OSF                                                                                                                 7       //振荡器停止标志
#define                                                 DS3231_XTAL                                                                                                  0x10    //晶体老化寄存器
#define                                                 DS3231_TEMPERATUREH                                                                                          0x11    //温度寄存器高字节(8位)
#define                                                 DS3231_TEMPERATUREL                                                                                          0x12    //温度寄存器低字节(高2位)                                                                                                                                                                



PEXT _calendar_obj calendar;        //日历结构体

/* Exported functions ------------------------------------------------------- */                                                                                                                                                               
PEXT void I2C_DS3231_Init(void);       
PEXT void i2c_Stop(void);
PEXT uint32_t I2C_DS3231_ByteWrite(u8 WriteAddr, u8 data);        
PEXT uint8_t I2C_DS3231_DataRead(u8 ReadAddr);                                                                                                                                                       
PEXT uint8_t BCD_DEC(u8 val);               
PEXT uint8_t DEC_BCD(u8 val);
PEXT void i2c_SendByte(uint8_t _ucByte);
PEXT void I2C_DS3231_SetTime(u8 yea,u8 mon,u8 da,u8 we,u8 hou,u8 min,u8 sec);
PEXT void Time_Regulate_Get(_calendar_obj *tm);

PEXT void I2C_DS3231_getTime(void);
PEXT void I2C_DS3231_getTemperature(void);

PEXT void GregorianDay(_calendar_obj * tm);

#undef PEXT
#endif

/*********************************************END OF FILE**********************/


二、初始化与函数
#define                _I2C_DS3231_PUBLIC_
#include        "common.h"


/**
  ******************************************************************************
  * @file    bsp_i2c_ds3231.c
  * @author  兲涳
  * @version V1.0
  * @date    2020-11-16
  * @brief   i2c RTC(DS3231)应用函数bsp
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */


/**
  * @brief  转换成BCD码
  * @param  None
  * @retval 返回BCD码
  */
u16 B_BCD(u8 val)
{
  u8 i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

/**
  * @brief  I2C I/O配置
  * @param  None
  * @retval None
  */
static void I2C_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_Initure;
       
        /* 使能与 I2C 有关的时钟 */
          __HAL_RCC_GPIOC_CLK_ENABLE();                   // 使能GPIOC端口时钟
       
        /* I2C_SCL、I2C_SDA*/
          GPIO_Initure.Mode=GPIO_MODE_OUTPUT_OD;          //开漏输出
        GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉
        GPIO_Initure.Speed=GPIO_SPEED_HIGH;                     //高速       
        GPIO_Initure.Pin=GPIO_PIN_10|GPIO_PIN_11;                                                 //PC3
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10|GPIO_PIN_11,GPIO_PIN_SET);        //初始化后置1
}

/**
  * @brief  I2C 外设(DS3231)初始化
  * @param  None
  * @retval None
  */
void I2C_DS3231_Init(void)
{
  I2C_GPIO_Config();
       
        /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
        i2c_Stop();
}

/**
  * @brief  I2C总线位延迟,最快400KHz
  * @param  None
  * @retval None
  */
static void i2c_Delay(void)
{
        uint8_t i;

        /* 
                 下面的时间是通过逻辑分析仪测试得到的。
    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
  
                循环次数为10时,SCL频率 = 205KHz
                循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us
                 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us
        */
        for (i = 0; i < 10; i++);
}

/**
  * @brief  I2C总线启动信号
  * @param  None
  * @retval None
  */
void i2c_Start(void)
{
        /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
        I2C_SDA_1();
        I2C_SCL_1();
        i2c_Delay();
        I2C_SDA_0();
        i2c_Delay();
        I2C_SCL_0();
        i2c_Delay();
}

/**
  * @brief  I2C总线停止信号
  * @param  None
  * @retval None
  */
void i2c_Stop(void)
{
        /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
        I2C_SDA_0();
        I2C_SCL_1();
        i2c_Delay();
        I2C_SDA_1();
}

/**
  * @brief  MCU向I2C总线设备发送8bit数据
  * @param   
  *                @arg         _ucByte:发送的字节
        * @retval None
  */
void i2c_SendByte(uint8_t _ucByte)
{
        uint8_t i;

        /* 先发送字节的高位bit7 */
        for (i = 0; i < 8; i++)
        {               
                if (_ucByte & 0x80)
                {
                        I2C_SDA_1();
                }
                else
                {
                        I2C_SDA_0();
                }
                i2c_Delay();
                I2C_SCL_1();
                i2c_Delay();       
                I2C_SCL_0();
                if (i == 7)
                {
                         I2C_SDA_1(); // 释放总线
                }
                _ucByte <<= 1;        /* 左移一个bit */
                i2c_Delay();
        }
}

/**
  * @brief  MCU从I2C总线设备读取8bit数据
  * @param  None
        * @retval 读到的数据
  */
uint8_t i2c_ReadByte(void)
{
        uint8_t i;
        uint8_t value;

        /* 读到第1个bit为数据的bit7 */
        value = 0;
        for (i = 0; i < 8; i++)
        {
                value <<= 1;
                I2C_SCL_1();
                i2c_Delay();
                if (I2C_SDA_READ())
                {
                        value++;
                }
                I2C_SCL_0();
                i2c_Delay();
        }
        return value;
}

/**
  * @brief  MCU产生一个时钟,并读取器件的ACK应答信号
  * @param  None
        * @retval 返回0表示正确应答,1表示无器件响应
  */
uint8_t i2c_WaitAck(void)
{
        uint8_t re;

        I2C_SDA_1();        /* CPU释放SDA总线 */
        i2c_Delay();
        I2C_SCL_1();        /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
        i2c_Delay();
        if (I2C_SDA_READ())        /* CPU读取SDA口线状态 */
        {
                re = 1;
        }
        else
        {
                re = 0;
        }
        I2C_SCL_0();
        i2c_Delay();
        return re;
}

/**
  * @brief  MCU产生一个ACK信号
  * @param  None
        * @retval None
  */
void i2c_Ack(void)
{
        I2C_SDA_0();        /* CPU驱动SDA = 0 */
        i2c_Delay();
        I2C_SCL_1();        /* CPU产生1个时钟 */
        i2c_Delay();
        I2C_SCL_0();
        i2c_Delay();
        I2C_SDA_1();        /* CPU释放SDA总线 */
}

/**
  * @brief  MCU产生1个NACK信号
  * @param  None
        * @retval None
  */
void i2c_NAck(void)
{
        I2C_SDA_1();        /* CPU驱动SDA = 1 */
        i2c_Delay();
        I2C_SCL_1();        /* CPU产生1个时钟 */
        i2c_Delay();
        I2C_SCL_0();
        i2c_Delay();       
}

/**
  * @brief  检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
  * @param   
  *                @arg  _Address:设备的I2C总线地址
        * @retval 返回值 0 表示正确, 返回1表示未探测到
  */
uint8_t i2c_CheckDevice(uint8_t _Address)
{
        uint8_t ucAck;

        I2C_DS3231_Init();                /* 配置GPIO */

       
        i2c_Start();                /* 发送启动信号 */

        /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
        i2c_SendByte(_Address | I2C_WR);
        ucAck = i2c_WaitAck();        /* 检测设备的ACK应答 */

        i2c_Stop();                        /* 发送停止信号 */

        return ucAck;
}

//
/**
  * @brief        写一个字节到I2C DS3231中
  * @param   
  *                @arg data:要写入的字节
  *                @arg WriteAddr:写地址
        * @retval 返回1,表示写入成功.
  */
uint32_t I2C_DS3231_ByteWrite(u8 WriteAddr, u8 data)
{
        /* 第1步:发起I2C总线启动信号 */
        i2c_Start();
       
        /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
        i2c_SendByte(DS3231_ADDRESS| I2C_WR);        /* 此处是写指令 */
       
        /* 第3步:等待ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
        /* 第4步:发送寄存器地址 */
        i2c_SendByte((uint8_t)WriteAddr);
       
  /* 第5步:等待ACK */
        if (i2c_WaitAck() != 0)
        {
          goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
        /* 第6步:开始写入数据 */
        i2c_SendByte(data);
       
        /* 第7步:等待ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
  /* 命令执行成功,发送I2C总线停止信号 */
        i2c_Stop();
        return 1;
cmd_fail: /* 命令执行失败后,发送停止信号 */
        /* 发送I2C总线停止信号 */
        i2c_Stop();
        return 0;
}

/**
  * @brief        从DS3231里面读取一个字节数据
  * @param   
  *                @arg data:存放从DS3231读取的数据
  *                @arg ReadAddr:读取数据的DS3231的地址
        * @retval data:返回数据.
  */
uint8_t I2C_DS3231_DataRead(u8 ReadAddr)
{
        uint8_t data;

        /* 第1步:发起I2C总线启动信号 */
        i2c_Start();

        /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
        i2c_SendByte(DS3231_ADDRESS|I2C_WR);        /* 此处是写指令 */
  
        /* 第3步:等待ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
        /* 第4步:发送DS3231寄存器地址 */
        i2c_SendByte((uint8_t)ReadAddr);
       
        /* 第5步:等待ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
        /* 第6步:产生第二次 I2C 起始信号 */  
          i2c_Start();
       
        /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
        //i2c_SendByte(DS3231_ADDRESS | I2C_RD);        /* 此处是读指令 */
        i2c_SendByte(DS3231_ADDRESS | I2C_RD);        /* 此处是读指令 */
       
        /* 第8步:发送ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }       
   
          /* 第9步:读取数据 */
        data = i2c_ReadByte();

          i2c_NAck();       
        i2c_Stop();
        return data;
       
          cmd_fail: /* 命令执行失败后,发送停止信号 */
        /* 发送I2C总线停止信号 */
        i2c_Stop();
        return 0;
}

/**
  * @brief        BCD(8421)转DEC.
  * @param  val:BCD码.
  * @retval i:DEC码.
  */
uint8_t BCD_DEC(u8 val)
{
        u8 i;
        i= val&0x0f;
        val >>= 4;
        val &= 0x0f;
        val *= 10;
        i += val;   
        return i;
}

/**
  * @brief        BCD(8421)转DEC.
  * @param  val:DEC码.
  * @retval k:BCD码.
  */
uint8_t DEC_BCD(u8 val)
{
  u8 i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

/**
  * @brief        时间设置
  * @param   
  *                @arg         分别输入 年 月 日 星期 时 分 秒
  * @retval 无
  */
void I2C_DS3231_SetTime(u8 yea,u8 mon,u8 da,u8 we,u8 hou,u8 min,u8 sec)
{
  u8 temp=0;
  yea-=2000;
  temp=DEC_BCD(yea);
  I2C_DS3231_ByteWrite(0x06,temp);
  temp=DEC_BCD(mon);
  I2C_DS3231_ByteWrite(0x05,temp);
   
  temp=DEC_BCD(da);
  I2C_DS3231_ByteWrite(0x04,temp);
  
//        temp=DEC_BCD(we);
//  I2C_DS3231_ByteWrite(0x03,temp);
       
  temp=DEC_BCD(hou);
  I2C_DS3231_ByteWrite(0x02,temp);
  
  temp=DEC_BCD(min);
  I2C_DS3231_ByteWrite(0x01,temp);
  
  temp=DEC_BCD(sec);
  I2C_DS3231_ByteWrite(0x00,temp);
}       

/**
  * @brief        获取时间
  * @param   
  *                @arg pBuffer:存放从DS3231读取的数据的缓冲区指针
  *                @arg ReadAddr:读取数据的DS3231的地址
  *   @arg NumByteToWrite:要从DS3231读取的字节数
  * @retval 返回1,表示读取成功.
  */
void I2C_DS3231_getTime(void)
{
        calendar.year=I2C_DS3231_DataRead(0x06);  
        calendar.year=BCD_DEC(calendar.year)+2000;

        calendar.month=I2C_DS3231_DataRead(0x05);
        calendar.month=BCD_DEC(calendar.month);

        calendar.day=I2C_DS3231_DataRead(0x04);  
        calendar.day=BCD_DEC(calendar.day);

        calendar.week=I2C_DS3231_DataRead(0x03);  
        calendar.week=BCD_DEC(calendar.week);

        calendar.hour=I2C_DS3231_DataRead(0x02);
        calendar.hour&=0x3f;                  
        calendar.hour=BCD_DEC(calendar.hour);

        calendar.min=I2C_DS3231_DataRead(0x01);
        calendar.min=BCD_DEC(calendar.min);


        calendar.sec=I2C_DS3231_DataRead(0x00);
        calendar.sec=BCD_DEC(calendar.sec);
}

/**
  * @brief 保存用户使用串口设置的时间
  * @param   
  *                @arg tm:用于设置RTC时间的结构体指针
  * @retval
  */
void Time_Regulate_Get(_calendar_obj *tm)
{
          uint32_t temp_num = 0;
                uint8_t day_max=0 ;

          printf("rn=========================设置时间==================");
               
          do
          {
                        printf("rn  请输入年份(Please Set Years),范围[2000~2255],输入字符后请加回车:");
                        scanf("%d",&temp_num);
                        if(temp_num <2000 || temp_num >2255)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                                          
                        }
                        else
                        {          
                                printf("nr  年份被设置为: %dnr", temp_num);
        temp_num-=2000;
                                DEC_BCD(temp_num);
                                tm->year = temp_num;
                                break;
                        }
          }while(1);


         do
          {
                        printf("rn  请输入月份(Please Set Months):范围[1~12],输入字符后请加回车:");
                        scanf("%d",&temp_num);
                        if(temp_num <1 || temp_num >12)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                                          
                        }
                        else
                        {          
                                printf("nr  月份被设置为: %dnr", temp_num);
        DEC_BCD(temp_num);
                                tm->month = temp_num;
                                break;
                        }
          }while(1);
               
                /*根据月份计算最大日期*/
                switch(tm->month)
                        {
                                case 1:
                                case 3:
                                case 5:
                                case 7:
                                case 8:
                                case 10:
                                case 12:                                       
                                                day_max = 31;
                                        break;
                               
                                case 4:
                                case 6:
                                case 9:
                                case 11:
                                                day_max = 30;
                                        break;
                               
                                case 2:                                       
                                     /*计算闰年*/
                                                if(((tm->year+2000)%4==0) &&
                                                         (((tm->year+2000)%100!=0) || ((tm->year+2000)%400==0)))
                                                                {
                                                                        day_max = 29;
                                                                } else
                                                                {
                                                                        day_max = 28;
                                                                }
                                        break;                       
                        }

                do
          {                               
                        printf("rn  请输入日期(Please Set Months),范围[1~%d],输入字符后请加回车:",day_max);
                        scanf("%d",&temp_num);
                       
                        if(temp_num <1 || temp_num >day_max)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                        }
                        else
                        {
                                printf("nr  日期被设置为: %dnr", temp_num);
        DEC_BCD(temp_num);
                                tm->day = temp_num;
                                break;
                        }
          }while(1);
               
                GregorianDay( tm );
               
                do
          {                               
                        printf("rn  请输入时钟(Please Set Hours),范围[0~23],输入字符后请加回车:");
                        scanf("%d",&temp_num);
                       
                        if( temp_num >23)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                        }
                        else
                        {
                                printf("nr  时钟被设置为: %dnr", temp_num);
        DEC_BCD(temp_num);
                                tm->hour = temp_num;
                                break;
                        }
          }while(1);

                do
          {                               
                        printf("rn  请输入分钟(Please Set Minutes),范围[0~59],输入字符后请加回车:");
                        scanf("%d",&temp_num);
                       
                        if( temp_num >59)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                        }
                        else
                        {
                                printf("nr  分钟被设置为: %dnr", temp_num);
        DEC_BCD(temp_num);
                                tm->min = temp_num;
                                break;
                        }
          }while(1);

                do
          {                               
                        printf("rn  请输入秒钟(Please Set Seconds),范围[0~59],输入字符后请加回车:");
                        scanf("%d",&temp_num);
                       
                        if( temp_num >59)
                        {
                                printf("rn 您输入的数字是:%d,不符合要求",temp_num);
                        }
                        else
                        {
                                printf("nr  秒钟被设置为: %dnr", temp_num);
        DEC_BCD(temp_num);
                                tm->sec = temp_num;
                                break;
                        }
          }while(1);
                __HAL_UART_ENABLE_IT(&UART1_Handler,UART_IT_RXNE);        //开启接收中断
}


/**
  * @brief        获取温度
  * @param  无
  * @retval 无
  */
void I2C_DS3231_getTemperature(void)
{
        I2C_DS3231_ByteWrite(DS3231_CONTROL, 0x20|0x05);
        calendar.temperature=I2C_DS3231_DataRead(DS3231_TEMPERATUREH);
}

/*计算公历天数得出星期*/
void GregorianDay(_calendar_obj * tm)
{
        int leapsToDate;
        int lastYear;
        int day;
        int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };

        lastYear=tm->year-1;

        /*计算从公元元年到计数的前一年之中一共经历了多少个闰年*/
        leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;      

     /*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/
        if((tm->year%4==0) &&
           ((tm->year%100!=0) || (tm->year%400==0)) &&
           (tm->month>2)) {
                /*
                 * We are past Feb. 29 in a leap year
                 */
                day=1;
        } else {
                day=0;
        }

        day += lastYear*365 + leapsToDate + MonthOffset[tm->month-1] + tm->day; /*计算从公元元年元旦到计数日期一共有多少天*/

        tm->week=day%7; //算出星期
}

/*********************************************END OF FILE**********************/


三、函数调用(我用标准库的代码,如果在hal库有问题自己改下。调用方式是一样的)


/**
  ******************************************************************************
  * @file    main.c
  * @author  兲涳
  * @version V1.0
  * @date    2020-11-16
  * @brief   
  ******************************************************************************
  * @attention
  * I2C_2 RTC(DS3231)测试,测试信息通过USART1打印在电脑调试助手上,通过串口设置时间
        * !!!串口输入  t  回车 ,进行设置时间。
  ******************************************************************************
  */  
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_i2c_ds3231.h"
#include
/* Private typedef -----------------------------------------------------------*/
uint8_t i=0;
extern _calendar_obj calendar;        //日历结构体
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define SOFT_DELAY                Delay(0x4FFFFF);
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Delay(__IO u32 nCount);
/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{
        /* 初始化USART 配置模式为 115200 8-N-1 */
  USART_Config();
  printf("nDS3231   RTC时钟n");
        /* I2C 外设初(DS3231)始化 */
        I2C_DS3231_Init();
//  I2C_DS3231_SetTime(20,8,24,1,13,43,20);
  while(1)
        {
                SOFT_DELAY;
                if(i==1)
                {
                        Time_Regulate_Get( &calendar );
                        I2C_DS3231_SetTime(calendar.year, calendar.month, calendar.date, calendar.week, calendar.hour, calendar.min, calendar.sec);
                        i=0;
                }
                I2C_DS3231_getTime();                //获取时间
                I2C_DS3231_getTemperature();                //获取温度
                printf("%d年%d月%d日%d时%d分%d秒 星期%d 温度%dn",calendar.year+2000,calendar.month,calendar.date,
                                                calendar.hour,calendar.min,calendar.sec,calendar.week,calendar.temperature);//打印到串口屏不能有printf("n");换行!!!       
        }
}       
/**
  * @brief  延时函数
  * @param  无  
  * @retval 无
  */
void Delay(__IO uint32_t nCount)         //简单的延时函数
{
        for(; nCount != 0; nCount--);
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分