RA8900CE计时芯片介绍及开发方案

计时芯片

就是一个需要连接32.768k晶振的RTC芯片

规格书阅读

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

引脚表

封装是这样的,一共10个引脚。

基本上一看这个引脚表就知道大概。

T1和T2是工厂测试的,不用管。

SCL和SDA是IIC通讯用的。

FOUT和FOE就是链接晶振的。

INT是中断输出,闹钟、唤醒啥的都靠它。

其他的都是电源和地了。

模块框图

这个也简单,就是个S-35390A的简化版,有需要的朋友可以看我另一篇文章。S-35390A计时芯片介绍及开发方案_s35390-CSDN博客

软件设计

寄存器定义

里面有好几组寄存器,可以按照命令来读取。

基础信息寄存器

// RX-8900 Basic Time and Calendar Register definitions
#define RA8900_BTC_SEC					0x00
#define RA8900_BTC_MIN					0x01
#define RA8900_BTC_HOUR					0x02
#define RA8900_BTC_WEEK					0x03
#define RA8900_BTC_DAY					0x04
#define RA8900_BTC_MONTH				0x05
#define RA8900_BTC_YEAR					0x06
#define RA8900_BTC_RAM					0x07
#define RA8900_BTC_ALARM_MIN			0x08
#define RA8900_BTC_ALARM_HOUR			0x09
#define RA8900_BTC_ALARM_WEEK_OR_DAY	0x0A
#define RA8900_BTC_TIMER_CNT_0			0x0B
#define RA8900_BTC_TIMER_CNT_1			0x0C
#define RA8900_BTC_EXT					0x0D
#define RA8900_BTC_FLAG					0x0E
#define RA8900_BTC_CTRL					0x0F

扩展寄存器1

// RX-8900 Extension Register 1 definitions
#define RA8900_EXT_SEC					0x10
#define RA8900_EXT_MIN					0x11
#define RA8900_EXT_HOUR					0x12
#define RA8900_EXT_WEEK					0x13
#define RA8900_EXT_DAY					0x14
#define RA8900_EXT_MONTH				0x15
#define RA8900_EXT_YEAR					0x16
#define RA8900_EXT_TEMP					0x17
#define RA8900_EXT_BACKUP				0x18#define RA8900_EXT_TIMER_CNT_0			0x1B
#define RA8900_EXT_TIMER_CNT_1			0x1C
#define RA8900_EXT_EXT					0x1D
#define RA8900_EXT_FLAG					0x1E
#define RA8900_EXT_CTRL					0x1F#define RA8900_EXT_0X30   			    0x30
#define RA8900_EXT_0X32   			    0x32
#define RA8900_EXT_0X40   			    0x40
#define RA8900_EXT_0X5A					0x5a
#define RA8900_EXT_0X5C					0x5c

扩展寄存器

// Flag RA8900_BTC_EXT Register bit positions
#define RA8900_BTC_EXT_TSEL0		(1 << 0)
#define RA8900_BTC_EXT_TSEL1		(1 << 1)
#define RA8900_BTC_EXT_FSEL0		(1 << 2)
#define RA8900_BTC_EXT_FSEL1		(1 << 3)
#define RA8900_BTC_EXT_TE 			(1 << 4)
#define RA8900_BTC_EXT_USEL			(1 << 5)
#define RA8900_BTC_EXT_WADA			(1 << 6)
#define RA8900_BTC_EXT_TEST			(1 << 7)

标志位寄存器

#define RA8900_BTC_FLAG_VDET 		(1 << 0)
#define RA8900_BTC_FLAG_VLF 		(1 << 1)
#define RA8900_BTC_FLAG_AF 			(1 << 3)
#define RA8900_BTC_FLAG_TF 			(1 << 4)
#define RA8900_BTC_FLAG_UF 			(1 << 5)

控制寄存器

