硬汉嵌入式论坛

 找回密码
 立即注册
查看: 45|回复: 0
收起左侧

RX8025T定时重启偶发性失败

[复制链接]

40

主题

240

回帖

360

积分

高级会员

积分
360
发表于 昨天 16:16 | 显示全部楼层 |阅读模式
本帖最后由 LinY 于 2026-3-31 16:18 编辑

MCU: STM32L431RCT6
最早是直接用STOP模式进行低功耗的,发现还是会有几mA,因为有个只要有电就亮的电源灯,还要其他周边。
后面改成用RX8025T做时能供电,断电前写入闹钟配置,闹钟触发自动重启使能

测试环境测试一直没问题,现在在现场有个别设备就是不定期隔几天唤醒不了,盒子拿回来也测不出来。
业务上是每半小时重启一次。
闹钟每次设置的每天的下一次整30分钟,00:00,00:30,01:00...
现场设备确实休眠了的,也没有重启,重启我这边能有请求的。
就是休眠之后换不行了
想问问各位大佬可能原因?

[C] 纯文本查看 复制代码
#ifndef __RX8025T_H
#define __RX8025T_H

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"
#include <stdbool.h>
#include <stdlib.h>

/* RX8025T I2C地址配置 - 使用0x64 */
#define RX8025T_I2C_ADDR     0x64
#define RX8025T_I2C_ADDR_HAL RX8025T_I2C_ADDR // 使用0x64

/* 寄存器地址定义 */
#define RX8025T_REG_SEC            0x00
#define RX8025T_REG_MIN            0x01
#define RX8025T_REG_HOUR           0x02
#define RX8025T_REG_WEEK           0x03
#define RX8025T_REG_DAY            0x04
#define RX8025T_REG_MONTH          0x05
#define RX8025T_REG_YEAR           0x06
#define RX8025T_REG_RAM            0x07
#define RX8025T_REG_MIN_ALARM      0x08
#define RX8025T_REG_HOUR_ALARM     0x09
#define RX8025T_REG_WEEK_DAY_ALARM 0x0A
#define RX8025T_REG_TIM_CNT0       0x0B
#define RX8025T_REG_TIM_CNT1       0x0C
#define RX8025T_REG_EXTEN          0x0D
#define RX8025T_REG_FLAG           0x0E
#define RX8025T_REG_CONTROL        0x0F

/* 扩展寄存器(0x0D)位定义 */
#define RX8025T_EXTEN_TEST  (1 << 7) // 测试位(不要使用)
#define RX8025T_EXTEN_WADA  (1 << 6) // 0:周报警模式, 1:日报警模式
#define RX8025T_EXTEN_USEL  (1 << 5) // 0:每秒更新, 1:每分钟更新
#define RX8025T_EXTEN_TE    (1 << 4) // 定时器使能
#define RX8025T_EXTEN_FSEL1 (1 << 3) // FOUT频率选择
#define RX8025T_EXTEN_FSEL0 (1 << 2)
#define RX8025T_EXTEN_TSEL1 (1 << 1) // 定时器时钟源选择
#define RX8025T_EXTEN_TSEL0 (1 << 0)

/* 标志寄存器(0x0E)位定义 */
#define RX8025T_FLAG_UF   (1 << 5) // 更新时间中断标志
#define RX8025T_FLAG_TF   (1 << 4) // 定时器中断标志
#define RX8025T_FLAG_AF   (1 << 3) // 报警中断标志
#define RX8025T_FLAG_VLF  (1 << 1) // 电压低标志
#define RX8025T_FLAG_VDET (1 << 0) // 电压检测标志

/* 控制寄存器(0x0F)位定义 */
#define RX8025T_CONTR_CSEL1 (1 << 7) // 温度补偿间隔设置
#define RX8025T_CONTR_CSEL0 (1 << 6) // 00:0.5s, 01:1.0s, 10:2.0s(default), 11:4.0s
#define RX8025T_CONTR_UIE   (1 << 5) // 更新时间中断使能
#define RX8025T_CONTR_TIE   (1 << 4) // 定时器中断使能
#define RX8025T_CONTR_AIE   (1 << 3) // 报警中断使能
#define RX8025T_CONTR_RESET (1 << 0) // 复位位(不要使用)

/* 报警使能标志 */
#define RX8025T_ALARM_AE_FLAG 0x80

