uniqueeefocus41 发表于 2013-2-27 13:56:31

求助!!STM32L151中的RTC唤醒(wake up)中断问题

 各位大大,我最近在做STM32L151时出现了一个问题,就是RTC唤醒(wake up)中断不会中断啊,不知道为什么。下面是我的部分程序:

  void RTC_Configuration(void)
{
/* Enable PWR and BKP clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);                   
  /* Allow access to BKP Domain */
  PWR_RTCAccessCmd(ENABLE);                                        
                                                         
  
   /* Enable the LSE OSC */
  RCC_LSEConfig(RCC_LSE_ON);

  /* Wait till LSE is ready */  
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {
  }

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable the RTC Clock */
  RCC_RTCCLKCmd(ENABLE);
  /* Wait for RTC APB registers synchronisation */
  RTC_WaitForSynchro();
  
  RTC_InitStructure.RTC_AsynchPrediv = 0x06;
  RTC_InitStructure.RTC_SynchPrediv  = 0x66;
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  RTC_Init(&RTC_InitStructure);

/* Configure the RTC WakeUp Clock source: CK_SPRE (1Hz) */
  RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
  RTC_SetWakeUpCounter(0x0);
/* Enable the RTC Wakeup Interrupt */
  RTC_ITConfig(RTC_IT_WUT, ENABLE);
/* Enable Wakeup Counter */
  RTC_WakeUpCmd(ENABLE);
                                                                                
}

  void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
// Set the Vector Table base location at 0x08000000 */ 
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

// 1 bits for Preemption Priority and 3 bits for Sub Priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;                  
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

时钟用的是LSE,就是外部低速晶振(32.768K)的

一直不能产生中断,各位大大,帮我看看是怎么回事吧,小弟在此谢过了...  

zlk1214 发表于 2017-10-19 22:35:42

以STM32F207VE中的RTC为例。
第一,所有的RTC中断都必须由EXTI产生,手册上面有这样一句话:
All RTC interrupts are connected to the EXTI controller.
第二,既然是EXTI在产生,所以他不同于一般的中断。一般的中断是只要标志位为1,就一直触发中断,直到标志位被清零,这是电平触发(例如TIM_IT_Update就属于此类)。EXTI只能检测上升沿和下降沿,不能直接通过电平触发。因此,如果开机的时候一来RTC_FLAG_WUTF就已经置位,那么EXTI_Line22将永远是高电平,不会有上升沿,因此永远也不会触发中断。解决方案是在开中断前手动清除标志位:
RTC_WakeUpCmd(DISABLE);
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(0);
RTC_WakeUpCmd(ENABLE);

RTC_ClearFlag(RTC_FLAG_WUTF); // 由于EXTI中断只对WUTF的上升沿有效, 因此若之前WUTF已经置位, 则永远不会触发中断!!!
RTC_ITConfig(RTC_IT_WUT, ENABLE);第三,启动文件startup_stm32f2xx.s里面所定义的RTC_WKUP_IRQHandler、RTC_Alarm_IRQHandler和TAMP_STAMP_IRQHandler这几个中断函数实质上分别是EXTI22、EXTI17和EXTI21的中断函数,都只能通过对应的RTC_FLAG_xx标志位的上升/下降沿(也就是0-1跳变)触发,且在不清除RTC标志位的前提下只能触发一次(EXTI_PR标志位已清除)!
第四,RTC_ITConfig(RTC_IT_WUT, ENABLE)和EXTI_Init(&exti)要同时打开。并且RTC_IT_WUT有记忆性,系统复位后不会关闭该中断。手动执行RTC_ITConfig(RTC_IT_WUT, DISABLE)后中断不再有效。

恒丶佣兵 发表于 2015-8-10 08:43:26

如果你是由待机模式唤醒的话不会进入中断,他相当于复位直接由程序开始运行
你可以在正常运行模式下使能唤醒,就会进入中断

uniqueeefocus41 发表于 2013-2-27 16:22:32

回复:求助!!STM32L151中的RTC唤醒(wake up)中断问题

 :'(哪位大神可以帮帮我的咧~~~

。。。-419078 发表于 2013-3-25 20:29:40

回复:求助!!STM32L151中的RTC唤醒(wake up)中断问题

回复第 2 楼 于2013-02-27 16:22:32发表:
 :'(哪位大神可以帮帮我的咧~~~
 

你在stm32l1xxit.h文件中有加中断程序吗?http://www.amobbs.com/thread-5004198-1-1.html这里貌似有这个中断。。不过我刚开始学,也不清楚这些。

zykzyk-93033 发表于 2013-3-25 22:20:29

RE:求助!!STM32L151中的RTC唤醒(wake up)中断问题

RTC中断和代码开起了吗?:D

chuckweng 发表于 2013-6-24 10:24:48

回复:求助!!STM32L151中的RTC唤醒(wake up)中断问题

楼主问题解决了吗

紫嫣0302 发表于 2015-10-21 15:49:10

RTC中断配置程序有写吗?
例如:
/* EXTI configuration *******************************************************/
EXTI_ClearITPendingBit(EXTI_Line20);
EXTI_InitStructure.EXTI_Line = EXTI_Line20;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
官网上下载的STM32L固件库中就有RTC中断的例子,你可以参考。

freewarm_300572 发表于 2016-8-25 10:33:05

我正在愁这个呢,无法使用RTC唤醒。:'(

废鱼 发表于 2016-8-25 14:39:47

