两天的调试与查阅资料终于明白了HAL库中的低功耗模式的切换和退出。主要还是自己作死选择了STM32G071,本文内容基于NUCLEO-G071RB,CUBEMX版本5.2.0,STM32Cube FW_G0 V1.2.0,MDK 5.27.1.0。
首先配置时钟、UART、RTC和中断。
RCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认
SYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)
设置串口
打开中断入口
完成设置后点击生成代码创建工程
1.首先喜闻乐见的printf函数
- /* USER CODE BEGIN Includes */
- #include "stdio.h"
- /* USER CODE END Includes */
- #ifdef __GNUC__
- /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
- set to 'Yes') calls __io_putchar() */
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
- #else
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
- #endif /* __GNUC__ */
- PUTCHAR_PROTOTYPE
- {
- /* Place your implementation of fputc here */
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
- HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
-
- return ch;
- }
复制代码
2.RTC时间获取函数
- /* USER CODE BEGIN PTD */
- RTC_DateTypeDef sdatestructureget;
- RTC_TimeTypeDef stimestructureget;
- uint8_t aShowTime[16] = "hh:ms:ss";
- /* USER CODE END PTD */
- /* USER CODE BEGIN PD */
- static void RTC_TimeShow(uint8_t *showtime);
- /* USER CODE END PD */
- static void RTC_TimeShow(uint8_t *showtime)
- {
- /* Get the RTC current Time */
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
- /* Get the RTC current Date */
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
- /* Display time Format : hh:mm:ss */
- sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
- }
复制代码
3.standby进入函数
- /* USER CODE BEGIN PD */
- void Sys_Enter_Standby(void);
- /* USER CODE END PD */
- void Sys_Enter_Standby(void)
- {
- /* The Following Wakeup sequence is highly recommended prior to Standby mode entry
- - Enable wakeup
- - Clear wake up pin flag depending in edge detection & pin level.
- - Enter the Standby mode.
- */
- /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */
- HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发
- HAL_PWREx_EnableInternalWakeUpLine();
- /* Clear all related wakeup flags*/
- __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
- /* Enter the Standby mode */
- //HAL_PWR_EnterSTANDBYMode();
- printf("enter Shutdown Mode!");
- HAL_PWREx_EnterSHUTDOWNMode();
- /* This code will never be reached! */
- }
复制代码
4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)
- void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_RTC_AlarmAEventCallback could be implemented in the user file
- */
- flag =1;
- // NVIC_SystemReset();
-
- }
复制代码
5.在main函数中5秒的时候进入低功耗模式
- /* USER CODE BEGIN 2 */
- uint8_t sec=0;
- if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
- {
- /* Clear Standby flag */
- __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
- printf("wake up from standby!");
- /* Check and Clear the Wakeup flag */
- if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
- {
- __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
- }
-
- /* Wait that user release the User push-button */
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}
- }
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- RTC_TimeShow(aShowTime);
- if(sec == 0)flag=0;
- if(sec == 5)Sys_Enter_Standby();
- if(sec!=stimestructureget.Seconds)
- {
- sec=stimestructureget.Seconds;
- printf("%s",(char *)aShowTime);
- if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);
- }
- }
- /* USER CODE END 3 */
- }
复制代码
至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。
附加 避免上电自动配置RTC时钟
- /* USER CODE BEGIN Check_RTC_BKUP */
- if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}
- else{return;}
- /* USER CODE END Check_RTC_BKUP */
复制代码
以上代码请添加于MX_RTC_Init(void)中
项目文件
|