/* 定时器时钟源选择 */
typedef enum
{
  RX8025T_TIMER_SRC_4096HZ = 0x00, // 00: 4096Hz
  RX8025T_TIMER_SRC_64HZ = 0x01,   // 01: 64Hz
  RX8025T_TIMER_SRC_1HZ = 0x02,    // 10: 1Hz (每秒)
  RX8025T_TIMER_SRC_1_60HZ = 0x03  // 11: 1/60Hz (每分钟)
} RX8025T_TimerSource;

/* FOUT频率选择 */
typedef enum
{
  RX8025T_FOUT_DISABLE = 0x00, // 禁用输出
  RX8025T_FOUT_32768HZ = 0x01, // 32768Hz
  RX8025T_FOUT_1024HZ = 0x02,  // 1024Hz
  RX8025T_FOUT_1HZ = 0x03      // 1Hz
} RX8025T_FOUT_Freq;

/* 温度补偿间隔 */
typedef enum
{
  RX8025T_TCS_0_5S = 0x00, // 0.5秒
  RX8025T_TCS_1_0S = 0x40, // 1.0秒
  RX8025T_TCS_2_0S = 0x80, // 2.0秒(默认)
  RX8025T_TCS_4_0S = 0xC0  // 4.0秒
} RX8025T_TempCompInterval;

/* 星期枚举 */
typedef enum
{
  RX8025T_SUNDAY = 0,
  RX8025T_MONDAY,
  RX8025T_TUESDAY,
  RX8025T_WEDNESDAY,
  RX8025T_THURSDAY,
  RX8025T_FRIDAY,
  RX8025T_SATURDAY
} RX8025T_DayOfWeek;

/* 时间结构体 */
typedef struct
{
  uint8_t year;        // 年份 (00-99)
  uint8_t month;       // 月份 (1-12)
  uint8_t date;        // 日期 (1-31)
  uint8_t day_of_week; // 星期 (0-6, 0=周日)
  uint8_t hour;        // 小时 (0-23)
  uint8_t minute;      // 分钟 (0-59)
  uint8_t second;      // 秒 (0-59)
} RX8025T_TimeTypeDef;

/* 报警模式 */
typedef enum
{
  RX8025T_ALARM_DISABLE = 0,  // 报警禁用
  RX8025T_ALARM_DAY_MODE = 1, // 日模式
  RX8025T_ALARM_WEEK_MODE = 2 // 周模式
} RX8025T_AlarmMode;

/* 报警设置结构体 */
typedef struct
{
  RX8025T_AlarmMode mode; // 报警模式
  union
  {
    uint8_t day;       // 日模式: 日期(1-31), 0x80:每天
    uint8_t week;      // 周模式: 位掩码(bit0-6:周日-周六)
  } alarm_day_or_week; // 日期或星期
  uint8_t hour;        // 小时(0-23), 0x80:每小时
  uint8_t minute;      // 分钟(0-59), 0x80:每分钟(整点)
} RX8025T_AlarmTypeDef;

/* 电池状态结构体 */
typedef struct
{
  bool voltage_low;      // 电压低标志
  bool voltage_detected; // 电压检测标志
} RX8025T_BatteryStatus;

/* 错误代码 */
typedef enum
{
  RX8025T_OK = 0,
  RX8025T_ERROR = 1,
  RX8025T_ERROR_I2C = 2,
  RX8025T_ERROR_TIMEOUT = 3,
  RX8025T_ERROR_INVALID = 4,
  RX8025T_ERROR_VOLTAGE = 5
} RX8025T_StatusTypeDef;

/* 初始化与基础操作 */
RX8025T_StatusTypeDef RX8025T_Init(I2C_HandleTypeDef* hi2c);
RX8025T_StatusTypeDef RX8025T_DeInit(void);
bool RX8025T_IsReady(void);
RX8025T_StatusTypeDef RX8025T_Reset(void);

/* 时间操作 */
RX8025T_StatusTypeDef RX8025T_GetTime(RX8025T_TimeTypeDef* time);
RX8025T_StatusTypeDef RX8025T_SetTime(RX8025T_TimeTypeDef* time);
bool RX8025T_ValidateTime(RX8025T_TimeTypeDef* time);
RX8025T_StatusTypeDef RX8025T_WaitUpdate(uint32_t timeout_ms);

/* 中断配置 */
RX8025T_StatusTypeDef RX8025T_EnableUpdateInterrupt(bool enable, bool per_second);
RX8025T_StatusTypeDef RX8025T_EnableTimerInterrupt(bool enable, RX8025T_TimerSource source, uint16_t count);
RX8025T_StatusTypeDef RX8025T_EnableAlarmInterrupt(bool enable, RX8025T_AlarmTypeDef* alarm);