#define RA8900_BTC_CTRL_RESET 		(1 << 0)
#define RA8900_BTC_CTRL_AIE 		(1 << 3)
#define RA8900_BTC_CTRL_TIE 		(1 << 4)
#define RA8900_BTC_CTRL_UIE 		(1 << 5)
#define RA8900_BTC_CTRL_CSEL0 		(1 << 6)
#define RA8900_BTC_CTRL_CSEL1		(1 << 7)

初始化

就是调用两个接口,用配置结构体初始化,接个状态回来。由于我这里用的是软件IIC,用到硬件IIC的朋友请自行初始化,调用下LPI2C_DRV_MasterInit函数。

RA8900_Init(&rtc_Config,&g_RA8900State);

结构体长这样,按照内容配置就行,不会的可以照抄。

rtc_user_config rtc_Config=
{ONCE_PER_SECONDS,//按照秒或者分钟计时FREQ_32dot768KHZ,//晶振选择CLOCK_EVERY_SECOND,//时钟频率EXECUTE_PER_2_SEC,//时钟补偿false,//是否使能修正周期false,//是否使能时钟更新false,//是否使能闹钟WEEK_ALARM,//闹钟按照天还是周/*year,month,day,hour,min,second,week*///默认时钟{ 18, 1,  1  ,0  , 0,  0,  1 },/*min ,hour ,week, day ,AF ,enabled,wada,pending*///默认闹钟{ 0,  0,   1    ,1   ,0,   0,       0,   0  }
};

代码如下

rtc_state g_RA8900State;
rtc_state *g_RA8900StatePtr=&g_RA8900State;
void RA8900_Init(rtc_user_config *userConfigPtr, rtc_state *rtc)
{uint8_t ctrl[3]={0x02,0x00,0x61};/*the default data*/g_RA8900StatePtr = rtc;ctrl[0]=(userConfigPtr->WADA<<6)|(ctrl[0]&(~RA8900_BTC_EXT_WADA));ctrl[0]=(userConfigPtr->updateTime <<5)|(ctrl[0]&(~RA8900_BTC_EXT_USEL));ctrl[0]=(userConfigPtr->outputFreq<<2)|(ctrl[0]&(~(RA8900_BTC_EXT_FSEL0|RA8900_BTC_EXT_FSEL1)));ctrl[0]=(userConfigPtr->timerClock)|(ctrl[0]&(~(RA8900_BTC_EXT_TSEL0|RA8900_BTC_EXT_TSEL1)));/*config the ext reg must set TE \TEST to 1,RESET to 1 (when set clock need to stop clock) *//*set TE \TEST to 1,RESET to 1,anothers are the config */RA8900_WriteRegs(RA8900_BTC_EXT,3,ctrl);RA8900_ReadRegs(RA8900_BTC_EXT,3,ctrl);RA8900_SetTime(&(userConfigPtr->defaulRtcTime));/*check the time fixedCycle function*/if(userConfigPtr->isFixedCycleEnable){/*if enable ,set the TE bit in EXT Reg*/ctrl[0]=(userConfigPtr->isFixedCycleEnable<<4)|(ctrl[0]&(~RA8900_BTC_EXT_TE));}/*if not enable,dont't need to change, it is 0 alreadly*//*set the function interrupt*/ctrl[2]=(userConfigPtr->isAlarmEnable<<3)|(ctrl[2]&(~RA8900_BTC_CTRL_AIE));ctrl[2]=(userConfigPtr->isFixedCycleEnable<<4)|(ctrl[2]&(~RA8900_BTC_CTRL_TIE));ctrl[2]=(1<<5)|(ctrl[2]&(~RA8900_BTC_CTRL_UIE));/*set the Temperature compensation */ctrl[2]=(userConfigPtr->temperCompensation<<6)|(ctrl[2]&(~(RA8900_BTC_CTRL_CSEL0|RA8900_BTC_CTRL_CSEL1)));/*reset the device*/ctrl[2]=0;RA8900_WriteRegs(RA8900_BTC_EXT,3,ctrl);g_RA8900StatePtr->extReg=ctrl[0];g_RA8900StatePtr->ctrlreg=ctrl[2];g_RA8900StatePtr->flagReg=ctrl[1];
}