freewarm_300572 发表于 2016-8-25 10:33
我正在愁这个呢,无法使用RTC唤醒。

什么问题,发帖说明情况。

zlk1214 发表于 2017-10-19 22:38:18

本帖最后由 格式化/tp 于 2017-10-19 22:40 编辑

测试代码:
system_stm32f2xx.c中要把SystemInit函数中的SetSysClock();函数调用注释掉,启动时选16MHz的HSI作为系统时钟。
#include <stdio.h>
#include <stm32f2xx.h>

int fputc(int ch, FILE *fp)
{
    if (fp == stdout)
    {
      if (ch == '\n')
      {
            while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
            USART_SendData(USART1, '\r');
      }
      while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
      USART_SendData(USART1, ch);
    }
    return ch;
}

void setclk(void)
{
    RCC_PLLConfig(RCC_PLLSource_HSI, 16, 240, 2, 5);
    RCC_PLLCmd(ENABLE);
   
    RCC_PCLK1Config(RCC_HCLK_Div4);
    RCC_PCLK2Config(RCC_HCLK_Div2);
   
    FLASH_SetLatency(FLASH_Latency_7);
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while (RCC_GetSYSCLKSource() != 0x08);
}

int main(void)
{
    EXTI_InitTypeDef exti;
    GPIO_InitTypeDef gpio;
    RTC_DateTypeDef date;
    RTC_InitTypeDef rtc;
    RTC_TimeTypeDef time;
    USART_InitTypeDef usart;
    setclk();
   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
   
    PWR_BackupAccessCmd(ENABLE);
   
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    gpio.GPIO_Mode = GPIO_Mode_AF;
    gpio.GPIO_OType = GPIO_OType_PP;
    gpio.GPIO_Pin = GPIO_Pin_9;
    gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpio);
   
    USART_StructInit(&usart);
    usart.USART_BaudRate = 115200;
    usart.USART_Mode = USART_Mode_Tx;
    USART_Init(USART1, &usart);
    USART_Cmd(USART1, ENABLE);
   
    printf("STM32F207VE RTC\n");
    RCC_LSICmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
    if (RTC_GetFlagStatus(RTC_FLAG_INITS) == RESET)
    {
      printf("RTC Initialization!\n");
      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // 32kHz
      RCC_RTCCLKCmd(ENABLE);
      
      rtc.RTC_HourFormat = RTC_HourFormat_12;
      rtc.RTC_AsynchPrediv = 127;
      rtc.RTC_SynchPrediv = 249; // 128*250=32000
      RTC_Init(&rtc);
      
      date.RTC_Date = 19;
      date.RTC_Month = RTC_Month_October;
      date.RTC_WeekDay = RTC_Weekday_Thursday;
      date.RTC_Year = 17;
      RTC_SetDate(RTC_Format_BIN, &date);
      
      time.RTC_H12 = RTC_H12_PM;
      time.RTC_Hours = 8;
      time.RTC_Minutes = 49;
      time.RTC_Seconds = 10;
      RTC_SetTime(RTC_Format_BIN, &time);
    }
    else
      RTC_WaitForSynchro();
   
    RTC_WakeUpCmd(DISABLE);
    RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
    RTC_SetWakeUpCounter(0);
    RTC_WakeUpCmd(ENABLE);
   
    RTC_ClearFlag(RTC_FLAG_WUTF); // 由于EXTI中断只对WUTF的上升沿有效, 因此若之前WUTF已经置位, 则永远不会触发中断!!!
    RTC_ITConfig(RTC_IT_WUT, ENABLE);
   
    exti.EXTI_Line = EXTI_Line22;
    exti.EXTI_LineCmd = ENABLE;
    exti.EXTI_Mode = EXTI_Mode_Interrupt;
    exti.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&exti);
    NVIC_EnableIRQ(RTC_WKUP_IRQn);
   
    while (1)
    {
      RTC_GetDate(RTC_Format_BIN, &date);
      RTC_GetTime(RTC_Format_BIN, &time);
      printf("20%02d-%d-%d %02d:%02d:%02d %s\n", date.RTC_Year, (date.RTC_Month & 0x10) ? (date.RTC_Month - 6) : date.RTC_Month, date.RTC_Date, time.RTC_Hours, time.RTC_Minutes, time.RTC_Seconds, (time.RTC_H12 == RTC_H12_AM) ? "AM" : "PM");
      
      __WFI();
    }
}

void RTC_WKUP_IRQHandler(void)
{
    EXTI_ClearITPendingBit(EXTI_Line22);
    RTC_ClearITPendingBit(RTC_IT_WUT);
}

stm32csdm1661 发表于 2019-6-17 11:21:11

本帖最后由 skydashanmao 于 2019-6-17 11:24 编辑

我用的单片机是STM32L476,也是进不去中断,今天刚把这个问题解决掉。因为驱动库中给的RTC Wakeup的EXTI中断没有打开。进行如下操作:将HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS)函数中的__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT()替换为__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT()

516750565 发表于 2020-11-18 14:25:09

格式化/tp 发表于 2017-10-19 22:35
以STM32F207VE中的RTC为例。
第一,所有的RTC中断都必须由EXTI产生,手册上面有这样一句话:
All RTC inter ...

分析的很透彻,也讲的很清楚,感谢分享:handshake
页: [1]
查看完整版本: 求助!!STM32L151中的RTC唤醒(wake up)中断问题