/* 中断标志处理 */
RX8025T_StatusTypeDef RX8025T_GetInterruptFlags(uint8_t* flags);
RX8025T_StatusTypeDef RX8025T_ClearAllInterruptFlags(void);
RX8025T_StatusTypeDef RX8025T_ClearUpdateFlag(void);
RX8025T_StatusTypeDef RX8025T_ClearTimerFlag(void);
RX8025T_StatusTypeDef RX8025T_ClearAlarmFlag(void);

/* 其他功能 */
RX8025T_StatusTypeDef RX8025T_SetFOUT(RX8025T_FOUT_Freq freq);
RX8025T_StatusTypeDef RX8025T_GetBatteryStatus(RX8025T_BatteryStatus* status);
RX8025T_StatusTypeDef RX8025T_SetTempCompInterval(RX8025T_TempCompInterval interval);
RX8025T_StatusTypeDef RX8025T_SetRAM(uint8_t data);
RX8025T_StatusTypeDef RX8025T_GetRAM(uint8_t* data);
RX8025T_StatusTypeDef RX8025T_WriteRegister(uint8_t reg, uint8_t data);
RX8025T_StatusTypeDef RX8025T_ReadRegister(uint8_t reg, uint8_t* data);

/* 工具函数 */
uint8_t RX8025T_DecToBcd(uint8_t dec);
uint8_t RX8025T_BcdToDec(uint8_t bcd);
const char* RX8025T_GetDayOfWeekString(uint8_t day_of_week);
bool RX8025T_IsLeapYear(uint16_t year);
uint8_t RX8025T_GetDaysInMonth(uint8_t month, uint16_t year);

#ifdef __cplusplus
}
#endif

#endif /* __RX8025T_H */



[C] 纯文本查看 复制代码
#include "rx8025t.h"

#include <stdio.h>
#include <string.h>

#define RX8025T_I2C_TIMEOUT    500
#define RX8025T_UPDATE_TIMEOUT 1000

/* 全局句柄 */
static I2C_HandleTypeDef* rx8025t_hi2c = NULL;

/* 静态函数声明 */
static uint8_t DayOfWeekToRegister(uint8_t day_of_week);
static uint8_t RegisterToDayOfWeek(uint8_t reg_value);
static RX8025T_StatusTypeDef RX8025T_I2C_Check(void);
static RX8025T_StatusTypeDef RX8025T_ReadBytes(uint8_t reg, uint8_t* data, uint16_t len);
static RX8025T_StatusTypeDef RX8025T_WriteBytes(uint8_t reg, uint8_t* data, uint16_t len);
static bool IsTimeValid(RX8025T_TimeTypeDef* time);

/* 初始化函数 - 修正版 */
RX8025T_StatusTypeDef RX8025T_Init(I2C_HandleTypeDef* hi2c)
{
  uint8_t flag_reg = 0;
  uint8_t control_reg = 0;

  if (hi2c == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  rx8025t_hi2c = hi2c;

  printf("[RX8025T] Initializing with I2C address: 0x%02X\n", RX8025T_I2C_ADDR_HAL);

  /* 检查I2C通信 - 使用简单的寄存器读取 */
  if (RX8025T_ReadRegister(0x00, &flag_reg) != RX8025T_OK)
  {
    printf("[RX8025T] Error: I2C communication failed\n");
    rx8025t_hi2c = NULL;
    return RX8025T_ERROR_I2C;
  }

  printf("[RX8025T] I2C communication OK, SEC register: 0x%02X\n", flag_reg);

  /* 读取标志寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  printf("[RX8025T] Flag register: 0x%02X\n", flag_reg);

  /* 检查电压低标志 */
  if (flag_reg & RX8025T_FLAG_VLF)
  {
    printf("[RX8025T] Warning: Voltage low, reinitializing RTC\n");

    /* 电压低,需要重新初始化 */
    RX8025T_TimeTypeDef default_time = {
      .year = 26,                      /* 2026年 */
      .month = 1,                      /* 1月 */
      .date = 1,                       /* 1日 */
      .day_of_week = RX8025T_THURSDAY, /* 2026-1-1是星期四 */
      .hour = 0,                       /* 0时 */
      .minute = 0,                     /* 0分 */
      .second = 0                      /* 0秒 */
    };

    if (RX8025T_SetTime(&default_time) != RX8025T_OK)
    {
      return RX8025T_ERROR;
    }

    printf("[RX8025T] RTC initialized with default time\n");
  }

  /* 清除所有中断标志 */
  if (RX8025T_ClearAllInterruptFlags() != RX8025T_OK)
  {
    return RX8025T_ERROR;
  }

  /* 设置控制寄存器默认值 */
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR;
  }

  /* 设置温度补偿间隔为2.0秒,禁用所有中断 */
  control_reg &= 0x3F;             /* 清空高2位 */
  control_reg |= RX8025T_TCS_2_0S; /* 01000000b */
  control_reg &= ~(RX8025T_CONTR_UIE | RX8025T_CONTR_TIE | RX8025T_CONTR_AIE);

  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR;
  }

  /* 设置扩展寄存器默认值 */
  if (RX8025T_WriteRegister(RX8025T_REG_EXTEN, 0x00) != RX8025T_OK)
  {
    return RX8025T_ERROR;
  }

  printf("[RX8025T] Initialization completed successfully\n");

  return RX8025T_OK;
}

/* 反初始化 */
RX8025T_StatusTypeDef RX8025T_DeInit(void)
{
  if (rx8025t_hi2c == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  /* 禁用所有中断 */
  uint8_t control_reg = 0;
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control_reg) == RX8025T_OK)
  {
    control_reg &= ~(RX8025T_CONTR_UIE | RX8025T_CONTR_TIE | RX8025T_CONTR_AIE);
    RX8025T_WriteRegister(RX8025T_REG_CONTROL, control_reg);
  }

  rx8025t_hi2c = NULL;
  return RX8025T_OK;
}

/* 检查设备是否就绪 */
bool RX8025T_IsReady(void)
{
  if (rx8025t_hi2c == NULL || rx8025t_hi2c->State != HAL_I2C_STATE_READY)
  {
    return false;
  }

  /* 尝试读取设备ID或固定寄存器 */
  uint8_t test_byte = 0;
  if (RX8025T_ReadRegister(RX8025T_REG_SEC, &test_byte) != RX8025T_OK)
  {
    return false;
  }

  return true;
}

/* 软复位 */
RX8025T_StatusTypeDef RX8025T_Reset(void)
{
  uint8_t control_reg = 0;

  /* 读取控制寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 设置复位位 */
  control_reg |= RX8025T_CONTR_RESET;

  /* 写入复位命令 */
  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 等待复位完成 */
  HAL_Delay(10);

  /* 清除复位位 */
  control_reg &= ~RX8025T_CONTR_RESET;

  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  HAL_Delay(10);

  return RX8025T_OK;
}

