S-35390A计时芯片介绍及开发方案

news2024/11/19 14:27:19

计时芯片

S-35390A芯片是计时芯片,一般用来计算时间。低功耗,宽电压,受温度影响小,适用于很多电路。它有一个问题,不阻止用户设置不存在的时间,设置进去之后计时或者闹钟定时会出错。

规格书阅读

首先我们先读懂这个芯片是怎么用的。

引脚表

基本上一看这个引脚表就知道大概,1号和5号引脚是中断输出引脚,2号和3号引脚之间应该接个晶振,6号和7号引脚通过IIC跟主控芯片通讯,其余的都是电源和地。

模块框图

大概就能知道里面的框架是啥样的,里面最主要就是实时时间的寄存器,通过跟中断1和中断2寄存器对比决定两路中断的输出。具体时间通过中间的总线借助IIC串口通讯模块发出去。另外就是有几个检测电源电压的寄存器、状态寄存器、时钟校正寄存器和一个给用户可以当做E方用的自由寄存器。

通讯数据配置

跟普通的IIC一样,主控芯片先发个设备号0110,跟着3位的命令,1位的读写方向,等到计时芯片ACK之后,继续发送剩下的数据。

命令表格

这里有所有的命令,读写状态寄存器1和2、读写实时数据1和2、读写中断寄存器1和2、存取时钟校正寄存器和自由寄存器。

标1的是只写。标2的是用户自由寄存器,对应上面框图的用户自由寄存器。标3和4的是只读。标5的是测试位,使用的时候要保证为0。标6的怎么写都不影响。

状态寄存器1

POC检测电源电流,初始化的时候是0,有电流的时候是1,如果上电之后为0,就要重启整个芯片。

BLD检测电源电压,正常为0,读到是1的时候要重启整个芯片了。

INT1和INT2是中断事件发生标志位。

SC0和SC1都是用户自由定义的。

12/24如果是0就是12小时制,如果是1就是24小时制。

RESET平时为0,写个1进去就重启芯片。

状态寄存器2

TEST测试位设置为0就行,当设置为1的时候,INT1会输出1Hz的方波。

INT2AE、 INT2ME、 INT2FE共同决定了中断输出2引脚的输出模式:无中断、输出用户设定的频率、每分钟边沿中断、50%占空比的每分钟周期中断、闹钟模式。

INT1AE、 INT1ME、 INT1FE共同决定了中断输出1引脚的输出模式:无中断、输出用户设定的频率、每分钟边沿中断、50%占空比的每分钟周期中断、闹钟模式、每分钟周期中断、输出32.768kHz。

实时数据1和2

以写入实时数据寄存器1为例,流程如下。

里面的年是按照西历来计算的,只能写0-99,使用BCD码,低位在前。

譬如2053年,就写入53,二进制Y1-Y80就是1100 1010.

AM/PM如果是24小时制就无所谓写什么,如果是12小时制0是am,1就是pm.

后面的实时数据寄存器2也是一样。

中断寄存器1和2

根据状态寄存器2的设置,选择中断输出引脚是闹钟模式或者输出用户设定的频率

INT1AE = 1, INT1ME = 0, INT1FE = 0,就是闹钟模式。
INT1ME = 0, INT1FE = 1,就是输出用户设定的频率。
其实就是对应状态寄存器那个表格,INT2也是一样。

闹钟模式

时间到了就触发中断,里面的AM/PM要跟实时时钟里面一致。

B0的三个标志位表示设置的周、时、分是否有效,譬如下面这个设置闹钟为每天晚上7点,周的标志位就需要为0.

输出用户设定的频率

频率是每个位累加的,SC是用户自由寄存器。

校准寄存器

可以提前和延迟一定的时间。

用户自由寄存器

写一些用户想存储的信息,当做E方使用

使用注意事项

上电后POC为0,或者POC为1但是INT没有输出1 Hz方波,芯片内部数据可能处于不确定状态,需要重新上电。
上电之后由于检测电路正在工作,在上电后至少0.5秒后才进行数据传输。

接口编写

基本定义

命令

#define S35390_TIME_ADDRESS             0x32
#define S35390_STATUS1_ADDRESS       	0x30
#define S35390_STATUS2_ADDRESS       	0x31
#define S35390_INT1_REG_ADDRESS       	0x34 
#define S35390_INT2_REG_ADDRESS       	0x35

当前时间结构体和中断闹钟结构体

typedef	struct
{
	unsigned int 	year;		//year
	unsigned char 	month;		//month
	unsigned char 	day;		//day
    unsigned char 	hour;		//hour
	unsigned char 	minute;		//minute
	unsigned char 	second;		//second
	unsigned char 	week;		//week
}rtc_time;

typedef	struct
{
	unsigned char 	minute;		//minute
	unsigned char 	hour;		//hour
    unsigned char 	week;		//week
    unsigned char 	min_en;		//minute enable
    unsigned char 	hour_en;	//hour enable
    unsigned char 	week_en;	//min enable
}rtc_alarm;

接口

RTC_S35390_Init

初始化函数里面只是要配置下主控芯片的IIC外设,设置下上电默认时间。

S35390_ReadRegs

读取多字节数据

bool S35390_ReadRegs(uint8_t addr, uint8_t length,uint8_t *values)
{
	status_t ret=STATUS_BUSY;
    uint8_t Try = 3;

    if(xSemaphore_i2c != NULL )
    {
        if( xSemaphoreTake( xSemaphore_i2c, ( TickType_t ) 50 ) == pdTRUE )//获取信号量
        {
            while((Try--)&&(ret != STATUS_SUCCESS))//最多尝试3次
			{
            	 lpi2cMasterState.slaveAddress = addr;//读取地址

                /* Request data from the bus slave */
                ret = I2C_DRV_MasterReceiveDataBlock(INST_LPI2C1,values,length,true,10);
			}
            xSemaphoreGive( xSemaphore_i2c);//释放信号量
        }
    }
    
    if(ret != STATUS_SUCCESS)//读出失败
	{
		I2C_Reset();//重新初始化IIC模块
	}
    return ret;
}

S35390_WriteRegs

读取多字节数据

static bool S35390_WriteRegs(uint8_t addr, uint8_t length, uint8_t *values)
{
	status_t ret=STATUS_BUSY;
	uint8_t Try = 3;

	uint8_t masterbuffer[32]={0};
	memcpy(&masterbuffer[0],values,length);

    if( xSemaphore_i2c != NULL )
    {
        if( xSemaphoreTake( xSemaphore_i2c, ( TickType_t ) 50 ) == pdTRUE )//获取信号量
        {
			while((Try--)&&(ret != STATUS_SUCCESS))//最多尝试3次
			{
				lpi2cMasterState.slaveAddress = addr;//写入地址
				
				ret=I2C_DRV_MasterSendDataBlock(INST_LPI2C1, masterbuffer, length, true,100UL);
			}
			xSemaphoreGive( xSemaphore_i2c);//释放信号量
        }
    }

    if(ret != STATUS_SUCCESS)//写入失败
    {
		I2C_Reset();//重新初始化IIC模块
    }
    
    return  ret;
}

S35390_GetYear

别被这个名字骗了,其实就是将获取的年数据BCD码转成十进制数据。

static uint8_t S35390_GetYear(uint8_t regYearData )
{
	uint8_t timeYearData = 0x00;

	if ( regYearData & 1 )
	{
		timeYearData += 80;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 40;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 20;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 10;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 8;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 4;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 2;
	}
	regYearData >>= 1;
	if ( regYearData & 1 )
	{
		timeYearData += 1;
	}

	if ( timeYearData > 99 )//最大限制
	{
		timeYearData = 99;
	}
	else
	{
		; /* do nothing*/
	}

	return 	timeYearData;
}

S35390_GetMonth

获取月数据BCD码转成十进制数据。

