共2条
1/1 1 跳转至页
,VXWORKS,NUCLEUS,keil,for,arm,01a,ccd,13581980230, 44B0的RTC告警无效,请人指导!!

问
蹲在家里学ARM,写的44B0的RTC测试程序,那位朋友帮忙看一下,我本意用Test_rtc_AlARM(int h,int m,int s )实现设定当前时间后任意长时间(暂时在h时m分s秒)产生告警中断,但中断一直进不去。我试验时用的是当前时间两分钟后发生。
其实我一直对44b0的RTC的ALM充满了疑惑,到底什么是告警功能,告警中断发生条件,和实现功能的方法是什么。
我的理解是把它当成闹钟,实现方法是(ARM的相应中断都打开了)ALMEN使能,对应RTCALM都相应使能。设置相应告警时分秒寄存器。当RTC时钟运行到跟我们设定的告警时钟值相等瞬间发生一次告警中断,RTC时钟跟告警时钟比较时,只是按照RTCALM中设定的使能的年月日时分秒顺序比较,均想等时才发生,如果其中的RTCALM中的某位设为禁止,则不对此位作比即可。那位朋友指导一下,我的理解对不对啊。
#include "..\inc\44B.h"
#include "..\inc\44blab.h"
#include "..\inc\Option.h"
#include "..\inc\rtc.h"
#define BCD_change(t) (t>>4)*10+(t&0xf)
#define BCD_nchange(t) ((t/10)<<4)+(t%10)
volatile unsigned int sec_tick;
int year,month,day,weekday,hour,min,sec;
char *date[8] = {"","SUN","MON","TUE","WED","THU","FRI","SAT"};
int rtc_alm[3]={0,0,0};
/******************************************************************
【功能说明】时钟显示程序,利用滴答中断更新显示
******************************************************************/
void Display_Rtc(void)
{
Uart_Printf("This test should be excuted once RTC test(AlARM) for RTC initialization\n");
Uart_Printf("Please check the VDDRTC connector or connect the VDD to Bt1+ !!!\n");
Uart_Printf("Typing any key to exit!!!\n");
rtc_Init();
Read_Rtc();
}
void Read_Rtc(void)
{
pISR_TICK=(unsigned)Rtc_display;
rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
sec_tick=1;
rINTMSK=~(BIT_GLOBAL|BIT_TICK);
rTICINT = 127+(1<<7); //START
Uart_Getch();
rINTMSK |= (BIT_GLOBAL | BIT_TICK);
rRTCCON=0x0;
}
void __irq Rtc_display(void)
{
rI_ISPC=BIT_TICK;
if(rBCDYEAR == 0x99)
year = 0x1999;
else
year = 0x2000 + rBCDYEAR;
month=rBCDMON;
day=rBCDDAY;
weekday=rBCDDATE;
hour=rBCDHOUR;
min=rBCDMIN;
sec=rBCDSEC;
Uart_Printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4x,%2x,%2x,%s,%2x:%2x:%2x",year,month,day,date[weekday],hour,min,sec);
}
//******************************RTC******************************
void rtc_Init(void)
{
//RTCCON 3 2 1 0
// CLKRST CNTSEL CKLSEL RTCEN
rRTCCON = 0x01; // R/W 使能, 1/32768, Normal(merge), No reset
rBCDYEAR = TESTYEAR;
rBCDMON = TESTMONTH;
rBCDDAY = TESTDAY; // SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
rBCDDATE = TESTDATE;
rBCDHOUR = TESTHOUR;
rBCDMIN = TESTMIN;
rBCDSEC = TESTSEC;
rRTCCON = 0x0; // R/W 禁用, 1/32768, Normal(merge), No reset
}
/****************************************************************
【功能说明】时钟滴答测试程序
****************************************************************/
void Test_rtc_Tick(void)
{
Uart_Printf("[RTC Tick interrupt test for S3C44B0X]\n");
//Uart_Printf("Please check the VDDRTC connector or connect the VDD to Bt1+ !!!\n");
Uart_Printf("Typing any key to exit!!!\n");
pISR_TICK=(unsigned)Rtc_Tick; //设置滴答中断服务程序入口地址
sec_tick=1; //初始化滴答中断
rINTMSK=~(BIT_GLOBAL|BIT_TICK); //中断控制器中允许滴答中断
rRTCCON=0x0; //关闭R/W(为降低功耗), 1/32768, Normal(merge), No reset
rTICINT = 127+(1<<7); //启动滴答(又称时间片)中断
Uart_Getch(); //等待有任意字符输入当有输入时执行下面
rINTMSK |= (BIT_GLOBAL | BIT_TICK);//中断控制器中关闭禁用滴答中断
rRTCCON=0x0; //END
}
//****************************滴答中断服务程序*********************
void __irq Rtc_Tick(void)
{
rI_ISPC=BIT_TICK;
Uart_Printf("\b\b\b\b\b\b\b%03d sec",sec_tick++);
}
/*********************************************************************
【功能说明】RTCAlARM测试程序,目标是可设定任意长度时间后产生告警中断
*********************************************************************/
volatile int isRtcInt;
//
void __irq Rtc_AlARM(void)
{
rI_ISPC=BIT_RTC;
Beep(600);
//rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
Uart_Printf("RTC AlARM Interrupt O.K.\n");
isRtcInt=1;
}
int Test_rtc_AlARM(int h,int m,int s )
{
int *Palm;
int BCDALM[3];
BCDALM[2]=rBCDHOUR ;
BCDALM[1]=rBCDMIN ;
BCDALM[0]=rBCDSEC ;
Uart_Printf("\n\n\n[RTC AlARM Test for S3C44B0X]\n");
rtc_Init();
rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
rALMYEAR=rBCDYEAR ;
rALMMON =rBCDMON;
rALMDAY =rBCDDAY ;
//rALMHOUR =rBCDHOUR ;
// rALMMIN =rBCDMIN ;
/* if(rBCDSEC<0X30)
{
rALMSEC =0x30;}
else
{
rALMSEC =0x59;}*/
Uart_Printf("0x%x,0x%x,0x%x \n",BCDALM[2],BCDALM[1],BCDALM[0]);
Palm= BCD_Add(BCDALM,h,m,s);
rALMHOUR = Palm[2];
rALMMIN = Palm[1];
rALMSEC = Palm[0];
Uart_Printf("0x%x,0x%x,0x%x \n",Palm[2],Palm[1],Palm[0]);
isRtcInt=0;
pISR_RTC=(unsigned int)Rtc_AlARM;
rRTCALM=0x7e; //禁止秒AlARM中断发生,允许全局及其他中断的发生?
rINTMSK=~(BIT_GLOBAL|BIT_RTC);
while(isRtcInt==0); //程序就死在这里了,除RTCALM外RTC其他功能都正常
rINTMSK|=BIT_GLOBAL;
rRTCCON = 0x0;
return 1;
}
int * BCD_Add(int *BCD,int Hour,int Min,int Sec)
{
Sec += BCD_change(BCD[0]);
Min += BCD_change(BCD[1]);
Hour += BCD_change(BCD[2]);
if(Sec>=60)
{
Sec = Sec-60;
Min = Min+1;
}
if(Min>=60)
{
Min = Min-60;
Hour = Hour+1;
}
if(Hour>=24)
{
Uart_Printf("\n请注意你加的有点多了,已超过24小时,达到%d小时%d分钟%d秒了! \n",Hour,Min,Sec);
}
BCD[0] = BCD_nchange(Sec);
BCD[1] = BCD_nchange(Min);
BCD[2] = BCD_nchange(Hour);
//Uart_Printf("\n0x%x,0x%x,0x%x \n",BCD[2],BCD[1],BCD[0]);
return BCD;
}
。。。
void Main(void)
{...
Test_rtc_AlARM(0,2,0 );
...}
答 1: 请不要用他的内部时钟,有BUG!!
外加时钟IC吧!!目前这个BUG还没修改!!
答 2: 头晕 答 3: 自己顶一下,没人帮忙吗?
其实我一直对44b0的RTC的ALM充满了疑惑,到底什么是告警功能,告警中断发生条件,和实现功能的方法是什么。
我的理解是把它当成闹钟,实现方法是(ARM的相应中断都打开了)ALMEN使能,对应RTCALM都相应使能。设置相应告警时分秒寄存器。当RTC时钟运行到跟我们设定的告警时钟值相等瞬间发生一次告警中断,RTC时钟跟告警时钟比较时,只是按照RTCALM中设定的使能的年月日时分秒顺序比较,均想等时才发生,如果其中的RTCALM中的某位设为禁止,则不对此位作比即可。那位朋友指导一下,我的理解对不对啊。
#include "..\inc\44B.h"
#include "..\inc\44blab.h"
#include "..\inc\Option.h"
#include "..\inc\rtc.h"
#define BCD_change(t) (t>>4)*10+(t&0xf)
#define BCD_nchange(t) ((t/10)<<4)+(t%10)
volatile unsigned int sec_tick;
int year,month,day,weekday,hour,min,sec;
char *date[8] = {"","SUN","MON","TUE","WED","THU","FRI","SAT"};
int rtc_alm[3]={0,0,0};
/******************************************************************
【功能说明】时钟显示程序,利用滴答中断更新显示
******************************************************************/
void Display_Rtc(void)
{
Uart_Printf("This test should be excuted once RTC test(AlARM) for RTC initialization\n");
Uart_Printf("Please check the VDDRTC connector or connect the VDD to Bt1+ !!!\n");
Uart_Printf("Typing any key to exit!!!\n");
rtc_Init();
Read_Rtc();
}
void Read_Rtc(void)
{
pISR_TICK=(unsigned)Rtc_display;
rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
sec_tick=1;
rINTMSK=~(BIT_GLOBAL|BIT_TICK);
rTICINT = 127+(1<<7); //START
Uart_Getch();
rINTMSK |= (BIT_GLOBAL | BIT_TICK);
rRTCCON=0x0;
}
void __irq Rtc_display(void)
{
rI_ISPC=BIT_TICK;
if(rBCDYEAR == 0x99)
year = 0x1999;
else
year = 0x2000 + rBCDYEAR;
month=rBCDMON;
day=rBCDDAY;
weekday=rBCDDATE;
hour=rBCDHOUR;
min=rBCDMIN;
sec=rBCDSEC;
Uart_Printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4x,%2x,%2x,%s,%2x:%2x:%2x",year,month,day,date[weekday],hour,min,sec);
}
//******************************RTC******************************
void rtc_Init(void)
{
//RTCCON 3 2 1 0
// CLKRST CNTSEL CKLSEL RTCEN
rRTCCON = 0x01; // R/W 使能, 1/32768, Normal(merge), No reset
rBCDYEAR = TESTYEAR;
rBCDMON = TESTMONTH;
rBCDDAY = TESTDAY; // SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
rBCDDATE = TESTDATE;
rBCDHOUR = TESTHOUR;
rBCDMIN = TESTMIN;
rBCDSEC = TESTSEC;
rRTCCON = 0x0; // R/W 禁用, 1/32768, Normal(merge), No reset
}
/****************************************************************
【功能说明】时钟滴答测试程序
****************************************************************/
void Test_rtc_Tick(void)
{
Uart_Printf("[RTC Tick interrupt test for S3C44B0X]\n");
//Uart_Printf("Please check the VDDRTC connector or connect the VDD to Bt1+ !!!\n");
Uart_Printf("Typing any key to exit!!!\n");
pISR_TICK=(unsigned)Rtc_Tick; //设置滴答中断服务程序入口地址
sec_tick=1; //初始化滴答中断
rINTMSK=~(BIT_GLOBAL|BIT_TICK); //中断控制器中允许滴答中断
rRTCCON=0x0; //关闭R/W(为降低功耗), 1/32768, Normal(merge), No reset
rTICINT = 127+(1<<7); //启动滴答(又称时间片)中断
Uart_Getch(); //等待有任意字符输入当有输入时执行下面
rINTMSK |= (BIT_GLOBAL | BIT_TICK);//中断控制器中关闭禁用滴答中断
rRTCCON=0x0; //END
}
//****************************滴答中断服务程序*********************
void __irq Rtc_Tick(void)
{
rI_ISPC=BIT_TICK;
Uart_Printf("\b\b\b\b\b\b\b%03d sec",sec_tick++);
}
/*********************************************************************
【功能说明】RTCAlARM测试程序,目标是可设定任意长度时间后产生告警中断
*********************************************************************/
volatile int isRtcInt;
//
void __irq Rtc_AlARM(void)
{
rI_ISPC=BIT_RTC;
Beep(600);
//rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
Uart_Printf("RTC AlARM Interrupt O.K.\n");
isRtcInt=1;
}
int Test_rtc_AlARM(int h,int m,int s )
{
int *Palm;
int BCDALM[3];
BCDALM[2]=rBCDHOUR ;
BCDALM[1]=rBCDMIN ;
BCDALM[0]=rBCDSEC ;
Uart_Printf("\n\n\n[RTC AlARM Test for S3C44B0X]\n");
rtc_Init();
rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
rALMYEAR=rBCDYEAR ;
rALMMON =rBCDMON;
rALMDAY =rBCDDAY ;
//rALMHOUR =rBCDHOUR ;
// rALMMIN =rBCDMIN ;
/* if(rBCDSEC<0X30)
{
rALMSEC =0x30;}
else
{
rALMSEC =0x59;}*/
Uart_Printf("0x%x,0x%x,0x%x \n",BCDALM[2],BCDALM[1],BCDALM[0]);
Palm= BCD_Add(BCDALM,h,m,s);
rALMHOUR = Palm[2];
rALMMIN = Palm[1];
rALMSEC = Palm[0];
Uart_Printf("0x%x,0x%x,0x%x \n",Palm[2],Palm[1],Palm[0]);
isRtcInt=0;
pISR_RTC=(unsigned int)Rtc_AlARM;
rRTCALM=0x7e; //禁止秒AlARM中断发生,允许全局及其他中断的发生?
rINTMSK=~(BIT_GLOBAL|BIT_RTC);
while(isRtcInt==0); //程序就死在这里了,除RTCALM外RTC其他功能都正常
rINTMSK|=BIT_GLOBAL;
rRTCCON = 0x0;
return 1;
}
int * BCD_Add(int *BCD,int Hour,int Min,int Sec)
{
Sec += BCD_change(BCD[0]);
Min += BCD_change(BCD[1]);
Hour += BCD_change(BCD[2]);
if(Sec>=60)
{
Sec = Sec-60;
Min = Min+1;
}
if(Min>=60)
{
Min = Min-60;
Hour = Hour+1;
}
if(Hour>=24)
{
Uart_Printf("\n请注意你加的有点多了,已超过24小时,达到%d小时%d分钟%d秒了! \n",Hour,Min,Sec);
}
BCD[0] = BCD_nchange(Sec);
BCD[1] = BCD_nchange(Min);
BCD[2] = BCD_nchange(Hour);
//Uart_Printf("\n0x%x,0x%x,0x%x \n",BCD[2],BCD[1],BCD[0]);
return BCD;
}
。。。
void Main(void)
{...
Test_rtc_AlARM(0,2,0 );
...}
答 1: 请不要用他的内部时钟,有BUG!!
外加时钟IC吧!!目前这个BUG还没修改!!
答 2: 头晕 答 3: 自己顶一下,没人帮忙吗?
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
分享汽车通信和多媒体总线结构被打赏20分 | |
【我踩过的那些坑】结构堵孔导致的喇叭无声问题被打赏50分 | |
NUCLEO-U083RC学习历程38+串口通过队列的方式输出两个字符串被打赏20分 | |
【我踩过的那些坑】分享一下调试一款AD芯片的遇到的“坑”被打赏50分 | |
电流检测模块MAX4080S被打赏10分 | |
【我踩过的那些坑】calloc和malloc错误使用导致跑飞问题排查被打赏50分 | |
分享电控悬架的结构与工作原理(一)被打赏20分 | |
多组DCTODC电源方案被打赏50分 | |
【我踩过的那些坑】STM32cubeMX软件的使用过程中的“坑”被打赏50分 | |
新手必看!C语言精华知识:表驱动法被打赏50分 |