初级会员

- 积分
- 179
- 金钱
- 179
- 注册时间
- 2019-5-12
- 在线时间
- 19 小时
|
5金钱
最近在学习STM32,想利用RTC每秒和定时(比如40秒)产生一个中断然后执行一些任务。RTC是用的原子的RTC例程,我已经试过,可以每秒产生中断,但是闹钟中断发生不了。翻了很多程序参考,最后在原子论坛交到一片资料,按照资料写成一下代码,还是不行,希望论坛朋友赐教下,万分感激!
static void RTC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1位,从优先级3位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //先占优先级0位,从优先级4位
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道中断
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; //闹钟中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //比RTC全局中断的优先级高
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化时钟失败,晶振有问题
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
//RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode();/// 允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
RTC_SetCounter(0);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_SetAlarm(40); //设定每40秒产生一次闹钟中断
RTC_WaitForLastTask();
RTC_Set(2009,12,2,10,0,55); //设置时间
RTC_WaitForLastTask();
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0X5050); //向指定的后备寄存器中写入用户程序数据
}
else//系统继续计时
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
RTC_NVIC_Config();//RCT中断分组设置
RTC_Get();//更新时间
return 0; //ok
}
void RTCAlarm_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
{
RtcAlmFlag = 1;
}
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_WaitForLastTask();
RTC_ClearITPendingBit(RTC_IT_ALR|RTC_IT_OW);
RTC_WaitForLastTask();
RTC_SetAlarm(5+RTC_GetCounter()); //配置下次闹钟为40s后
RTC_WaitForLastTask();
}
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC)!=RESET) //是否秒中断发生
{
RTC_Get();//更新时间
if(!stopcopytimeflag)
CopyRtcToSysTime();
}
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清除秒中断标志位和溢出位
RTC_WaitForLastTask();
}
|
最佳答案
查看完整内容[请看2#楼]
【mini_RTC闹钟实验+战舰RTC闹钟实验】
http://www.openedv.com/forum.php?mod=viewthread&tid=275322
|