STM32G030使用cubemx的时候,配置RTC为什么没有出现对RTC_NVIC的配置

STM32G030使用cubemx的时候,配置RTC为什么没有出现对RTC_NVIC的配置

img

  • 关于该问题,我找了一篇非常好的博客,你可以看看是否有帮助,链接:STM32,CubeMX,低功耗模式:RTC唤醒
  • 除此之外, 这篇博客: STM32G030F6使用CubeMx配置RTC及闹钟实验中的 2.2 串口相关的代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 因打印相关信息需要使用 printf ,需要包含 stdio.h 的头文件,且需要重新设 fputc 的函数
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    RTC_HandleTypeDef hrtc;
    
    UART_HandleTypeDef huart1;
    
    /* USER CODE BEGIN PV */
    RTC_DateTypeDef date;	//读取日期
    RTC_TimeTypeDef time;	//读取时间
    uint8_t RTCStatus = 0;	//指示RTC状态
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_RTC_Init(void);
    static void MX_USART1_UART_Init(void);
    /* USER CODE BEGIN PFP */
    // fputc 函数重映射
    #ifdef __GNUC_
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    #endif
    PUTCHAR_PROTOTYPE
    {
        HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 0xFFFF);
    
        return ch;
    }
    /* USER CODE END PFP */
    
    • RTC 初始化
    static void MX_RTC_Init(void)
    {
    
      /* USER CODE BEGIN RTC_Init 0 */
    
      /* USER CODE END RTC_Init 0 */
    
      RTC_TimeTypeDef sTime = {0};
      RTC_DateTypeDef sDate = {0};
      RTC_AlarmTypeDef sAlarm = {0};
    
      /* USER CODE BEGIN RTC_Init 1 */
    
      /* USER CODE END RTC_Init 1 */
      /** Initialize RTC Only
      */
      hrtc.Instance = RTC;
      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
      hrtc.Init.AsynchPrediv = 127;
      hrtc.Init.SynchPrediv = 255;
      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
      hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
      hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
      if (HAL_RTC_Init(&hrtc) != HAL_OK)
      {
        Error_Handler();
      }
    
      /* USER CODE BEGIN Check_RTC_BKUP */
    //    //重启后判断该寄存器是否有值,判定是不是第丿次初始化,是否要装载初始倿
    //    if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == 0xAA)
    //    {
    //        //已经初始化过了,直接跳出初始化函
    //        return;
    //    }
    //    //第一次初始化,将任意后备寄存器写任意值,做个标记,标记已经初始化过了,下次系统复位时不用初始匿
    //    HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xAA);
      /* USER CODE END Check_RTC_BKUP */
    
      /** Initialize RTC and set the Time and Date
      */
      sTime.Hours = 14;
      sTime.Minutes = 50;
      sTime.Seconds = 0;
      sTime.SubSeconds = 0;
      sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
      sTime.StoreOperation = RTC_STOREOPERATION_RESET;
      if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
      {
        Error_Handler();
      }
      sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
      sDate.Month = RTC_MONTH_JANUARY;
      sDate.Date = 28;
      sDate.Year = 21;
    
      if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
      {
        Error_Handler();
      }
      /** Enable the Alarm A
      */
      sAlarm.AlarmTime.Hours = 14;
      sAlarm.AlarmTime.Minutes = 50;
      sAlarm.AlarmTime.Seconds = 10;	//设置 10s 后产生闹钟中断
      sAlarm.AlarmTime.SubSeconds = 0;
      sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
      sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
      sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
      sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
      sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
      sAlarm.AlarmDateWeekDay = 28;
      sAlarm.Alarm = RTC_ALARM_A;
      if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN RTC_Init 2 */
    
      /* USER CODE END RTC_Init 2 */
    
    }
    

    此初始化函数中 设置了当前的时间和日期,并使能了闹钟中断在 10s 后产生.

    • 配置 RTC 闹钟中断的回调函数及设置下次产生闹钟中断的时间函数
    /* 设置闹钟下次产生的时间 */
    void setalarm(int hours, int minutes, int seconds)
    {
        RTC_AlarmTypeDef sAlarm = {0};
        RTC_DateTypeDef sdate = {0};    
        RTC_TimeTypeDef stime = {0};
    
        //读取当前时间 
        HAL_RTC_GetTime(&hrtc, &stime, RTC_FORMAT_BIN); 
        HAL_RTC_GetDate(&hrtc, &sdate, RTC_FORMAT_BIN);
        //获取设置中断时的时间
        sAlarm.Alarm = RTC_ALARM_A;
        sAlarm.AlarmTime.Hours   = hours   + stime.Hours;
        sAlarm.AlarmTime.Minutes = minutes + stime.Minutes;
        sAlarm.AlarmTime.Seconds = seconds + stime.Seconds;
        if(sAlarm.AlarmTime.Seconds >= 60)
        {
            sAlarm.AlarmTime.Seconds = sAlarm.AlarmTime.Seconds % 60;
            sAlarm.AlarmTime.Minutes += 1;
            if(sAlarm.AlarmTime.Minutes >= 60)
            {
                sAlarm.AlarmTime.Minutes = sAlarm.AlarmTime.Minutes % 60;
                sAlarm.AlarmTime.Hours += 1;
                if(sAlarm.AlarmTime.Hours >= 24)
                {
                    sAlarm.AlarmTime.Hours = sAlarm.AlarmTime.Hours % 24;
                    sdate.Date += 1;
                }
            }
        }
        sAlarm.AlarmTime.SubSeconds = 0;
        sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
        sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
        sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
        sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
        sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
        sAlarm.AlarmDateWeekDay = sdate.Date;   //跨天数定时,需要注意
    
    
        if(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
        {
            Error_Handler();
        }
    }
    
    /**
      * @brief  Alarm callback 闹钟中断回调函数
      * @param  hrtc : RTC handle
      * @retval None
      */
    void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
    {
        static uint16_t sEnterCnt = 0;
        
        setalarm(0,0,5);	//设置 5s 后再次产生闹钟中断
        printf("Alarm A Interrupt Cnt:%d \r\n",sEnterCnt++);
    }
    
    • main 函数
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_RTC_Init();
      MX_USART1_UART_Init();
      /* USER CODE BEGIN 2 */
      printf("stm32g030f6 rtc & alarm demo start......\n");
      RTCStatus = 0x01;
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
        while(1)
        {
            HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
            HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
            printf("20%d-%02d-%02d %02d:%02d:%02d \r\n", date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds);
            HAL_Delay(1000);
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
        }
      /* USER CODE END 3 */
    }
    

    主函数中每隔 1s 读取一次实时日期和时间,并打印出来.

  • 您还可以看一下 曹江涛老师的基于STM32 CubeMX的RTC时钟实战课程中的 STM32的内部资源RTC初探小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    根据参考资料,我对于STM32G030芯片和CubeMX配置RTC的问题给出以下解答:

    根据问题描述,STM32G030芯片和CubeMX进行RTC配置时没有找到RTC_NVIC的选项。这是因为在STM32G030芯片中,RTC中断不再使用NVIC(Nested Vectored Interrupt Controller)配置方式,而是使用EXTI(External Interrupt)配置方式。

    要正确配置RTC功能,可以按照以下步骤进行配置:

    1. 打开CubeMX软件,选择对应的STM32G030芯片型号。
    2. 在"Pinout & Configuration"选项卡中,找到并选择RTC功能,在右侧的中断配置栏中,可以看到类似"RTC Alarm EXTI line"的选项。
    3. 点击选项旁边的"..."按钮,进入配置窗口。
    4. 在配置窗口中,可以看到"Trigger Mode"、"Falling Edge/ Rising Edge"等选项,根据实际需求进行配置。比如,选择"Trigger Mode"为"Rising Edge",表示上升沿触发。
    5. 配置完成后,点击"OK"按钮,返回到主界面。
    6. 在主界面上,可以看到选中的RTC功能已经配置成功。
    7. 继续进行其他的功能配置,最后生成代码。
    8. 将生成的代码导入到IDE(如Keil、IAR)中,进行编译和下载。

    通过以上步骤,可以正确配置RTC功能,并使用EXTI进行中断触发。具体配置的代码如下所示(注:代码仅供参考,具体根据需求和实际情况进行修改):

    /* 配置RTC时钟 */
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
    
    /* 配置RTC时钟分频系数,设置周期为1s */
    __HAL_RCC_RTC_ENABLE();
    hrtc.Instance = RTC;
    hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
    hrtc.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
    hrtc.Init.SynchPrediv = RTC_SYNCH_PREDIV;
    hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
    hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
    HAL_RTC_Init(&hrtc);
    
    /* 配置RTC中断触发方式 */
    HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, RTC_SMOOTHCALIB_PLUSPULSES_RESET, RTC_SMOOTHCALIB_PLUSPULSES_SET);
    HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
    HAL_RTCEx_SetTimestamp_IT(&hrtc, RTC_TIMESTAMPEDGE_RISING, RTC_TIMESTAMPPIN_DEFAULT);
    HAL_RTCEx_SetAlarm_IT(&hrtc, RTC_FORMAT_BIN, RTC_ALARMDATEWEEKDAYSEL_DATE, RTC_ALARMDATEWEEKDAYSEL_WEEKDAY, RTC_WAKEUPCLOCK_RTCCLK_DIV8);
    

    希望以上解答对您有所帮助,如有更多问题,请随时追问。