读取接口

互斥锁的作用就是防止同时读和写。

static bool RA8900_ReadRegs(uint8_t regIdx, uint8_t length,uint8_t *values)
{bool ret = false;uint8_t Try = 3;if( xSemaphore_i2c != NULL )//互斥锁{if( xSemaphoreTake( xSemaphore_i2c, ( TickType_t ) 50 ) == pdTRUE ){while((Try--)&&(ret != true))  // allow setting 3 times{ret=I2C_read_bytes(RA8900_ADDRESS,regIdx,RTC_ADDR_BYTES,length,values);}xSemaphoreGive( xSemaphore_i2c);}}return	ret;
}

写入接口

因为要把命令先写进去,所以这里开了个buffer把命令和数据拼起来再发出去。地址默认为0x32

bool RA8900_WriteRegs(uint8_t regIdx,uint8_t length, uint8_t *values)
{bool ret = false;uint8_t Try = 3;uint8_t masterbuffer[32]={0};masterbuffer[0]=regIdx;memcpy(&masterbuffer[1],values,length);if( xSemaphore_i2c != NULL ){if( xSemaphoreTake( xSemaphore_i2c, ( TickType_t ) 50 ) == pdTRUE ){while((Try--)&&(ret != true))// allow setting 3 times{ret = I2C_write_bytes(RA8900_ADDRESS,length+ 1,masterbuffer);}xSemaphoreGive( xSemaphore_i2c);}}return	ret;
}

获取时间

time就是个结构体,里面有的东西下面都能看到了。将时间信息获取到regdate里面之后按照字节来转换BCD码。

uint8_t RA8900_GetTime(rtc_time *time)
{uint8_t regdate[16]={0,0,0,0,0,0,0};uint8_t err = 0;err = RA8900_ReadRegs(RA8900_BTC_SEC,7,regdate);time->second  = RA8900_Bcd2Dec(regdate[0] & 0x7f);time->minute  = RA8900_Bcd2Dec(regdate[1] & 0x7f);time->hour = RA8900_Bcd2Dec(regdate[2] & 0x3f);time->week = RA8900_GetWeekDay(regdate[3] & 0x7f);time->day = RA8900_Bcd2Dec(regdate[4] & 0x3f);time->month  = RA8900_Bcd2Dec(regdate[5] & 0x1f)-1;time->year = RA8900_Bcd2Dec(regdate[6])+2000;if (err==false){return 0;}return 1;
}

设置当前时间

按照位置去写入就行。

uint8_t  RA8900_SetTime(rtc_time *time)
{uint8_t date[7];int ret = 0;date[0]   = RA8900_Dec2Bcd(time->second);date[1]   = RA8900_Dec2Bcd(time->minute);date[2]  = RA8900_Dec2Bcd(time->hour);date[3]  = 1 << (time->week);date[4]   = RA8900_Dec2Bcd(time->day);date[5] = RA8900_Dec2Bcd(time->month+1);date[6]  = RA8900_Dec2Bcd(time->year % 100);ret =  RA8900_WriteRegs(RA8900_BTC_SEC, 7, date);return ret;
}

十进制转换BCD码

这种基本都是标准的

uint8_t RA8900_Dec2Bcd(uint8_t binData)
{uint8_t ret;ret = binData/10;//十位binData %= 10; //个位ret <<= 4; ret += binData;return ret;
}

BCD码转换为十进制

uint8_t RA8900_Bcd2Dec(uint8_t bcdData)
{uint8_t ret;ret = bcdData&0x0f;//个位。bcdData >>= 4;bcdData &= 0x0f;bcdData *= 10;//十位ret += bcdData;//相加return ret;
}

获取闹钟时间

uint8_t RA8900_GetAlarm(rtc_alarm *alarmTime)
{uint8_t alarmvals[3];//分,时,天uint8_t ctrl[3];//标志位int err;//获取闹钟时间,分err = RA8900_ReadRegs(RA8900_BTC_ALARM_MIN, 3, alarmvals);if (!err){return err;}//获取标志位:extension, flag, control valueserr = RA8900_ReadRegs(RA8900_BTC_EXT, 3, ctrl);if (!err){return err;}//将获取到的闹钟信息转换为十进制alarmTime->minute = RA8900_Bcd2Dec(alarmvals[0] & 0x7f);alarmTime->hour = RA8900_Bcd2Dec(alarmvals[1] & 0x3f);if (ctrl[0] & RA8900_BTC_EXT_WADA )//闹钟为每天{alarmTime->week = 0xff;alarmTime->day = RA8900_Bcd2Dec(alarmvals[2] & 0x3f);}else//闹钟为每周{ alarmTime->week = RA8900_GetWeekDay( alarmvals[2] & 0x7f );alarmTime->day = 0xff;alarmTime->WADA=0;}//检查闹钟中断是否使能alarmTime->enabled = !!(ctrl[2] & RA8900_BTC_CTRL_AIE);//检查闹钟是否已经触发,就是是否响了alarmTime->pending = (ctrl[1] & RA8900_BTC_FLAG_AF) && alarmTime->enabled;return err;
}

设置闹钟时间

可以是日闹钟,可以是周闹钟。

int RA8900_SetAlarmClock(rtc_alarm *alarmClockTime)
{uint8_t alarmvals[3];//分, 时, 天uint8_t ctrl[3];//控制信息int err;alarmvals[0] = RA8900_Dec2Bcd(alarmClockTime->minute);alarmvals[1] = RA8900_Dec2Bcd(alarmClockTime->hour);//获取控制信息RA8900_ReadRegs(RA8900_BTC_EXT, 3, ctrl);if(alarmClockTime->WADA){alarmvals[2] = RA8900_Dec2Bcd(alarmClockTime->day);ctrl[0] |= RA8900_BTC_EXT_WADA;}else{/*  bit:  7   6    5    4     3    2     1    0    *//* week:  0   Sat  Fri  Thur  Wed  Tue   Mon  Sun  */alarmvals[2] = alarmClockTime->week;ctrl[0] &= ~(RA8900_BTC_EXT_WADA);}RA8900_WriteRegs( RA8900_BTC_EXT, 1, &ctrl[0]);ctrl[2]= RA8900_BTC_CTRL_AIE|ctrl[2];ctrl[2] &= ~(RA8900_BTC_CTRL_UIE | RA8900_BTC_CTRL_TIE);RA8900_WriteRegs(RA8900_BTC_CTRL, 1, &ctrl[2]);RA8900_WriteRegs(RA8900_BTC_ALARM_MIN, 3, alarmvals);ctrl[1] &= ~RA8900_BTC_FLAG_AF;err = RA8900_WriteRegs(RA8900_BTC_FLAG, 1 ,&ctrl[1]);return err;
}

停止闹钟

int RA8900_StopAlarm(void)
{uint8_t ctrl[1];//控制位 ext, flag registersint err;RA8900_ReadRegs(RA8900_BTC_CTRL, 1, ctrl);ctrl[0] &= ~RA8900_BTC_CTRL_AIE;err = RA8900_WriteRegs(RA8900_BTC_CTRL, 1, ctrl);return err;
}

清除所有标志位

void  RA8900_ClearFlag(uint8_t flag)
{uint8_t currentFlag;RA8900_ReadRegs(RA8900_BTC_FLAG,1,&currentFlag);currentFlag=currentFlag & (~flag);RA8900_WriteRegs(RA8900_BTC_FLAG,1,&currentFlag);
}

转换为周几

长度7位,从低到高哪位为1就是周几。

static uint_8 RA8900_GetWeekDay(uint8_t regWeekDay )
{uint_8 index, timeWeekDay;for ( index=0; index < 7; index++ ){if ( regWeekDay & 1 ){timeWeekDay = index;break;}regWeekDay >>= 1;}return 	timeWeekDay;
}

获取温度

只是个功能,没啥用,将获取到的数值按公式算就行。

#define RA8900_EXT_TEMP					0x17uint8_t RA8900_GetTemp(void)
{uint8_t tempvalue = 0;float   RtcTemp = 0.0;RA8900_ReadRegs(RA8900_EXT_TEMP,1,&tempvalue);RtcTemp = (tempvalue*2 - 187.19)/3.218;tempvalue = (uint8_t)RtcTemp;return tempvalue;
}

保持增强功能

他有个增强功能,要在初始化的时候做这几件事,50ms为周期调用下面这个初始化接口。其实就是写入几个命令。

#define RA8900_EXT_0X30   			    0x30
#define RA8900_EXT_0X32   			    0x32
#define RA8900_EXT_0X40   			    0x40
#define RA8900_EXT_0X5A					0x5a
#define RA8900_EXT_0X5C					0x5cuint8_t RA8900CE_Inhance(void)
{bool err = false;uint8_t ctrl = 0;static uint8_t s_Step = FSM_STEP_01;//默认为第一步switch(s_Step){case FSM_STEP_01://第一步{ctrl = 0xd1;err = RA8900_WriteRegs(RA8900_EXT_0X30,1,&ctrl);if (!err){return err;}ctrl = 0x00;err = RA8900_WriteRegs(RA8900_EXT_0X40,1,&ctrl);if (!err){return err;}ctrl = 0x81;err = RA8900_WriteRegs(RA8900_EXT_0X32,1,&ctrl);if (!err){return err;}s_Step = FSM_STEP_02;//跳到第二步 }break;case FSM_STEP_02://第二步{ctrl = 0x80;err = RA8900_WriteRegs(RA8900_EXT_0X32,1,&ctrl);if (!err){return err;}s_Step = FSM_STEP_03;//跳到第三步 break;}case FSM_STEP_03://第三步{ctrl = 0x04;err = RA8900_WriteRegs( RA8900_EXT_0X32, 1, &ctrl);if (!err){return err;}s_Step = FSM_STEP_04;//跳到第四步 break;}case FSM_STEP_04://第四步{ctrl = 0x00;err = RA8900_ReadRegs(RA8900_EXT_0X5C,1,&ctrl);if (!err){return err;}ctrl &= ~0x0f;ctrl |= 0x0c;err = RA8900_WriteRegs(RA8900_EXT_0X5C,1,&ctrl);if (!err){return err;}err = RA8900_ReadRegs(RA8900_EXT_0X5A,1,&ctrl);if (!err){return err;}ctrl &= ~0xe0;ctrl |= 0xe0;err = RA8900_WriteRegs( RA8900_EXT_0X5A, 1, &ctrl);if (!err){return err;}ctrl = 0x00;err = RA8900_WriteRegs(RA8900_EXT_0X30,1, &ctrl);if (!err){return err;}s_Step = FSM_STEP_END;//结束break;}default:s_Step = FSM_STEP_END;break;}return err;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GD32F470_GP2Y0A02YK0F 红外激光测距传感器 避障测距20-150cm模块移植

2.4 红外测距传感器 GP2Y0A02YKOF是夏普的一款距离测量传感器模块。它由PSD(position sensitive detector)和IRED(infrared emitting diode)以及信号处理电路三部分组成。由于采用了三角测量方法,被测物体的材质、环境温度以及测量时间都不会影响传感器的测量精度。传感器输出电…

线段树和树状数组

实战演练 1.【模板】树状数【模板】树状数组1 输入&#xff1a; 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 注意&#xff1a;只修改一个数&#xff08;单点修改&#xff09;&#xff0c;却要输出一个区间的值&#xff08;区间查询&#xff09;&#xff01;&#xff…

FreeRTOS学习 -- 再识

工作中一直使用FreeRTOS进行着开发&#xff0c;但是没有进行过系统的总结过。现在将快速使用几天时间将FreeRTOS相关知识点加以总结。 官网&#xff1a; https://www.freertos.org/zh-cn-cmn-s/ 参看资料&#xff1a; 正点原子 STM32F1 FreeRTOS开发手册_V1.2.pdf The FreeRTOS…

LangChain入门:15.Sequential Chain:顺序链的使用

Sequential Chain是LangChain库中的一个强大工具&#xff0c;它允许我们将多个LLMChain按照特定的顺序连接起来&#xff0c;形成一个处理流程。这种链式结构使得我们可以将一个大任务分解为几个小任务&#xff0c;并依次执行&#xff0c;每个任务的输出成为下一个任务的输入。 …

linux:du和df区别

文章目录 1. 概述2. du 命令2. df 命令3. 区别总结 1. 概述 du 和 df 都是 Linux 系统中用于查看磁盘空间使用情况的命令&#xff0c;但它们的功能和用法有所不同。 2. du 命令 du 是 “disk usage” 的缩写&#xff0c;用于显示文件或目录的磁盘使用情况。du 命令用于查看指…

如何用matplotlib画图像的时候使用中文标签名

Matplotlib 中文显示不是特别友好&#xff0c;要在 Matplotlib 中显示中文&#xff0c;我们可以通过两个方法&#xff1a; 下载使用支持中文的字体库。设置 Matplotlib 的字体参数。 下载使用支持中文的字体库: Matplotlib 默认情况不支持中文&#xff0c;我们可以使用以下简…

Disk Drill Enterprise for Mac v5.5.1515数据恢复软件中文版

Disk Drill 是 Mac 操作系统固有的Mac数据恢复软件&#xff1a;使用 Recovery Vault 轻松保护文件免遭意外删除&#xff0c;并从 Mac 磁盘恢复丢失的数据。支持大多数存储设备&#xff0c;文件类型和文件系统。 软件下载&#xff1a;Disk Drill Enterprise for Mac v5.5.1515激…

博士推荐 | 拥有超过10年的数据解决方案经验,数据驱动的决策者

编辑 / 木子 审核 / 朝阳 伟骅英才 伟骅英才致力于以大数据、区块链、AI人工智能等前沿技术打造开放的人力资本生态&#xff0c;用科技解决职业领域问题&#xff0c;提升行业数字化服务水平&#xff0c;提供创新型的产业与人才一体化服务的人力资源解决方案和示范平台&#x…

jupyter python paramiko 网络系统运维

概述 通过使用jupyter进行网络运维的相关测试 设备为H3C 联通性测试 import paramiko import time import getpass import re import os import datetimeusername "*****" password "*****" ip "10.32.**.**"ssh_client paramiko.SSHCli…

【明道云】设置默认值时,发现单选项目无法与文本项目比较

【背景】 新建表单&#xff0c;其中字段B的默认值通过使用字段A在另一张表单B中搜索获得。 字段A在当前表的填写形式是下拉框&#xff0c;而用于比较的表单B的相应字段A1则是文本。因此在建立条件时发现由于组件类型不同&#xff0c;无法选到字段A作为比较条件。 【解决办法】…

基于Difussion图像、视频生成综述

2024年大年初七&#xff08;02.16&#xff09;OpenAI 发布视频生成模型 Sora 在各大平台转疯了&#xff0c;和2022年发布ChatGPT3.5时一样的疯狂。在开工第一天&#xff0c;我就去官网上看了 Sora 的技术报告&#xff0c;遗憾的是&#xff0c;在这份技术报告中只披露了一些模型…

rsync+inotify的实时同步

目录 一、inotify 二、rsyncinotify实时同步搭建 1. 实验环境配置 2. 配置 服务端192.168.91.103 1. 修改rsync源服务器配置文件 3. 配置 客户端192.168.91.102 1. 创建文件夹 ​编辑 2. 调整 inotify 内核参数 3. 安装inotify-tools 4. inotify对文件进行监控 5. 测…