Assinass_ 2025-07-28 02:52 采纳率: 0%
浏览 14
已结题

关于#stm32#的问题:RTC闹钟中断

在学习stm32F103C8T6过程中使用RTC闹钟中断的时候一直不能成功进入到中断函数,请大shen来指点!!

#include "stm32f10x.h"                  // Device header
#include "time.h"
#include "Buzzer.h"
#include "Delay.h"

uint16_t RTCTime[] = {2025,7,28,1,13,20};
uint16_t RTCALMTime[] = {2025,7,28,1,13,30};
void MyRTC_SetTime(void);
void SetRTC_ALM(void);


typedef struct
{
    uint16_t year;
    uint8_t mon;
    uint8_t day;
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
    
}time_date;

void MyRTC_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
    
    PWR_BackupAccessCmd(ENABLE);
    
//    if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
//    {
        RCC_LSEConfig(RCC_LSE_ON);
        
        
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
        
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        RCC_RTCCLKCmd(ENABLE);
        
        RTC_WaitForSynchro();  //等待时钟同步
        RTC_WaitForLastTask(); //等待上一次写入操作完成
        
        RTC_SetPrescaler(32768-1);
        RTC_WaitForLastTask();
        
        MyRTC_SetTime();
        RTC_WaitForLastTask();
        
        SetRTC_ALM();
        RTC_WaitForLastTask();
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_Init(&NVIC_InitStructure);
//        BKP_WriteBackupRegister(BKP_DR1,0xA5A5);
        
        
//    }
//    else
//    {
//        RTC_WaitForSynchro();  //等待时钟同步
//        RTC_WaitForLastTask(); //等待上一次写入操作完成
//    }
//    
    
}

void MyRTC_SetTime(void)
{
    time_t time_cnt;
    struct tm time_date;
    
    time_date.tm_year = RTCTime[0] - 1900;
    time_date.tm_mon = RTCTime[1] - 1;
    time_date.tm_mday = RTCTime[2];
    time_date.tm_hour = RTCTime[3];
    time_date.tm_min = RTCTime[4];
    time_date.tm_sec = RTCTime[5];
    
    time_cnt = mktime(&time_date) - 8*60*60;
    
    RTC_SetCounter(time_cnt);
    RTC_WaitForLastTask();
}

void MyRTC_ReadTime(void)
{
    time_t time_cnt;
    struct tm time_date;
    
    time_cnt = RTC_GetCounter() + 8*60*60;
    
    time_date = *localtime(&time_cnt);
    
    RTCTime[0] = time_date.tm_year + 1900;
    RTCTime[1] = time_date.tm_mon + 1;
    RTCTime[2] = time_date.tm_mday;
    RTCTime[3] = time_date.tm_hour;
    RTCTime[4] = time_date.tm_min;
    RTCTime[5] = time_date.tm_sec;
    
}

void SetRTC_ALM(void)
{
    time_t time_alm;
    struct tm time_almdate;
    
    time_almdate.tm_year = RTCALMTime[0] - 1900;
    time_almdate.tm_mon = RTCALMTime[1] - 1;
    time_almdate.tm_mday = RTCALMTime[2];
    time_almdate.tm_hour = RTCALMTime[3];
    time_almdate.tm_min = RTCALMTime[4];
    time_almdate.tm_sec = RTCALMTime[5];
    
    time_alm = mktime(&time_almdate) - 8*60*60; // 减去8小时时区差
    
    RTC_SetAlarm(time_alm);
    RTC_WaitForLastTask();
    
    RTC_ClearFlag(RTC_FLAG_ALR);
        
    RTC_ITConfig(RTC_IT_ALR,ENABLE);
        
}



void RTC_IRQHandler (void)
{
    if(RTC_GetITStatus(RTC_IT_ALR) == SET)
    {
        Buzzer_ON();
        Delay_s(10);
        Buzzer_OFF();
        RTC_ClearITPendingBit(RTC_IT_ALR);
    }
}


img

调试的时候中断配置使能和NVIC都配置没问题,但是就是进不去中断函数,RTC_SetAlarm给的值也测试过是没问题的。这个问题已经困扰了我许久了,但一直找不到原因。

  • 写回答

4条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-07-28 02:52
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 首先要确保RTC的基本配置正确,包括时钟源选择、分频设置等。
      - 闹钟的配置参数要准确,如闹钟时间的设置。
      - 中断相关的配置,包括使能RTC闹钟中断、配置NVIC等。
    2. 解决方案:
      - RTC基本配置
      ```c
      // 使能PWR和BKP时钟
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
      // 允许访问后备寄存器
      PWR_BackupAccessCmd(ENABLE);

      // 配置RTC时钟源
      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
      // 使能RTC时钟
      RCC_RTCCLKCmd(ENABLE);

      // 等待RTC寄存器同步
      while (RCC_GetFlagStatus(RCC_FLAG_RTCSYNC) == RESET);

      // 配置RTC预分频器
      RTC_SetPrescaler(32767); // 例如,设置分频系数为32767,使RTC时钟频率为32.768kHz
      - **闹钟配置**:c
      // 设置闹钟时间
      RTC_SetAlarm(RTC_Format_BIN, 12, 0, 0); // 例如,设置为12点整

      // 配置闹钟中断
      RTC_ITConfig(RTC_IT_ALR, ENABLE);
      - **NVIC配置**:c
      NVIC_InitTypeDef NVIC_InitStructure;
      NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
      - **中断函数**:c
      void RTC_IRQHandler(void)
      {
      if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
      {
      // 在此处编写中断处理代码
      // 例如,执行特定任务
      RTC_ClearITPendingBit(RTC_IT_ALR);
      }
      }
      ```
      3. 多种解决方案优缺点:
      - 上述方案
      - 优点:较为全面地涵盖了RTC闹钟中断的配置步骤,从基本时钟配置到闹钟设置再到中断处理,逻辑清晰,易于理解和调试。
      - 缺点:代码相对较为固定,对于不同的应用场景可能需要进行一些修改,例如闹钟时间的设置方式等。
      - 另一种简化思路
      - 优点:代码量可能相对较少,配置过程相对简洁。
      - 缺点:可能会忽略一些重要的配置细节,对于初学者来说可能理解起来不够全面,不利于排查问题。
      4. 总结:
      - 要成功实现RTC闹钟中断,需要正确配置RTC的时钟、分频、闹钟时间以及中断相关设置。通过上述步骤,可以逐步排查问题并确保能够正确进入中断函数执行相应操作。

    请注意,以上代码基于STM32F10x标准库,具体实现可能需要根据实际硬件和开发环境进行适当调整。同时,不同的开发板和芯片可能在配置上略有差异。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月28日
  • 创建了问题 7月28日