static uint8_t S35390_GetMonth(uint8_t regMonthData )
{
	uint8_t timeMonthData = 0x00;

	regMonthData >>= 3;
	if ( regMonthData & 1 )
	{
		timeMonthData += 10;
	}
	regMonthData >>= 1;
	if ( regMonthData & 1 )
	{
		timeMonthData += 8;
	}
	regMonthData >>= 1;
	if ( regMonthData & 1 )
	{
		timeMonthData += 4;
	}
	regMonthData >>= 1;
	if ( regMonthData & 1 )
	{
		timeMonthData += 2;
	}
	regMonthData >>= 1;
	if ( regMonthData & 1 )
	{
		timeMonthData += 1;
	}

	if ( timeMonthData == 0x00 )//最小限制
	{
		timeMonthData = 0x01;
	}
	else if ( timeMonthData > 12 )//最大限制
	{
		timeMonthData = 12;
	}
	else
	{
		; /* do nothing*/
	}

	return 	timeMonthData;
}

S35390_GetDay

获取日数据BCD码转成十进制数据。

static uint8_t S35390_GetDay(uint8_t regDayData )
{
	uint8_t timeDayData = 0x00;

	regDayData >>= 2;
	if ( regDayData & 1 )
	{
		timeDayData += 20;
	}
	regDayData >>= 1;
	if ( regDayData & 1 )
	{
		timeDayData += 10;
	}
	regDayData >>= 1;
	if ( regDayData & 1 )
	{
		timeDayData += 8;
	}
	regDayData >>= 1;
	if ( regDayData & 1 )
	{
		timeDayData += 4;
	}
	regDayData >>= 1;
	if ( regDayData & 1 )
	{
		timeDayData += 2;
	}
	regDayData >>= 1;
	if ( regDayData & 1 )
	{
		timeDayData += 1;
	}

	if ( timeDayData == 0 )//最小限制
	{
		timeDayData = 1;
	}
	else if ( timeDayData > 31 )//最大限制
	{
		timeDayData = 31;
	}
	else
	{
		; /* do nothing*/
	}

	return 	timeDayData;
}

S35390_GetWeek

获取周数据BCD码转成十进制数据。

static uint8_t S35390_GetWeek(uint8_t regWeekData )
{
	uint8_t timeWeekData = 0x00;

	regWeekData >>= 5;
	if ( regWeekData & 1 )
	{
		timeWeekData += 4;
	}
	regWeekData >>= 1;
	if ( regWeekData & 1 )
	{
		timeWeekData += 2;
	}
	regWeekData >>= 1;
	if ( regWeekData & 1 )
	{
		timeWeekData += 1;
	}

	return 	timeWeekData;
}

S35390_GetHour

获取时数据BCD码转成十进制数据。

static uint8_t S35390_GetHour(uint8_t regHourData )
{
	uint8_t timeHourData = 0x00;

	regHourData >>= 2;
	if ( regHourData & 1 )
	{
		timeHourData += 20;
	}
	regHourData >>= 1;
	if ( regHourData & 1 )
	{
		timeHourData += 10;
	}
	regHourData >>= 1;
	if ( regHourData & 1 )
	{
		timeHourData += 8;
	}
	regHourData >>= 1;
	if ( regHourData & 1 )
	{
		timeHourData += 4;
	}
	regHourData >>= 1;
	if ( regHourData & 1 )
	{
		timeHourData += 2;
	}
	regHourData >>= 1;
	if ( regHourData & 1 )
	{
		timeHourData += 1;
	}

	if ( timeHourData > 23 )//最大限制
	{
		timeHourData = 23;
	}
	else
	{
		; /* do nothing*/
	}

	return 	timeHourData;
}

S35390_GetMinute

获取分数据BCD码转成十进制数据。

static uint8_t S35390_GetMinute(uint8_t regMinuteData )
{
	uint8_t timeMinuteData = 0x00;

	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 40;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 20;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 10;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 8;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 4;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 2;
	}
	regMinuteData >>= 1;
	if ( regMinuteData & 1 )
	{
		timeMinuteData += 1;
	}

	if ( timeMinuteData > 59 )//最大限制
	{
		timeMinuteData = 59;
	}
	else
	{
		; /* do nothing*/
	}

	return 	timeMinuteData;
}

S35390_SetYear

别被它名字骗了,这个接口只是将年数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetYear(uint16_t timeYearData )
{
	uint8_t regYearData = 0x00;

	if (timeYearData >= 2000)//允许入参格式为2000+的
	{
		timeYearData -= 2000;
	}
	else
	{
		; /* do nothing*/
	}

	if (timeYearData > 99)//限制入参大小
	{
		timeYearData = 0;
	}
	else
	{
		; /* do nothing*/
	}

	if ((timeYearData/80) == 1)
	{
		regYearData |= 0x01;
		timeYearData -= 80;
	}
	if ((timeYearData/40) == 1)
	{
		regYearData |= 0x02;
		timeYearData -= 40;
	}
	if ((timeYearData/20) == 1)
	{
		regYearData |= 0x04;
		timeYearData -= 20;
	}
	if ((timeYearData/10) == 1)
	{
		regYearData |= 0x08;
		timeYearData -= 10;
	}
	if ((timeYearData/8) == 1)
	{
		regYearData |= 0x10;
		timeYearData -= 8;
	}
	if ((timeYearData/4) == 1)
	{
		regYearData |= 0x20;
		timeYearData -= 4;
	}
	if ((timeYearData/2) == 1)
	{
		regYearData |= 0x40;
		timeYearData -= 2;
	}
	if (timeYearData == 1)
	{
		regYearData |= 0x80;
	}

	return 	regYearData;
}

S35390_SetMonth

将月数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetMonth(uint8_t timeMonthData )
{
	uint8_t regMonthData = 0x00;

	if (timeMonthData == 0x00)//限制最小
	{
		timeMonthData = 0x01;
	}
	else if (timeMonthData > 12)//限制最大
	{
		timeMonthData = 1;
	}
	else
	{
		; /* do nothing*/
	}

	if ((timeMonthData/10) == 1)
	{
		regMonthData |= 0x08;
		timeMonthData -= 10;
	}
	if ((timeMonthData/8) == 1)
	{
		regMonthData |= 0x10;
		timeMonthData -= 8;
	}
	if ((timeMonthData/4) == 1)
	{
		regMonthData |= 0x20;
		timeMonthData -= 4;
	}
	if ((timeMonthData/2) == 1)
	{
		regMonthData |= 0x40;
		timeMonthData -= 2;
	}
	if (timeMonthData == 1)
	{
		regMonthData |= 0x80;
	}

	return 	regMonthData;
}

S35390_SetDay

将日数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetDay(uint8_t timeDayData )
{
	uint8_t regDayData = 0x00;

	if (timeDayData == 0x00)//限制最小
	{
		timeDayData = 0x01;
	}
	else if (timeDayData > 31)//限制最大
	{
		timeDayData = 1;
	}
	else
	{
		; /* do nothing*/
	}

	if ((timeDayData/20) == 1)
	{
		regDayData |= 0x04;
		timeDayData -= 20;
	}
	if ((timeDayData/10) == 1)
	{
		regDayData |= 0x08;
		timeDayData -= 10;
	}
	if ((timeDayData/8) == 1)
	{
		regDayData |= 0x10;
		timeDayData -= 8;
	}
	if ((timeDayData/4) == 1)
	{
		regDayData |= 0x20;
		timeDayData -= 4;
	}
	if ((timeDayData/2) == 1)
	{
		regDayData |= 0x40;
		timeDayData -= 2;
	}
	if (timeDayData == 1)
	{
		regDayData |= 0x80;
	}

	return 	regDayData;
}

S35390_SetWeek

将周数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetWeek(uint8_t timeWeekData )
{
	uint8_t regWeekData = 0x00;

    if (timeWeekData > 6)//限制最大
	{
    	timeWeekData = 0;
	}
	else
	{
		; /* do nothing*/
	}

	if ((timeWeekData/4) == 1)
	{
		regWeekData |= 0x20;
		timeWeekData -= 4;
	}
	if ((timeWeekData/2) == 1)
	{
		regWeekData |= 0x40;
		timeWeekData -= 2;
	}
	if (timeWeekData == 1)
	{
		regWeekData |= 0x80;
	}

	return 	regWeekData;
}

S35390_SetHour

将时数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetHour(uint8_t timeHourData)
{
	uint8_t regHourData = 0x00;

    if (timeHourData > 23)//限制最大
	{
    	timeHourData = 0;
	}
	else
	{
		; /* do nothing*/
	}

    if ((timeHourData/20) == 1)
	{
    	regHourData |= 0x04;
		timeHourData -= 20;
	}
	if ((timeHourData/10) == 1)
	{
		regHourData |= 0x08;
		timeHourData -= 10;
	}
	if ((timeHourData/8) == 1)
	{
		regHourData |= 0x10;
		timeHourData -= 8;
	}
	if ((timeHourData/4) == 1)
	{
		regHourData |= 0x20;
		timeHourData -= 4;
	}
	if ((timeHourData/2) == 1)
	{
		regHourData |= 0x40;
		timeHourData -= 2;
	}
	if (timeHourData == 1)
	{
		regHourData |= 0x80;
	}

	return 	regHourData;
}

S35390_SetMinute

将分数据转换成BCD码,然后返回回去。

static uint8_t S35390_SetMinute(uint8_t timeMinuteData )
{
	uint8_t regMinuteData = 0x00;

    if (timeMinuteData > 59)//限制最大
	{
    	timeMinuteData = 0;
	}
	else
	{
		; /* do nothing*/
	}

    if ((timeMinuteData/40) == 1)
	{
    	regMinuteData |= 0x02;
		timeMinuteData -= 40;
	}
    if ((timeMinuteData/20) == 1)
	{
    	regMinuteData |= 0x04;
    	timeMinuteData -= 20;
	}
	if ((timeMinuteData/10) == 1)
	{
		regMinuteData |= 0x08;
		timeMinuteData -= 10;
	}
	if ((timeMinuteData/8) == 1)
	{
		regMinuteData |= 0x10;
		timeMinuteData -= 8;
	}
	if ((timeMinuteData/4) == 1)
	{
		regMinuteData |= 0x20;
		timeMinuteData -= 4;
	}
	if ((timeMinuteData/2) == 1)
	{
		regMinuteData |= 0x40;
		timeMinuteData -= 2;
	}
	if (timeMinuteData == 1)
	{
		regMinuteData |= 0x80;
	}

	return 	regMinuteData;
}

S35390_GetStatusReg1

获取状态寄存器1、状态寄存器2也是如此。

uint8_t S35390_GetStatusReg1(uint8_t *statusReg)
{
	return S35390_ReadRegs(S35390_STATUS1_ADDRESS,1,statusReg);
}

S35390_SetStatusReg1

设置状态寄存器1、状态寄存器2也是如此。

uint8_t S35390_SetStatusReg1(uint8_t *statusReg)
{
	return S35390_WriteRegs(S35390_STATUS1_ADDRESS,1, statusReg);
}

S35390_SetAlarm1

设置中断闹钟1、中断闹钟2也是如此,注意需要先在状态寄存器里面设置为闹钟模式。

int S35390_SetAlarm1(rtc_alarm *alarmTime)
{
	status_t ret=STATUS_BUSY;
	uint8_t reg_data[3] = {0};
	uint8_t flg_am_pm = 0;		//0:am,1:pm

	reg_data[0] = S35390_SetWeek(alarmTime->week) | alarmTime->week_en;

	if(alarmTime->hour >= 12)
	{
		flg_am_pm = 1;
	}
    
	reg_data[1] = S35390_SetHour(alarmTime->hour) | alarmTime->hour_en | (flg_am_pm << 1);
	reg_data[2] = S35390_SetMinute(alarmTime->minute) | alarmTime->min_en;

	ret = S35390_WriteRegs(S35390_INT1_REG_ADDRESS,3,reg_data);

	return ret;
}

S35390_GetAlarm1

获取闹钟1设置

int S35390_GetAlarm1(rtc_alarm *alarmTime)
{
	status_t ret=STATUS_BUSY;
	uint8_t reg_data[3] = {0};

	ret =  S35390_ReadRegs(S35390_INT1_REG_ADDRESS,3, reg_data);

    if(ret != STATUS_SUCCESS)
	{
    	LOG_ERR( "Get alarm set  time error!\r\n");
	}
	else
	{
		alarmTime->week = S35390_GetWeek(reg_data[0]);
		alarmTime->week_en = reg_data[0] & 0x01;

		alarmTime->hour = S35390_GetHour(reg_data[1]);
		alarmTime->hour_en = reg_data[1] & 0x01;

		alarmTime->minute = S35390_GetMinute(reg_data[2]);
		alarmTime->min_en = reg_data[2] & 0x01;
	}
    
    return  ret;
}

S35390_EnableAlarm1

使能闹钟模式,其实就是将状态寄存器1改成闹钟模式。

int S35390_EnableAlarm1(void)
{
	status_t ret=STATUS_BUSY;
	uint8_t reg_data = 0;

	ret =  S35390_ReadRegs(S35390_STATUS2_ADDRESS,1, &reg_data);

	if(STATUS_SUCCESS == ret)
	{
		//INT1AE = 1;INT1ME = 0;INT1FE = 0;
		reg_data &= ~(0x01 << 4);
		reg_data |= (0x01 << 5);
		reg_data &= ~(0x03 << 6);
		ret =  S35390_WriteRegs(S35390_STATUS2_ADDRESS,1, &reg_data);
	}

	return ret;
}

S35390_DisableAlarm

失能闹钟模式,其实就是改变状态寄存器1。

int S35390_DisableAlarm(void)
{
	status_t ret=STATUS_BUSY;
	uint8_t reg_data = 0;

	ret =  S35390_ReadRegs(S35390_STATUS1_ADDRESS,1, &reg_data);

	if(STATUS_SUCCESS == ret)
	{
		//INT1AE = 0;INT1ME = 0;INT1FE = 0;
		reg_data &= ~(0x01 << 4);
		reg_data &= ~(0x01 << 5);
		reg_data &= ~(0x03 << 6);
		ret =  S35390_WriteRegs(S35390_STATUS1_ADDRESS,1, &reg_data);
	}

	return ret;
}

S35390_GetTime

获取当前时间

#define S35390_BTC_SEC					0x06
#define S35390_BTC_MIN					0x05
#define S35390_BTC_HOUR					0x04
#define S35390_BTC_WEEK					0x03
#define S35390_BTC_DAY					0x02
#define S35390_BTC_MONTH				0x01
#define S35390_BTC_YEAR					0x00

uint8_t S35390_GetTime(rtc_time *time)
{
	uint8_t reg_date[7]={0};
	uint8_t err = 0;

	err = S35390_ReadRegs(S35390_TIME_ADDRESS,7,reg_date);//获取当前时间到reg_date

	time->second  = S35390_GetMinute(reg_date[S35390_BTC_SEC]); //转换成十进制数据
	time->minute  = S35390_GetMinute(reg_date[S35390_BTC_MIN]);
	time->hour = S35390_GetHour(reg_date[S35390_BTC_HOUR]);
	time->week = S35390_GetWeek(reg_date[S35390_BTC_WEEK]);
	time->day = S35390_GetDay(reg_date[S35390_BTC_DAY]);
	time->month  = S35390_GetMonth(reg_date[S35390_BTC_MONTH]);
	time->year = S35390_GetYear(reg_date[S35390_BTC_YEAR])+2000;

	LOG_INFO("%-30s%s%d,%d,%d,%d,%d,%d,%d\r\n","GetRTC","=",time->year,time->month,time->day,time->hour,time->minute,time->second,time->week);

	return err;
}

S35390_EnableAlarm

其实就是将状态寄存器设置为闹钟模式

int S35390_EnableAlarm(void)
{
	status_t ret=STATUS_BUSY;
	uint8_t reg_data = 0;

	ret =  S35390_ReadRegs(S35390_STATUS2_ADDRESS,1, &reg_data);

	if(STATUS_SUCCESS == ret)
	{
		//INT1AE = 1;INT1ME = 0;INT1FE = 0;
		reg_data &= ~(0x01 << 4);
		reg_data |= (0x01 << 5);
		reg_data &= ~(0x03 << 6);
		ret =  S35390_WriteRegs(S35390_STATUS2_ADDRESS,1, &reg_data);
	}

	return ret;
}

S35390_SetTime

设置当前时间

uint8_t  S35390_SetTime(rtc_time *time)
{
	uint8_t reg_date[7] = {0};
	uint8_t ret = 0xff;
	uint8_t week_tmp = 0;

	reg_date[S35390_BTC_SEC]   = S35390_SetMinute(time->second); //转换成BCD码
	reg_date[S35390_BTC_MIN]   = S35390_SetMinute(time->minute);
	reg_date[S35390_BTC_HOUR]  = S35390_SetHour(time->hour);

	week_tmp = CalculateWeekForKimLarsenCalculationFormula(time->year,time->month,time->day);//计算出周数据
	
	if(time->week != week_tmp)
	{
		LOG_ERR("week set error!\r\n");
	}
	reg_date[S35390_BTC_WEEK]  = S35390_SetWeek(week_tmp);

	reg_date[S35390_BTC_DAY]   = S35390_SetDay(time->day);
	reg_date[S35390_BTC_MONTH] = S35390_SetMonth(time->month);
	reg_date[S35390_BTC_YEAR]  = S35390_SetYear(time->year);

	ret =  S35390_WriteRegs(S35390_TIME_ADDRESS,7, reg_date);

	return ret;
}

static uint8_t CalculateWeekForKimLarsenCalculationFormula(uint16_t year, uint8_t month, uint8_t date)
{
    uint8_t week;

    if ((month == 1) || (month == 2)) {
        month += 12;
        year--;
    }
    week = (date + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;

    return week;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何移除禁用WordPress默认小工具(附WordPress默认小工具名称)

WordPress 自带的小工具非常多&#xff0c;但是我们用到的也就那么几种&#xff0c;甚至一种都不会用到&#xff0c;所以很有必要注销&#xff08;去除&#xff09;掉一些不用的小工具。实现的方法也很简单&#xff0c;只需将以下代码&#xff0c;根据自己的情况删除需要用的小…

精品基于SpringBoot的体育馆场地预约赛事管理系统的设计与实现-选座

《[含文档PPT源码等]精品基于SpringBoot的体育馆管理系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#…

掌握3个Mock工具,轻松玩转单元测试

公司要求提升单元测试的质量&#xff0c;提高代码的分支覆盖率和行覆盖率&#xff0c;安排我研究单元测试&#xff0c;指定方案分享并在开发部普及开。 单元测试中的Mock的目的 Mock的主要目的是让单元测试Write Once, Run Everywhere. 即编写一次后&#xff0c;可以在任意时…

程序媛的mac修炼手册-- 2024如何彻底卸载Python

啊&#xff0c;前段时间因为想尝试chatgpt的API&#xff0c;需要先创建一个python虚拟环境来安装OpenAI Python library. 结果&#xff0c;不出意外的出意外了&#xff0c;安装好OpenAI Python library后&#xff0c;因为身份认证问题&#xff0c;根本就没有获取API key的权限…

【YOLO系列算法人员摔倒检测】

YOLO系列算法人员摔倒检测 模型和数据集下载YOLO系列算法的人员摔倒检测数据集可视化数据集图像示例&#xff1a; 模型和数据集下载 yolo行人跌倒检测一&#xff1a; 1、训练好的行人跌倒检测权重以及PR曲线&#xff0c;loss曲线等等&#xff0c;map达90%多&#xff0c;在行人跌…

GEE必须会教程—曾“几何”时(Geometry类型)

几何图形组成了世界万物&#xff0c;在数学史具有重要地位&#xff0c;将几何图形迁移到地理空间信息的处理上&#xff0c;我们我们得到就是研究区域的边界范围&#xff0c;因此&#xff0c;在学习矢量数据和栅格数据之前&#xff0c;我们有必要了解几何图形在GEE上的编辑。 1…

019 Spring Boot+Vue 电影院会员管理系统(源代码+数据库+文档)

部分代码地址&#xff1a; https://github.com/XinChennn/xc019-cinema 一、系统介绍 cinema项目是一套电影院会员管理系统&#xff0c;使用前后端分离架构开发包含管理员、会员管理、会员卡管理、电影票、消费记录、数据统计等模块 二、所用技术 后端技术栈&#xff1a; …

【爬虫逆向实战篇】定位加密参数、断点调试与JS代码分析

文章目录 1. 写在前面2. 确认加密参数3. 加密参数定位4. XHR断点调试 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向…

openssl3.2 - 编译 - zlib.dll不要使用绝对路径

文章目录 openssl3.2 - 编译 - 编译时的动态库zlib.dll不要使用绝对路径概述测试zlib特性在安装好的目录中是否正常笔记70-test_tls13certcomp.t80-test_cms.t对测试环境的猜测从头再编译测试安装一次测试一下随便改变位置的openssl用到zlib时是否好使测试一下随便改变位置的op…

11-ATF初始化Normal cpu context

ATF (Arm Trusted Firmware) 初始化 Normal CPU Context 的步骤主要涉及设置正常世界(Normal World)CPU的环境,确保在从安全世界(Secure World)切换到正常世界时,CPU能够正确执行正常世界的代码。以下是一般步骤的概述: CPU启动与初始化: 在系统启动时,CPU首先在安全世…

ChatGPT Plus遇到订阅被拒原因与解决方案

ChatGPT Plus被广泛认为相比普通版本更快、更强&#xff0c;并且能最先体验新功能。 很多小伙伴再订阅时遇到图片中的问题 错误提示包括这些&#xff1a; Your credit card was declined.Try paying with a debit card instead.您的信用卡被拒绝了。请尝试用借记卡支付。你的…

Vue+SpringBoot打造高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

国内Twitter账号注册要注意什么?注册多个Twitter账号如何防止被封?

在这个数字化快速发展的时代&#xff0c;Twitter作为一个全球性的社交媒体平台&#xff0c;对于个人品牌塑造乃至跨境电商均有着不可忽视的影响力。然而&#xff0c;在中国大陆地区&#xff0c;对于Twitter账号注册以及如何安全地注册多个Twitter账号这样的话题&#xff0c;往往…

详解 IT/OT 融合的五层架构(从PLC/SCADA到MES/ERP)

作为一个电气自动化的从业者&#xff0c;有必要搞懂下面术语的意思。 IT&#xff1a;Information Technology的缩写&#xff0c;指信息技术&#xff1b; OT&#xff1a;Operational Technology的缩写&#xff0c;指操作层面的技术&#xff0c;比如运营技术&#xff1b;CT&…

Java8 Stream API 详解:流式编程进行数据处理

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…

xss靶场实战(xss-labs-master靶场)

xss-labs-master靶场链接&#xff1a;https://pan.baidu.com/s/1X_uZLF3CWw2Cmt3UnZ1bTw?pwdgk9c 提取码&#xff1a;gk9c xss-labs level 1 修改 url 地址中的name<script>alert(1)</script>&#xff0c;便可以通关 level 2 在搜索框中输入的 JS 代码无法执行 …

vDPA测试环境搭建

要求&#xff1a; 运行 Linux 发行版的计算机。本指南使用 CentOS 9-stream&#xff0c;但对于其他 Linux 发行版&#xff0c;特别是对于 Red Hat Enterprise Linux 7&#xff0c;命令不应有重大变化。 具有 sudo 权限的用户 ~ 主目录中有 25 GB 的可用空间 至少 8GB 内存 …

完美解决ubuntu+windows双系统下时间不正确问题

在同一台电脑上安装ubuntuwindows双系统时&#xff0c;会出现某个系统的时间不正确的问题&#xff0c;而由于windows同步时间实在是太慢了&#xff0c;如果不去解决&#xff0c;windows上的时间大概率一直都是不对的。 原因分析 windows采用LocalTime机制设置时间&#xff0c…

车载电子电器架构 —— OEM基础技术概念开发流程

车载电子电器架构 —— 基础技术概念开发 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

Sora—openai最新大模型文字生成视频

这里没办法发视频&#xff0c;发几个图片感受感受吧 OpenAI发布了Sora&#xff0c;一种文字生成视频的技术&#xff0c;从演示看&#xff0c;效果还是相当不错的。 Sora的强大之处在于其能够根据文本描述&#xff0c;生成长达 60秒的视频&#xff0c;其中包含精细复杂的场景…