1.单片机选型
GD32L233KBQ6
PA0低电平mcu进入standby休眠态,检测到PA0高电平则唤醒,软复位重新执行main函数。
2.main.c
#include "gd32l23x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32l23x_eval.h"
#include "gd32l23x_i2c.h"
void delay(volatile uint32_t t) {
while(t--);
}
void usart0_gpio_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9); // PA9 -> USART0_TX
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10); // PA10 -> USART0_RX
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9 | GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9 | GPIO_PIN_10);
}
void usart0_config(void)
{
rcu_periph_clock_enable(RCU_USART0);
usart_deinit(USART0); // 复位
usart_baudrate_set(USART0, 115200U);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_enable(USART0);
}
void wakeup_pin_init(void)
{
// 1. 启用 PMU 时钟
rcu_periph_clock_enable(RCU_PMU);
// 2. 清除之前的 STANDBY / WUF 标志
pmu_flag_clear(PMU_FLAG_STANDBY);
pmu_flag_clear(PMU_FLAG_WAKEUP);
// 3. 允许 WKUP0(PA0) 上升沿唤醒
pmu_wakeup_pin_enable(PMU_WAKEUP_PIN0);
}
void enter_standby_mode(void)
{
// 进入 STANDBY 模式
pmu_to_standbymode();
}
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t)ch);
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
return ch;
}
int main(void)
{
SystemInit();
systick_config();
usart0_gpio_config();
usart0_config();
printf("MCU started!\r\n");
// 如果是来自 Standby 模式唤醒
if (pmu_flag_get(PMU_FLAG_STANDBY)) {
printf("Woke up from Standby mode!\r\n");
pmu_flag_clear(PMU_FLAG_STANDBY);
}
// 如果没有插入外设(PA0 == 0) → 进入 Standby
if (gpio_input_bit_get(GPIOA, GPIO_PIN_0) == RESET) {
printf("No device detected. Entering Standby...\r\n");
delay_1ms(10);
wakeup_pin_init(); // 初始化唤醒引脚
pmu_to_standbymode(); // 无参数,直接调用
}
// 正常运行逻辑
printf("Device detected. Running normally...\r\n");
while (1){
// 串口回显
if (usart_flag_get(USART0, USART_FLAG_RBNE) != RESET) {
uint8_t ch = usart_data_receive(USART0);
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
usart_data_transmit(USART0, ch);
}
};
}
3.实现效果
起始PA0低电平,pmu_to_standbymode()进入休眠态,无法实现while循环中的串口回显功能。
PA0给高电平后,mcu唤醒,串口回显成功。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_60013390/article/details/149113289
|