STM32CubeMX设置
开串口以及中断
LED2,配置GPIO
生成项目:
keil配置自动复位和打开MicroLIB
书写代码:首先书写uart.c中重写printf
cs
#include <stdio.h>
int fputc (int ch,FILE * file)
{
HAL_UART_Transmit(&huart1,(uin8_t *)&ch,1,1000);
return ch;
}
复制register代码到hal库中main.c中
cs
printf("低功率实验:睡眠模式...\n");
// 1. 开启LED灯,延时2s,模拟正常程序执行过程
LED_On(LED_1);
Delay_s(2);
while (1)
{
// 2. 进入睡眠模式
printf("正常代码执行完毕,3s后进入睡眠模式...\n");
Delay_s(3);
printf("进入睡眠模式");
enter_sleep_mode();
// 3. 以下代码只有在唤醒之后才会执行
printf("从睡眠模式中唤醒...\n");
Delay_s(2);
}
然后再进行修改:
cs
printf("尚硅谷低功率实验:睡眠模式...\n");
// 1. 开启LED灯,延时2s,模拟正常程序执行过程
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 2. 进入睡眠模式
printf("正常代码执行完毕,3s后进入睡眠模式...\n");
HAL_Delay(3000);
printf("进入睡眠模式\n");
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 3. 以下代码只有在唤醒之后才会执行
printf("从睡眠模式中唤醒...\n");
HAL_Delay(2000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
但是hal库中的中断开启需要手动开启
cs
HAL_UART_Receive_IT(&huart1, &ch, 1);
运行代码会发现不停的唤醒,因为任何中断都可以进入睡眠模式,hal中的systick中断也可以进入睡眠,解决办法是临时暂停然后恢复。
cs
// 暂停Systick中断
HAL_SuspendTick();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 恢复Systick中断
HAL_ResumeTick();
再次运行:会发现进入睡眠模式后只能唤醒1次,分析原因是因为,中断服务程序默认关闭中断。
解决办法,是将中断服务程序的回调函数,重写打开中断。 添加下面代码(哪里都可以)。
cs
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
printf("%c", ch);
// 重新打开接收中断使能
HAL_UART_Receive_IT(&huart1, &ch, 1);
}
}
进入睡眠模式发现烧录不了程序了,解决方法是打开keil中按下图配置