/* 获取当前时间 */
RX8025T_StatusTypeDef RX8025T_GetTime(RX8025T_TimeTypeDef* time)
{
  uint8_t buffer[7] = {0};

  if (time == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 读取时间寄存器 */
  if (RX8025T_ReadBytes(RX8025T_REG_SEC, buffer, sizeof(buffer)) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 解析时间数据 */
  time->second = RX8025T_BcdToDec(buffer[0] & 0x7F);
  time->minute = RX8025T_BcdToDec(buffer[1] & 0x7F);
  time->hour = RX8025T_BcdToDec(buffer[2] & 0x3F);
  time->day_of_week = RegisterToDayOfWeek(buffer[3] & 0x07);
  time->date = RX8025T_BcdToDec(buffer[4] & 0x3F);
  time->month = RX8025T_BcdToDec(buffer[5] & 0x1F);
  time->year = RX8025T_BcdToDec(buffer[6]);

  return RX8025T_OK;
}

/* 设置时间 */
RX8025T_StatusTypeDef RX8025T_SetTime(RX8025T_TimeTypeDef* time)
{
  uint8_t buffer[7];

  if (time == NULL || !IsTimeValid(time))
  {
    return RX8025T_ERROR;
  }

  /* 准备BCD时间数据 */
  buffer[0] = ((time->second / 10) << 4) | (time->second % 10);
  buffer[1] = ((time->minute / 10) << 4) | (time->minute % 10);
  buffer[2] = ((time->hour / 10) << 4) | (time->hour % 10);
  buffer[3] = 1 << time->day_of_week; /* 星期位映射 */
  buffer[4] = ((time->date / 10) << 4) | (time->date % 10);
  buffer[5] = ((time->month / 10) << 4) | (time->month % 10);
  buffer[6] = ((time->year / 10) << 4) | (time->year % 10);

  /* 清除STOP位(确保时钟运行) */
  buffer[0] &= 0x7F;

  /* 写入时间 */
  return RX8025T_WriteBytes(RX8025T_REG_SEC, buffer, 7);
}

/* 验证时间有效性 */
bool RX8025T_ValidateTime(RX8025T_TimeTypeDef* time)
{
  if (time == NULL)
  {
    return false;
  }

  /* 检查秒 */
  if (time->second > 59)
  {
    return false;
  }

  /* 检查分 */
  if (time->minute > 59)
  {
    return false;
  }

  /* 检查时 */
  if (time->hour > 23)
  {
    return false;
  }

  /* 检查星期 */
  if (time->day_of_week > 6)
  {
    return false;
  }

  /* 检查日期 */
  if (time->date < 1 || time->date > 31)
  {
    return false;
  }

  /* 检查月份 */
  if (time->month < 1 || time->month > 12)
  {
    return false;
  }

  /* 检查年份 */
  if (time->year > 99)
  {
    return false;
  }

  /* 检查特定月份的天数 */
  uint8_t max_days = RX8025T_GetDaysInMonth(time->month, 2000 + time->year);
  if (time->date > max_days)
  {
    return false;
  }

  return true;
}

/* 等待更新完成 */
RX8025T_StatusTypeDef RX8025T_WaitUpdate(uint32_t timeout_ms)
{
  uint32_t tickstart = HAL_GetTick();
  uint8_t flag_reg = 0;

  do
  {
    if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
    {
      return RX8025T_ERROR_I2C;
    }

    if ((flag_reg & RX8025T_FLAG_UF) == 0)
    {
      return RX8025T_OK;
    }

    if (timeout_ms > 0 && (HAL_GetTick() - tickstart) > timeout_ms)
    {
      return RX8025T_ERROR_TIMEOUT;
    }

    HAL_Delay(1);
  }
  while (1);
}

/* 使能更新时间中断 */
RX8025T_StatusTypeDef RX8025T_EnableUpdateInterrupt(bool enable, bool per_second)
{
  uint8_t extreg = 0;
  uint8_t control = 0;

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 配置扩展寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_EXTEN, &extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (per_second)
  {
    extreg &= ~RX8025T_EXTEN_USEL; /* 秒更新 */
  }
  else
  {
    extreg |= RX8025T_EXTEN_USEL; /* 分更新 */
  }

  if (RX8025T_WriteRegister(RX8025T_REG_EXTEN, extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 配置控制寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (enable)
  {
    control |= RX8025T_CONTR_UIE;
  }
  else
  {
    control &= ~RX8025T_CONTR_UIE;
  }

  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 清除更新标志 */
  if (enable)
  {
    RX8025T_ClearUpdateFlag();
  }

  return RX8025T_OK;
}

/* 使能定时器中断 */
RX8025T_StatusTypeDef RX8025T_EnableTimerInterrupt(bool enable, RX8025T_TimerSource source, uint16_t count)
{
  uint8_t extreg = 0;
  uint8_t control = 0;

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 设置计数值 */
  if (enable && count > 0)
  {
    if (RX8025T_WriteRegister(RX8025T_REG_TIM_CNT0, (uint8_t)(count & 0xFF)) != RX8025T_OK)
    {
      return RX8025T_ERROR_I2C;
    }

    if (RX8025T_WriteRegister(RX8025T_REG_TIM_CNT1, (uint8_t)((count >> 8) & 0x0F)) != RX8025T_OK)
    {
      return RX8025T_ERROR_I2C;
    }
  }

  /* 配置扩展寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_EXTEN, &extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  extreg &= ~(RX8025T_EXTEN_TSEL0 | RX8025T_EXTEN_TSEL1);
  extreg |= (source & 0x03);

  if (enable)
  {
    extreg |= RX8025T_EXTEN_TE;
  }
  else
  {
    extreg &= ~RX8025T_EXTEN_TE;
  }

  if (RX8025T_WriteRegister(RX8025T_REG_EXTEN, extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 配置控制寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control) != RX8025T_OK)
  {
    return RX8025T_ERROR;
  }

  if (enable)
  {
    control |= RX8025T_CONTR_TIE;
  }
  else
  {
    control &= ~RX8025T_CONTR_TIE;
  }

  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 清除定时器标志 */
  if (enable)
  {
    RX8025T_ClearTimerFlag();
  }

  return RX8025T_OK;
}

/* 使能报警中断 */
RX8025T_StatusTypeDef RX8025T_EnableAlarmInterrupt(bool enable, RX8025T_AlarmTypeDef* alarm)
{
  uint8_t extreg = 0;
  uint8_t control = 0;

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (enable && alarm == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  /* 设置报警时间 */
  if (enable)
  {
    /* 设置星期/日寄存器 */
    if (alarm->mode == RX8025T_ALARM_DAY_MODE)
    { /* 日模式 */
      if (alarm->alarm_day_or_week.day & RX8025T_ALARM_AE_FLAG)
      {
        /* 每天 */
        if (RX8025T_WriteRegister(RX8025T_REG_WEEK_DAY_ALARM, RX8025T_ALARM_AE_FLAG) != RX8025T_OK)
        {
          return RX8025T_ERROR_I2C;
        }
      }
      else if (alarm->alarm_day_or_week.day > 0 && alarm->alarm_day_or_week.day <= 31)
      {
        /* 特定日期 */
        if (RX8025T_WriteRegister(RX8025T_REG_WEEK_DAY_ALARM, RX8025T_DecToBcd(alarm->alarm_day_or_week.day)) != RX8025T_OK)
        {
          return RX8025T_ERROR_I2C;
        }
      }
      else
      {
        return RX8025T_ERROR_INVALID;
      }
    }
    else if (alarm->mode == RX8025T_ALARM_WEEK_MODE)
    { /* 周模式 */
      if (alarm->alarm_day_or_week.week > 0 && alarm->alarm_day_or_week.week <= 0x7F)
      {
        if (RX8025T_WriteRegister(RX8025T_REG_WEEK_DAY_ALARM, alarm->alarm_day_or_week.week) != RX8025T_OK)
        {
          return RX8025T_ERROR_I2C;
        }
      }
      else
      {
        return RX8025T_ERROR_INVALID;
      }
    }
    else
    {
      return RX8025T_ERROR_INVALID;
    }

    /* 设置小时寄存器 */
    if (alarm->hour & RX8025T_ALARM_AE_FLAG)
    {
      /* 每小时 */
      if (RX8025T_WriteRegister(RX8025T_REG_HOUR_ALARM, RX8025T_ALARM_AE_FLAG) != RX8025T_OK)
      {
        return RX8025T_ERROR_I2C;
      }
    }
    else if (alarm->hour < 24)
    {
      /* 特定小时 */
      if (RX8025T_WriteRegister(RX8025T_REG_HOUR_ALARM, RX8025T_DecToBcd(alarm->hour)) != RX8025T_OK)
      {
        return RX8025T_ERROR_I2C;
      }
    }
    else
    {
      return RX8025T_ERROR_INVALID;
    }

    /* 设置分钟寄存器 */
    if (alarm->minute & RX8025T_ALARM_AE_FLAG)
    {
      /* 每分钟 */
      if (RX8025T_WriteRegister(RX8025T_REG_MIN_ALARM, RX8025T_ALARM_AE_FLAG) != RX8025T_OK)
      {
        return RX8025T_ERROR_I2C;
      }
    }
    else if (alarm->minute < 60)
    {
      /* 特定分钟 */
      if (RX8025T_WriteRegister(RX8025T_REG_MIN_ALARM, RX8025T_DecToBcd(alarm->minute)) != RX8025T_OK)
      {
        return RX8025T_ERROR_I2C;
      }
    }
    else
    {
      return RX8025T_ERROR_INVALID;
    }
  }

  /* 配置扩展寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_EXTEN, &extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (enable)
  {
    if (alarm->mode == RX8025T_ALARM_DAY_MODE)
    {
      extreg |= RX8025T_EXTEN_WADA; /* 日模式 */
    }
    else
    {
      extreg &= ~RX8025T_EXTEN_WADA; /* 周模式 */
    }
  }

  if (RX8025T_WriteRegister(RX8025T_REG_EXTEN, extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 配置控制寄存器 */
  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (enable)
  {
    control |= RX8025T_CONTR_AIE;
  }
  else
  {
    control &= ~RX8025T_CONTR_AIE;
  }

  if (RX8025T_WriteRegister(RX8025T_REG_CONTROL, control) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 清除报警标志 */
  if (enable)
  {
    RX8025T_ClearAlarmFlag();
  }

  return RX8025T_OK;
}

/* 获取中断标志 */
RX8025T_StatusTypeDef RX8025T_GetInterruptFlags(uint8_t* flags)
{
  if (flags == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  return RX8025T_ReadRegister(RX8025T_REG_FLAG, flags);
}

/* 清除所有中断标志 */
RX8025T_StatusTypeDef RX8025T_ClearAllInterruptFlags(void)
{
  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 写入0清除所有标志位 */
  return RX8025T_WriteRegister(RX8025T_REG_FLAG, 0x00);
}

/* 清除更新标志 */
RX8025T_StatusTypeDef RX8025T_ClearUpdateFlag(void)
{
  uint8_t flag_reg = 0;

  if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  flag_reg &= ~RX8025T_FLAG_UF;

  return RX8025T_WriteRegister(RX8025T_REG_FLAG, flag_reg);
}

/* 清除定时器标志 */
RX8025T_StatusTypeDef RX8025T_ClearTimerFlag(void)
{
  uint8_t flag_reg = 0;

  if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  flag_reg &= ~RX8025T_FLAG_TF;

  return RX8025T_WriteRegister(RX8025T_REG_FLAG, flag_reg);
}

/* 清除报警标志 */
RX8025T_StatusTypeDef RX8025T_ClearAlarmFlag(void)
{
  uint8_t flag_reg = 0;

  if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  flag_reg &= ~RX8025T_FLAG_AF;

  return RX8025T_WriteRegister(RX8025T_REG_FLAG, flag_reg);
}

/* 设置FOUT输出频率 */
RX8025T_StatusTypeDef RX8025T_SetFOUT(RX8025T_FOUT_Freq freq)
{
  uint8_t extreg = 0;

  if (freq > 3)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_ReadRegister(RX8025T_REG_EXTEN, &extreg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  extreg &= ~(RX8025T_EXTEN_FSEL0 | RX8025T_EXTEN_FSEL1);
  extreg |= ((freq & 0x03) << 2);

  return RX8025T_WriteRegister(RX8025T_REG_EXTEN, extreg);
}

/* 获取电池状态 */
RX8025T_StatusTypeDef RX8025T_GetBatteryStatus(RX8025T_BatteryStatus* status)
{
  uint8_t flag_reg = 0;

  if (status == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  if (RX8025T_ReadRegister(RX8025T_REG_FLAG, &flag_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  status->voltage_low = (flag_reg & RX8025T_FLAG_VLF) ? true : false;
  status->voltage_detected = (flag_reg & RX8025T_FLAG_VDET) ? true : false;

  return RX8025T_OK;
}

/* 设置温度补偿间隔 */
RX8025T_StatusTypeDef RX8025T_SetTempCompInterval(RX8025T_TempCompInterval interval)
{
  uint8_t control_reg = 0;

  if (RX8025T_ReadRegister(RX8025T_REG_CONTROL, &control_reg) != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  control_reg &= 0x3F; /* 清空CSEL位 */
  control_reg |= interval;

  return RX8025T_WriteRegister(RX8025T_REG_CONTROL, control_reg);
}

/* 设置RAM数据 */
RX8025T_StatusTypeDef RX8025T_SetRAM(uint8_t data)
{
  return RX8025T_WriteRegister(RX8025T_REG_RAM, data);
}

/* 读取RAM数据 */
RX8025T_StatusTypeDef RX8025T_GetRAM(uint8_t* data)
{
  if (data == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  return RX8025T_ReadRegister(RX8025T_REG_RAM, data);
}

/* 写入寄存器 */
RX8025T_StatusTypeDef RX8025T_WriteRegister(uint8_t reg, uint8_t data)
{
  uint8_t buffer[2];

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  buffer[0] = reg;
  buffer[1] = data;

  if (HAL_I2C_Master_Transmit(rx8025t_hi2c, RX8025T_I2C_ADDR_HAL, buffer, 2, RX8025T_I2C_TIMEOUT) != HAL_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  return RX8025T_OK;
}

/* 读取寄存器 */
RX8025T_StatusTypeDef RX8025T_ReadRegister(uint8_t reg, uint8_t* data)
{
  if (data == NULL)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 发送寄存器地址 */
  if (HAL_I2C_Master_Transmit(rx8025t_hi2c, RX8025T_I2C_ADDR_HAL, &#174;, 1, RX8025T_I2C_TIMEOUT) != HAL_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 读取数据 */
  if (HAL_I2C_Master_Receive(rx8025t_hi2c, RX8025T_I2C_ADDR_HAL, data, 1, RX8025T_I2C_TIMEOUT) != HAL_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  return RX8025T_OK;
}

/* 十进制转BCD */
uint8_t RX8025T_DecToBcd(uint8_t dec)
{
  return ((dec / 10) << 4) | (dec % 10);
}

/* BCD转十进制 */
uint8_t RX8025T_BcdToDec(uint8_t bcd)
{
  return ((bcd >> 4) * 10) + (bcd & 0x0F);
}

/* 获取星期字符串 */
const char* RX8025T_GetDayOfWeekString(uint8_t day_of_week)
{
  static const char* days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

  if (day_of_week > 6)
  {
    return "Invalid";
  }

  return days[day_of_week];
}

/* 判断是否为闰年 */
bool RX8025T_IsLeapYear(uint16_t year)
{
  return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}

/* 获取月份天数 */
uint8_t RX8025T_GetDaysInMonth(uint8_t month, uint16_t year)
{
  static const uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

  if (month < 1 || month > 12)
  {
    return 0;
  }

  if (month == 2 && RX8025T_IsLeapYear(year))
  {
    return 29;
  }

  return days_in_month[month - 1];
}

/* 星期转寄存器值 */
static uint8_t DayOfWeekToRegister(uint8_t day_of_week)
{
  if (day_of_week > 6)
  {
    return 0x01; /* 默认周日 */
  }

  return (1 << day_of_week);
}

/* 寄存器值转星期 */
static uint8_t RegisterToDayOfWeek(uint8_t reg_value)
{
  reg_value &= 0x07; /* 只取低3位 */

  switch (reg_value)
  {
  case 0x01:
    return 0; /* 周日 */
  case 0x02:
    return 1; /* 周一 */
  case 0x04:
    return 2; /* 周二 */
  case 0x08:
    return 3; /* 周三 */
  case 0x10:
    return 4; /* 周四 */
  case 0x20:
    return 5; /* 周五 */
  case 0x40:
    return 6; /* 周六 */
  default:
    return 0; /* 默认周日 */
  }
}

/* 检查I2C状态 */
static RX8025T_StatusTypeDef RX8025T_I2C_Check(void)
{
  if (rx8025t_hi2c == NULL)
  {
    return RX8025T_ERROR;
  }

  if (rx8025t_hi2c->State == HAL_I2C_STATE_BUSY || rx8025t_hi2c->State == HAL_I2C_STATE_BUSY_TX || rx8025t_hi2c->State == HAL_I2C_STATE_BUSY_RX)
  {
    return RX8025T_ERROR;
  }

  return RX8025T_OK;
}

/* 读取多个字节 */
static RX8025T_StatusTypeDef RX8025T_ReadBytes(uint8_t reg, uint8_t* data, uint16_t len)
{
  if (data == NULL || len == 0)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 使用HAL_I2C_Mem_Read一次性读取多个寄存器 */
  if (HAL_I2C_Mem_Read(rx8025t_hi2c, RX8025T_I2C_ADDR_HAL, reg, I2C_MEMADD_SIZE_8BIT, data, len, RX8025T_I2C_TIMEOUT) != HAL_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  return RX8025T_OK;
}

/* 写入多个字节 */
static RX8025T_StatusTypeDef RX8025T_WriteBytes(uint8_t reg, uint8_t* data, uint16_t len)
{
  if (data == NULL || len == 0)
  {
    return RX8025T_ERROR_INVALID;
  }

  if (RX8025T_I2C_Check() != RX8025T_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  /* 使用HAL_I2C_Mem_Write一次性写入多个寄存器 */
  if (HAL_I2C_Mem_Write(rx8025t_hi2c, RX8025T_I2C_ADDR_HAL, reg, I2C_MEMADD_SIZE_8BIT, data, len, RX8025T_I2C_TIMEOUT) != HAL_OK)
  {
    return RX8025T_ERROR_I2C;
  }

  return RX8025T_OK;
}

/* 验证时间有效性 */
static bool IsTimeValid(RX8025T_TimeTypeDef* time)
{
  if (time == NULL)
  {
    return false;
  }

  /* 基本范围检查 */
  if (time->second > 59 || time->minute > 59 || time->hour > 23 || time->day_of_week > 6 || time->date < 1 || time->date > 31 || time->month < 1 ||
      time->month > 12 || time->year > 99)
  {
    return false;
  }

  /* 月份天数检查 */
  uint8_t max_days = RX8025T_GetDaysInMonth(time->month, 2000 + time->year);
  if (time->date > max_days)
  {
    return false;
  }

  return true;
}


[C] 纯文本查看 复制代码
调用:

void enter_standby_mode(void)
{
  // clear flag
  RX8025T_ClearAllInterruptFlags();
  HAL_Delay(5);

  // 重新回复GPIO
  InitBoardGPIO();

  // RX8025X gpio set to turn off  
  __PWR_OFF_ENABLE;
  HAL_Delay(1);

  // Delay util turn off
  uint32_t d = 0;
  while (1)
  {
printf("d:%d\n", d++); 
    HAL_Delay(200);
  }
}


// 休眠业务代码
if (can_enter_standby())
{
  // 防止有外设还有缓存没有发送完
  osDelay(3000);
  
  // 发送一次测试完成请求
  UploadACK();  

  // 设置下一次闹钟时间,中间调用有任何返回失败的就重启
  set_next_alarm_time();
  // 进入休眠模式
  enter_standby_mode();
  HAL_Delay(100);
}




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-4-1 05:20 , Processed in 0.174358 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表