关于武汉芯景科技有限公司的IIC接口日历时钟芯片XJ8372开发指南(兼容RS5C372)

一、芯片引脚介绍

1.芯片引脚

2.引脚描述

二、系统结构图

三、功能描述

1.时钟功能

2.警报功能

3.高精度时间调整功能

4.晶振停振监测

5.周期中断

6.32kHz 时钟输出

四、寄存器的描述

五、程序代码

XJ8372.C

/*
 * XJ8372.c
 *
 *  Created on: 2024年8月8日
 *      Author: Administrator
 */

#include "softiic.h"
#include "XJ8372.h"
#include "usart.h"
#include <stdio.h>


//XJ8372的IIC读
uint8_t XJ8372ReadOneByte(uint8_t ReadAddr)
{
	  uint8_t temp=0;
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(0X64);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(ReadAddr);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(0X65);
	  bsp_analog_i2c_wait_ack();
	  temp= bsp_analog_i2c_read_byte();
	  bsp_analog_i2c_nack();
	  bsp_analog_i2c_stop();
   return temp;
}



//XJ8372的IIC写
void XJ8372WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite)
{
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(0x64);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(WriteAddr);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(DataToWrite);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_stop();
}


//XJ8372的IIC连续写
void XJ8372sequence_write(uint8_t WriteAddr,uint8_t* data,int length)
{
	bsp_analog_i2c_start();
	bsp_analog_i2c_send_byte(0X64);
	bsp_analog_i2c_wait_ack();
	bsp_analog_i2c_send_byte(WriteAddr);
	bsp_analog_i2c_wait_ack();
    for (int i = 0; i < length; i++)
    {
		bsp_analog_i2c_send_byte(*(data+i));
		bsp_analog_i2c_wait_ack();
    }
	bsp_analog_i2c_nack();
	bsp_analog_i2c_stop();
}


//时间初始化结构体
Clock_Typedef Clock_init={
  .SEC=0x50,
  .MIN=0x59,
  .HOUR=0x18,
  .WEEK=0x01,
  .DAY=0x01,
  .MONTH=0x01,
  .YEAR=0x24
};
/***
功能:设定XJ8372的时间
输入:Clock_init的地址
返回:无
*****/
void SET_XJ8372TIMER(Clock_Typedef* clock)
{
	XJ8372WriteOneByte(RS5C_REG_CTRL2,1<<5);//设置24小时
	XJ8372sequence_write(XJ8372_REG_SECS,(uint8_t*)clock ,7);
}



/***
功能:打印出XJ8372的时间
输入:无
返回:无
*****/
void printf_XJ8372TIMER(void)
{
	printf("北京时间  ");
	printf(" 20%x年 ",XJ8372ReadOneByte(XJ8372_REG_YEAR)& 0x7f);
	printf("%x月 ",XJ8372ReadOneByte(XJ8372_REG_MONTH));
	printf("%x日 ",XJ8372ReadOneByte(XJ8372_REG_DAY)& 0x7f);

	//printf(" 星期 %x ",XJ8372ReadOneByte(XJ8372_REG_WDAY)& 0x7f);

	switch(XJ8372ReadOneByte(XJ8372_REG_WDAY)& 0x7f)
			{
			case 1:printf(" 星期 一");break;
			case 2:printf(" 星期 二");break;
			case 3:printf(" 星期 三");break;
			case 4:printf(" 星期 四");break;
			case 5:printf(" 星期 五");break;
			case 6:printf(" 星期 六");break;
			case 7:printf(" 星期 日");break;
			default:printf("error");
			}

	printf("   %x:",XJ8372ReadOneByte(XJ8372_REG_HOURS)& 0x3f);
	printf(" %x:",XJ8372ReadOneByte(XJ8372_REG_MINS)& 0x7f);
	printf(" %x  \r\n",XJ8372ReadOneByte(XJ8372_REG_SECS)& 0x7f);

	HAL_Delay(1000);
}



/***
功能:校准时间
输入:可以通过输入不同参数,来调节精度
返回:无
*****/
void Time_aligned(uint8_t aligne)
{
	XJ8372WriteOneByte(RS5C372_REG_TRIM,aligne);
}


//设置闹钟A赋初值
Alarm_A_Typedef Alarm_A_init={
		.MIN_Alarm_A=0x00,
		.HOUR_Alarm_A=0x19,
		.WD_Alarm_A=0x7f,
};
void Alarm_A_Init(Alarm_A_Typedef*alarm)
{
	XJ8372sequence_write(RS5C_REG_ALARM_A_MIN,(uint8_t*)alarm ,3);
	XJ8372WriteOneByte(RS5C_REG_CTRL1,1<<7);
}



//设置闹钟B赋初值
Alarm_B_Typedef Alarm_B_init={
		.MIN_Alarm_B=0x00,
		.HOUR_Alarm_B=0x19,
		.WD_Alarm_B=0x7f,
};
void Alarm_B_Init(Alarm_B_Typedef*alarm)
{
	XJ8372sequence_write(RS5C_REG_ALARM_B_MIN,(uint8_t*)alarm ,3);
	XJ8372WriteOneByte(RS5C_REG_CTRL1,1<<6);
}


/***
功能:获取闹钟A的状态
输入:
返回:  1  闹钟匹配上了
	 0    闹钟没匹配上
*****/
uint8_t Alarm_A_flag (void)
{
	uint8_t Control2_data;
	uint8_t alarm_A_flag;
	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	Control2_data=Control2_data&0x02;
	alarm_A_flag=Control2_data>>1;
	return alarm_A_flag;
}



/***
功能:设置输出引脚为A或者B,设置输出频率为1HZ或者2HZ
输入:
	INTx :  INTA引脚   	  INTB引脚
    fre  : Pulse_Mode2Hz  Pulse_Mode1Hz
返回:无
*****/
void Set_Pulse_Mode(uint8_t fre,uint8_t INTx)
{
	uint8_t Control1_data;
	uint8_t Control2_data;

	Control1_data=XJ8372ReadOneByte(RS5C_REG_CTRL1);
	Control1_data=Control1_data&0xF8;

	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	Control2_data=Control2_data|0X08;

	if(INTx==INTA)
	{
		XJ8372WriteOneByte(RS5C_REG_CTRL1,(Control1_data|fre)&0XCF);//设置频率和输出额引脚为A
	}
	else
	{
		XJ8372WriteOneByte(RS5C_REG_CTRL2,Control2_data);
		XJ8372WriteOneByte(RS5C_REG_CTRL1,(Control1_data|fre)|0X20);//设置频率和输出额引脚为B
	}
}



/***
功能:设置输出引脚为A或者B,设置每秒、每分钟,每小时、每个月
输入:
	INTx :  INTA引脚
	       INTB引脚
    tim  : Every_second
    	   Every_minute,
	       Every_hour,
	       Every_month,
返回:无
*****/
void Set_Level_Mode(uint8_t tim,uint8_t INTx)
{
	uint8_t Control1_data;
	uint8_t Control2_data;

	Control1_data=XJ8372ReadOneByte(RS5C_REG_CTRL1);
	Control1_data=Control1_data&0xF8;

	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	Control2_data=Control2_data|0X08;

	if(INTx==INTA)
	{
		XJ8372WriteOneByte(RS5C_REG_CTRL1,(Control1_data|tim)&0XCF);//设置频率和输出额引脚为A
	}
	else
	{
		XJ8372WriteOneByte(RS5C_REG_CTRL2,Control2_data);
		XJ8372WriteOneByte(RS5C_REG_CTRL1,(Control1_data|tim)|0X20);//设置频率和输出额引脚为B
	}

}


/***
功能:由于Level_Mode会导致引脚输出低电平,这个函数可以清除并且恢复高电平
输入:
返回:无
*****/
void clear_Level_Mode (void)
{
	uint8_t Control2_data;
	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	Control2_data=Control2_data&0XFB;
	XJ8372WriteOneByte(RS5C_REG_CTRL2,Control2_data);
}



/***
功能:设置24小时制或者12小时制
输入:
返回:无
*****/
void Set_12or24Mode (void)
{
	uint8_t Control2_data;
	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	Control2_data=Control2_data|0X20;
	XJ8372WriteOneByte(RS5C_REG_CTRL2,Control2_data);
}


/***
功能:控制INTB是否输出32KHZ
输入:
	SET 	:  不输出
    RESET   : 输出
返回:无
*****/
void Output_32kHz (uint8_t CLEN)
{
	uint8_t Control2_data;
	Control2_data=XJ8372ReadOneByte(RS5C_REG_CTRL2);
	if(CLEN==1)
	{
		Control2_data=Control2_data|0X08;
	}
	else
	{
		Control2_data=Control2_data&0XF7;
	}
	XJ8372WriteOneByte(RS5C_REG_CTRL2,Control2_data);
}

XJ8372.H

/*
 * XJ7372.h
 *
 *  Created on: 2024年8月8日
 *      Author: Administrator
 */

#ifndef __XJ8372_H_
#define __XJ8372_H_


//设置时间结构体
typedef struct{
  uint8_t SEC;
  uint8_t MIN;
  uint8_t HOUR;
  uint8_t WEEK;
  uint8_t DAY;
  uint8_t MONTH;
  uint8_t YEAR;
}Clock_Typedef;

extern Clock_Typedef Clock_init;


//设置闹钟A的结构体
typedef struct{
  uint8_t MIN_Alarm_A;
  uint8_t HOUR_Alarm_A;
  uint8_t WD_Alarm_A;
}Alarm_A_Typedef;

//设置闹钟B的结构体
typedef struct{
  uint8_t MIN_Alarm_B;
  uint8_t HOUR_Alarm_B;
  uint8_t WD_Alarm_B;
}Alarm_B_Typedef;

extern Alarm_A_Typedef Alarm_A_init;
extern Alarm_B_Typedef Alarm_B_init;


enum XJ8372_Pulse_Mode
{
	Pulse_Mode2Hz=0x02,
	Pulse_Mode1Hz,
};

enum XJ8372_Level_Mode
{
	Every_second =0x04,
	Every_minute,
	Every_hour,
	Every_month,
};



#define XJ8372_REG_SECS		0X00
#define XJ8372_REG_MINS		0X10
#define XJ8372_REG_HOURS	0X20
#define XJ8372_REG_WDAY		0X30
#define XJ8372_REG_DAY		0X40
#define XJ8372_REG_MONTH	0X50
#define XJ8372_REG_YEAR		0X60
#define RS5C372_REG_TRIM	0X70
#define RS5C_REG_ALARM_A_MIN	0X80			/* or ALARM_W */
#define RS5C_REG_ALARM_A_HOURS	0X90
#define RS5C_REG_ALARM_A_WDAY	0XA0
#define RS5C_REG_ALARM_B_MIN	0XB0			/* or ALARM_W */
#define RS5C_REG_ALARM_B_HOURS	0XC0
#define RS5C_REG_ALARM_B_WDAY	0XD0
#define RS5C_REG_CTRL1		0XE0
#define RS5C_REG_CTRL2		0XF0

#define INTA 0
#define INTB 1

#define RESET 0
#define SET 1




void SET_XJ8372TIMER(Clock_Typedef* clock);
uint8_t XJ8372ReadOneByte(uint8_t ReadAddr);
void XJ8372WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite);
void printf_XJ8372TIMER(void);
void XJ8372sequence_write(uint8_t WriteAddr,uint8_t* data,int length);
void Alarm_A_Init(Alarm_A_Typedef*alarm);
void Set_Pulse_Mode(uint8_t fre,uint8_t INTx);
void Set_Level_Mode(uint8_t tim,uint8_t INTx);
void clear_Level_Mode (void);
void Set_12or24Mode (void);
void Output_32kHz (uint8_t  CLEN);
uint8_t Alarm_A_flag (void);
void Alarm_B_Init(Alarm_B_Typedef*alarm);



#endif

main.c

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  bsp_analog_i2c_init();
  HAL_TIM_Base_Start_IT(&htim2);

  SET_XJ8372TIMER(&Clock_init);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  printf_XJ8372TIMER();
	 // printf_XJ8372TIMER();

  }
  /* USER CODE END 3 */
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值