共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网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |