串口DMA与主函数
2025/9/8大约 2 分钟
很简单,全双工
时序图很好看,读写同时进行



主函数
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t SYSCLK_Frequency = 0;
uint32_t HCLK_Frequency = 0;
uint32_t PCLK1_Frequency = 0;
uint32_t PCLK2_Frequency = 0;
uint32_t SYSCLK_Source = 0;
/* 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_USART1_UART_Init();
/* USER CODE BEGIN 2 */
printf("stop mode test\r\n");
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 使用绿灯指示,运行状态
HAL_GPIO_WritePin(GPIOB, LED_G_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, LED_G_Pin, GPIO_PIN_SET);
// 任务执行完毕,进入睡眠降低功耗
// 使用红灯指示,进入停止状态
HAL_GPIO_WritePin(GPIOB, LED_R_Pin, GPIO_PIN_RESET);
// 暂停滴答时钟,防止通过滴答时钟中断唤醒
HAL_SuspendTick();
// 配置下次唤醒的闹钟时间
RTC_AlarmStart();
// 使能PWR时钟
__HAL_RCC_PWR_CLK_ENABLE();
// 清除唤醒标记
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
// 进入停止模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
//唤醒点灯
HAL_GPIO_WritePin(GPIOB, LED_R_Pin, GPIO_PIN_SET);
// 被唤醒后,恢复滴答时钟
HAL_ResumeTick();
// 获取重新配置后的时钟状态
SYSCLK_Frequency = HAL_RCC_GetSysClockFreq();
HCLK_Frequency = HAL_RCC_GetHCLKFreq();
PCLK1_Frequency = HAL_RCC_GetPCLK1Freq();
PCLK2_Frequency = HAL_RCC_GetPCLK2Freq();
SYSCLK_Source = __HAL_RCC_GET_SYSCLK_SOURCE();
// 重新配置时钟源后始终状态
printf("\r\n 重新配置后的时钟状态:\r\n");
printf(" SYSCLK 频率:%d,\r\n HCLK 频率:%d,\r\n PCLK1 频率:%d,\r\n PCLK2 频率:%d,\r\n 时钟源:%d (0 表示 HSI,8 表示 PLLCLK)\n",SYSCLK_Frequency,HCLK_Frequency,PCLK1_Frequency,PCLK2_Frequency,SYSCLK_Source);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, LED_B_Pin, GPIO_PIN_SET);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}// 使能PWR时钟
HAL_RCC_PWR_CLK_ENABLE();
📌 如果没有使能 PWR 时钟,后续的 PWR 相关操作(如清除唤醒标志、进入低功耗模式)可能会失败!
// 清除唤醒标记
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
📌 如果 MCU 之前进入了 STOP/STANDBY 模式,并被外部中断或 RTC 唤醒,PWR_FLAG_WU 可能仍然保持为 1。此时,不清除该标志就无法再次进入低功耗模式。
新知识(这都不知道?)
局部变量未定义初值是随机值啊,不是0;
全局变量/静态才是0啊;
Output模式下:Output Level 控制初始电平,Pull-up/Pull-down基本无效。
Input模式下:Pull-up/Pull-down才决定引脚悬空时是高还是低
开漏模式下也可以把电平置1,只不过原理不一样,靠的是外部的上拉电阻,IIC用
详见:

