Mstar 平台RTC 时钟(RX8130CE)调试

很多嵌入式设备在使用过程中,会碰到未联网的状态,但是有需要保证时间的正常,或者定时开关机功能。这个时候就需要添加RTC 时钟模块。下面通过mstar 平台的rx8130ce 型号时钟调试为例,一起分享。

RTC HW 连接

在这里插入图片描述
从HW提供的原理图设计时,提供了两款RTC 时钟芯片,地址分别是0x64,0xD0。
在这里插入图片描述
从提供的PCB 板上,UT3 未上件。 我们进一步查询I2C 的连接走线。
在这里插入图片描述
分析完原理图,要确保硬件的一下几点正常:

  1. RTC 的power 连接正常,电池(待机/断电时供电)和主板(上电时)
  2. RTC 的I2C 和主芯片的连接正常;
  3. RTC 的I2C 地址 的确定;

I2C 地址配置

在这里插入图片描述
找到pin 脚定义,然后配置总线,设置delay 时间,接着在总线下面挂载设备。

//Bus Info Define
#define BOARD_I2C_SWBUS_NUM               3
#define BOARD_I2C_HWBUS_NUM               0
#define BOARD_I2C_DEVICE_NUM              6

static SWI2CBus_t BOARD_I2C_SWBUS[BOARD_I2C_SWBUS_NUM]=
{
    //Example for SW I2C => { 1, PAD_DDCR_CK, PAD_DDCR_DA, 60, }, //SW_I2C  /SCL_PAD /SDA_PAD /Delay
     // Bus-0
    {PAD_DDCR_CK, PAD_DDCR_DA, 100}, //IS_SW_I2C  /SCL_PAD /SDA_PAD /Delay
    // Bus-1
    {PAD_TGPIO0 , PAD_TGPIO1, 100},
    // Bus-2
    {PAD_GPIO19 , PAD_GPIO20,100},
    // Bus-3
    //{PAD_GPIO2  , PAD_GPIO3,100},
};

static HWI2CBus_t BOARD_I2C_HWBUS[BOARD_I2C_HWBUS_NUM];

//Device Info Define
static I2CDeviceInfo_s  Board_I2C_Dev[BOARD_I2C_DEVICE_NUM] =
{
    //Example => { TUNER1, 1, 0xC2 }, //gID(U32)  /i2c_bus(U8) /slave_id(U8)
    {TUNER1        , 1,  0xC0}, //gID(U32)  /i2c_bus(U8) /slave_id(U8)
    // AD82088
    {AMP_SLAVER_ID , 1,  0x62},  // 0x31 << 1 --> 0x62
    // RTC
    {RTC_I2C_ID    , 1,  0x64},
    // temp R/W
    {TMP102_CHIP_R  , 1, 0x90},
    {TMP102_CHIP_W  , 1, 0x91},
    // TCA9535
    {TCA9539_I2C_ID , 2, 0xE8},  // 0x74 << 1  = 0xE8
};

{RTC_I2C_ID , 1, 0x64}, 就是挂载第二组总线上的RTC,地址为0x64.

I2C 的读写

在这里插入图片描述
注意上面的RTC8130_SECADDR 是 RTC 的寄存器地址,跟时间日期相关的几个寄存器地址如下:

#define RTC8130_SLAVEADDR   0x64
#define RTC8130_SECADDR     0x10
#define RTC8130_MINADDR     0x11
#define RTC8130_HOURADDR    0x12
#define RTC8130_WEEKADDR    0x13
#define RTC8130_DATEADDR    0x14
#define RTC8130_MONTHADDR   0x15
#define RTC8130_YEARADDR    0x16

这些地址在协议里面会有说明。

RTC 时间数据格式

在这里插入图片描述
分析datasheet 中RTC 时间格式,其中秒,分,时,天,月,年 都是BCD 码格式存储。周 的存储方法不一样,按照所在的bit 位标记为第几周,一个月最多跨6 周。

  1. 设置时间
static MAPI_U8 HEX2BCD(MAPI_U8 cHEXData)
{
    MAPI_U8 cTemp;
    cTemp = ((cHEXData / 10) << 4) | (cHEXData % 10);
    return cTemp;
}

先将16进制的数据转换成BCD 码,然后设置到对应寄存器中。

	SecAdd = RTC8130_SECADDR;  // 0x10
	TimeTable[RTC_SECOND] = HEX2BCD(RTC8130_TimeData.param[RTC_SECOND]) & 0x7F;
	TimeTable[RTC_MINUTE] = HEX2BCD(RTC8130_TimeData.param[RTC_MINUTE]) & 0x7F;
	TimeTable[RTC_HOUR]   = HEX2BCD(RTC8130_TimeData.param[RTC_HOUR])   & 0x3F;
	TimeTable[RTC_WEEK]   = RTC8130_TimeData.param[RTC_WEEK] & 0x7F ;
	TimeTable[RTC_DATE]   = HEX2BCD(RTC8130_TimeData.param[RTC_DATE])   & 0x3F;
	TimeTable[RTC_MONTH]  = HEX2BCD(RTC8130_TimeData.param[RTC_MONTH])  & 0x1F;
	TimeTable[RTC_YEAR]   = HEX2BCD(RTC8130_TimeData.param[RTC_YEAR])   & 0xFF;

	ret = iptr->WriteBytes(1,&SecAdd,7,&TimeTable[RTC_SECOND]);
  1. 获取时间
	mapi_i2c *iptr  = NULL;
	MAPI_U8  regAddr = RTC8130_SECADDR;

	RX8130_PRINTF(printf("[%s][%d] RX81390 Enter .\n",__FUNCTION__,__LINE__));

	iptr = mapi_i2c::GetI2C_Dev(RTC_I2C_ID);
	if(iptr == NULL)
    {
        printf("[%s][%d] RX81390 Invalid I2c rtc addr .\n", __FUNCTION__,__LINE__);
        return MAPI_FALSE;
    }

    ret = iptr->ReadBytes(1, &regAddr, 7, TimeTable);
    if(MAPI_FALSE == ret)
    {
    	printf("[%s][%d] RX81390 Read ret = %d\n", __FUNCTION__,__LINE__,ret);
    	return MAPI_FALSE;
    }

	RTC8130_TimeData.param[RTC_SECOND] = BCD2HEX(TimeTable[0]);
	RTC8130_TimeData.param[RTC_MINUTE] = BCD2HEX(TimeTable[1]);
	RTC8130_TimeData.param[RTC_HOUR]   = BCD2HEX(TimeTable[2]);
	RTC8130_TimeData.param[RTC_WEEK]   = TimeTable[3] & 0x7F;
	RTC8130_TimeData.param[RTC_DATE]   = BCD2HEX(TimeTable[4]);
	RTC8130_TimeData.param[RTC_MONTH]  = BCD2HEX(TimeTable[5]);
	RTC8130_TimeData.param[RTC_YEAR]   = BCD2HEX(TimeTable[6]);

将读取到的BCD码转换成16进制数据给上层使用。

static MAPI_U8 BCD2HEX(MAPI_U8 cBCDData)
{
    MAPI_U8 cTemp;
    cTemp = ((cBCDData >> 4) * 10) + ( cBCDData & 0x0F);
    return cTemp;
}

另外要主要周,年的范围。例如, 年的最大值 165
(80+40+20+10+8+4+2+1),那么实际使用的需要补齐。
2019 年则传入RTC时是19,1970 传入应该是70 。一般定时也不多超过100年,所以还是能够满足实际要求的。

RTC 初始配置

在这里插入图片描述
datasheet 显示 Extension Register,Flag Register,Control Register0,Control Register1 需要设置默认状态。

RX8130_CONFIG g_RX8130_CONFIGData[] =
{
    {0x30,0x80},//enable DTE
    {0x1c,0x04},
    {0x1d,0x06},
    {0x1e,0x00},
    {0x1f,0x00},
};
	iptr = mapi_i2c::GetI2C_Dev(RTC_I2C_ID);
	if(iptr == NULL)
    {
        printf("[%s][%d] RX81390 Invalid I2c mcu addr .\n",__FUNCTION__,__LINE__);
        return ret;
    }
	
	for(i=0; i<sizeof(g_RX8130_CONFIGData)/sizeof(g_RX8130_CONFIGData[0]); i++)
	{
		unAddr = g_RX8130_CONFIGData[i].RX8130_Address;
		unData = g_RX8130_CONFIGData[i].RX8130_InitData;
		ret = iptr->WriteBytes(1, &unAddr, 1, &unData);
	    RX8130_PRINTF(printf("[%s][%d] RX8130 Write [0x%02x : 0x%02X] ret = %d\n",__FUNCTION__,__LINE__,unAddr,unData,ret));
	}
	return ret;

按照对应bit 位将初始值设入寄存器即可完成初始化,后面就可以正常设置,获取时间。

驱动源码

https://download.csdn.net/download/kehyuanyu/11987005

发布了101 篇原创文章 · 获赞 19 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/kehyuanyu/article/details/103165814
今日推荐