目錄
?
一、CubeMX配置RTC
1.RTC實時重要一環——BKP 寄存器
2.RTC實時時鐘
2.1打開RTC并設置時間
2.2打開外部低速時鐘
2.3代碼實現:
二、單片機工作模式
1.低功耗睡眠模式(Sleep)
2.低功耗停止模式(Stop)
3.低功耗待機模式(StandBy)
三、看門狗
1.獨立看門狗
2.窗口看門狗
一、CubeMX配置RTC
1.RTC實時重要一環——BKP 寄存器
BKP寄存器簡介
BKP(Backup Registers)備份寄存器
BKP可用于存儲用戶應用程序數據。當VDD(2.03.6V)電源被切斷,他們仍然由VBAT(1.83.6V)維持供電。當系統在待機模式下被喚醒,或系統復位或電源復位時他們也不會被復位
TAMPER引腳產生的侵入事件將所有備份寄存器內容清除
RTC引腳輸出RTC校準時鐘、RTC鬧鐘脈沖或者秒脈沖
存儲RTC時鐘校準寄存器
用戶數據存儲容量:
20字節(中容量和小容量)/ 84字節(大容量和互聯型)
小實驗將要實現的現象:單片機掉電后,不會遺忘BKP寄存器中的數值!
硬件連接:(需要額外供電給VB引腳)
第一次先寫:
HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,100);
uint32_t Ret= HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1);//斷電后靠VBAT供電OLED_ShowNum(0, 0, Ret, 4, 12);
運行后,第二次注釋掉HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,100);并且把單片機供電拔了,繼續運行,按道理說,這個Ret數值就會隨著單片機斷電變成0,但是當VDD電源被切斷,他仍然由VBAT維持供電!所以數值會維持不變!
CubeMX配置簡單使用BKP寄存器:
BKP 寄存器通常與 RTC 一起使用,在CubeIDE中假如需要使用BKP寄存器,需要先打開RTC
代碼實現:
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_I2C2_Init();MX_RTC_Init();/* USER CODE BEGIN 2 */OLED_Init();//OLED初始化OLED_CLS();// HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,100);//寫BKPuint32_t Ret= HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1);//斷電后靠VBAT供電。讀BKPOLED_ShowNum(0, 0, Ret, 4, 12);//顯示數值/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
2.RTC實時時鐘
CubeMX配置:
2.1打開RTC并設置時間
2.2打開外部低速時鐘
配置RTC時鐘源為LSE外部低速時鐘
2.3代碼實現:
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_I2C2_Init();/* USER CODE BEGIN 2 */RTC_TimeTypeDef RTC_Time ;//時分秒RTC_DateTypeDef RTC_Date; //年月日OLED_Init();OLED_CLS();OLED_ShowStr(0, 0, "Data:20 - -", 2);OLED_ShowStr(0, 2, "Time:", 2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_RTC_GetDate(&hrtc, &RTC_Date, RTC_FORMAT_BIN);HAL_RTC_GetTime(&hrtc,&RTC_Time, RTC_FORMAT_BIN);OLED_ShowNum(57, 0, RTC_Date.Year, 2, 16);OLED_ShowNum(78, 0, RTC_Date.Month, 2, 16);OLED_ShowNum(100, 0, RTC_Date.Date, 2, 16);OLED_ShowNum(57, 2, RTC_Time.Hours , 2, 16);OLED_ShowNum(78, 2, RTC_Time.Minutes, 2, 16);OLED_ShowNum(100, 2, RTC_Time.Seconds, 2, 16);}/* USER CODE END 3 */
}
效果:
二、單片機工作模式
1.低功耗睡眠模式(Sleep)
使用
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
打開睡眠模式。由于Hal庫與標準庫在管理系統時鐘和低功耗模式時的處理方式不同,Hal庫中需要多手動關閉SysTick定時器,因為SysTick定時器會周期性觸發中斷,會喚醒睡眠模式。
HAL_SuspendTick();//關閉SysTick定時器
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();//恢復SysTick定時器
2.低功耗停止模式(Stop)
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);//進入Stop模式
SystemClock_Config();//恢復時鐘
3.低功耗待機模式(StandBy)
配置PA0為喚醒引腳:
代碼:
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);while(1)
{__HAL_RCC_PWR_CLK_ENABLE();HAL_PWR_EnterSTANDBYMode();
}
三、看門狗
1.獨立看門狗
打開獨立看門狗并設置預分頻器和重裝值:
HAL_IWDG_Refresh(&hiwdg);//初始化完成后執行一次喂狗
//獲取當前的復位是IWDG造成的復位還是按Rst鍵造成的復位
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
{// IWDG reset flag is setOLED_ShowString(2, 1, "IWDGRST"); //OLED閃爍IWDGRST字符串HAL_Delay(500);OLED_ShowString(2, 1, " ");HAL_Delay(100);__HAL_RCC_CLEAR_RESET_FLAGS();
}
else
{OLED_ShowString(3, 1, "RST"); //OLED閃爍RST字符串HAL_Delay(500);OLED_ShowString(3, 1, " ");HAL_Delay(100);
}while (1)
{HAL_IWDG_Refresh(&hiwdg);//喂狗HAL_Delay(1100);
}
2.窗口看門狗
代碼:
//獲取當前的復位是WWDG造成的復位還是按Rst鍵復位,這里代碼有大耗時,需要在
MX_WWDG_Init(); 之前
if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
{// IWDG reset flag is setOLED_ShowString(2, 1, "WWDGRST"); //OLED閃爍IWDGRST字符HAL_Delay(500);OLED_ShowString(2, 1, " ");HAL_Delay(100);__HAL_RCC_CLEAR_RESET_FLAGS();
}
else
{OLED_ShowString(3, 1, "RST"); //OLED閃爍RST字符HAL_Delay(500);OLED_ShowString(3, 1, " ");HAL_Delay(100);
}MX_WWDG_Init();
while (1)
{HAL_Delay(40);HAL_WWDG_Refresh(&hwwdg);//喂狗HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);//開
}