引言
在汽车电子系统中,低功耗设计至关重要,特别是在车辆熄火后需要保持某些功能运行的场景。YTM32B1ME0x采用了先进的电源管理技术,提供多种低功耗模式,支持动态电压频率调节(DVFS),并集成了智能电源管理单元,能够在保证系统性能的同时最大化电池续航时间。
电源管理系统概览
电源域架构
YTM32B1ME0x采用多电源域设计:
| 电源域 | 电压范围 | 主要功能 | 低功耗特性 |
|---|---|---|---|
| VDD | 2.7V-3.6V | 主电源域 | 可关断 |
| VDDA | 2.7V-3.6V | 模拟电源 | 独立控制 |
| VBAT | 1.65V-3.6V | 备份电源 | 超低功耗 |
| VDD_USB | 3.0V-3.6V | USB电源 | 按需供电 |
| VREF | 内部参考 | ADC参考 | 可关断 |
功耗模式概览
┌─────────────────────────────────────┐ │ 电源管理控制器 │ │ Power Management Unit │ └─────────────────┬───────────────────┘ │ ┌─────────────────────────────┼─────────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 运行 │ │ 睡眠 │ │ 停止 │ │ 模式 │ │ 模式 │ │ 模式 │ │ RUN │ │ SLEEP │ │ STOP │ └─────────┘ └─────────┘ └─────────┘ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 80MHz │ │ CPU停止 │ │ 时钟停止│ │ 全功能 │ │ 外设运行│ │ RAM保持 │ │ ~50mA │ │ ~10mA │ │ ~100μA │ └─────────┘ └─────────┘ └─────────┘ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 待机 │ │ 关机 │ │ VBAT │ │ 模式 │ │ 模式 │ │ 域 │ │ STANDBY │ │SHUTDOWN │ │ BACKUP │ └─────────┘ └─────────┘ └─────────┘ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 深度睡眠│ │ 完全关断│ │ RTC运行 │ │ ~10μA │ │ ~1μA │ │ ~2μA │ └─────────┘ └─────────┘ └─────────┘
低功耗模式详解
睡眠模式(SLEEP)
睡眠模式是最浅的低功耗模式,CPU停止执行但外设继续运行:
// 睡眠模式配置
typedef struct {
bool sleep_on_exit; // 中断返回后继续睡眠
bool deep_sleep_enable; // 深度睡眠使能
uint32_t wakeup_sources; // 唤醒源配置
sleep_callback_t enter_callback; // 进入睡眠回调
sleep_callback_t exit_callback; // 退出睡眠回调
} sleep_config_t;
// 进入睡眠模式
void enter_sleep_mode(sleep_config_t *config) {
// 保存当前状态
save_cpu_context();
// 配置睡眠参数
if (config->sleep_on_exit) {
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
}
// 配置唤醒源
configure_wakeup_sources(config->wakeup_sources);
// 调用进入睡眠回调
if (config->enter_callback) {
config->enter_callback();
}
// 进入睡眠模式
__WFI(); // Wait For Interrupt
// 唤醒后执行
if (config->exit_callback) {
config->exit_callback();
}
// 恢复状态
restore_cpu_context();
}
// 配置唤醒源
void configure_wakeup_sources(uint32_t wakeup_sources) {
// 配置外部中断唤醒
if (wakeup_sources & WAKEUP_SOURCE_EXTI) {
EXTI->IMR |= EXTI_IMR_MR0; // 使能EXTI0中断
}
// 配置定时器唤醒
if (wakeup_sources & WAKEUP_SOURCE_TIMER) {
TIM2->DIER |= TIM_DIER_UIE; // 使能定时器中断
}
// 配置UART唤醒
if (wakeup_sources & WAKEUP_SOURCE_UART) {
UART1->CR1 |= UART_CR1_RXNEIE; // 使能接收中断
}
// 配置RTC唤醒
if (wakeup_sources & WAKEUP_SOURCE_RTC) {
RTC->CR |= RTC_CR_ALRAIE; // 使能RTC闹钟中断
}
}
// 睡眠模式功耗优化
void optimize_sleep_power(void) {
// 关闭不必要的外设时钟
RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN);
RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN);
RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN | RCC_APB2ENR_USART1EN);
// 配置GPIO为模拟输入以减少漏电流
configure_gpio_for_low_power();
// 禁用不必要的中断
disable_non_wakeup_interrupts();
// 降低系统时钟频率
reduce_system_clock_frequency();
}
// GPIO低功耗配置
void configure_gpio_for_low_power(void) {
GPIO_InitTypeDef gpio_config;
// 配置未使用的GPIO为模拟输入
gpio_config.Mode = GPIO_MODE_ANALOG;
gpio_config.Pull = GPIO_NOPULL;
gpio_config.Speed = GPIO_SPEED_LOW;
// 配置GPIOC未使用引脚
gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
HAL_GPIO_Init(GPIOC, &gpio_config);
// 配置输出引脚为低电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
}
停止模式(STOP)
停止模式下,主时钟停止,但RAM内容保持,功耗进一步降低:
// 停止模式配置
typedef struct {
stop_mode_t stop_mode; // 停止模式类型
bool flash_power_down; // Flash掉电
bool regulator_low_power; // 调节器低功耗模式
uint32_t wakeup_sources; // 唤醒源
stop_callback_t enter_callback; // 进入回调
stop_callback_t exit_callback; // 退出回调
} stop_config_t;
// 进入停止模式
void enter_stop_mode(stop_config_t *config) {
// 保存外设状态
save_peripheral_state();
// 配置停止模式参数
configure_stop_mode(config);
// 调用进入停止回调
if (config->enter_callback) {
config->enter_callback();
}
// 清除唤醒标志
PWR->CR |= PWR_CR_CWUF;
// 设置停止模式
PWR->CR &= ~PWR_CR_PDDS; // 选择停止模式
if (config->regulator_low_power) {
PWR->CR |= PWR_CR_LPDS; // 低功耗调节器
}
if (config->flash_power_down) {
PWR->CR |= PWR_CR_FPDS; // Flash掉电
}
// 设置深度睡眠
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
// 进入停止模式
__WFI();
// 唤醒后恢复
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
// 恢复系统时钟
restore_system_clock();
// 恢复外设状态
restore_peripheral_state();
// 调用退出停止回调
if (config->exit_callback) {
config->exit_callback();
}
}
// 配置停止模式
void configure_stop_mode(stop_config_t *config) {
// 配置唤醒源
configure_stop_wakeup_sources(config->wakeup_sources);
// 配置RTC唤醒
if (config->wakeup_sources & WAKEUP_SOURCE_RTC) {
configure_rtc_wakeup();
}
// 配置外部中断唤醒
if (config->wakeup_sources & WAKEUP_SOURCE_EXTI) {
configure_exti_wakeup();
}
// 配置UART唤醒
if (config->wakeup_sources & WAKEUP_SOURCE_UART) {
configure_uart_wakeup();
}
}
// RTC唤醒配置
void configure_rtc_wakeup(void) {
// 使能PWR时钟
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
// 使能备份域访问
PWR->CR |= PWR_CR_DBP;
// 配置RTC时钟源
RCC->BDCR |= RCC_BDCR_RTCSEL_LSI; // 选择LSI作为RTC时钟
RCC->BDCR |= RCC_BDCR_RTCEN; // 使能RTC
// 配置RTC唤醒定时器
RTC->WPR = 0xCA; // 解锁写保护
RTC->WPR = 0x53;
RTC->CR &= ~RTC_CR_WUTE; // 禁用唤醒定时器
while (!(RTC->ISR & RTC_ISR_WUTWF)); // 等待写入允许
RTC->WUTR = 32768 - 1; // 1秒唤醒(32768Hz LSI)
RTC->CR |= RTC_CR_WUTIE; // 使能唤醒中断
RTC->CR |= RTC_CR_WUTE; // 使能唤醒定时器
RTC->WPR = 0xFF; // 锁定写保护
// 配置EXTI线22(RTC唤醒)
EXTI->IMR |= EXTI_IMR_MR22;
EXTI->RTSR |= EXTI_RTSR_TR22;
NVIC_EnableIRQ(RTC_WKUP_IRQn);
}
// 外设状态保存
void save_peripheral_state(void) {
peripheral_state_t *state = get_peripheral_state();
// 保存GPIO状态
state->gpio_moder[0] = GPIOA->MODER;
state->gpio_moder[1] = GPIOB->MODER;
state->gpio_moder[2] = GPIOC->MODER;
state->gpio_odr[0] = GPIOA->ODR;
state->gpio_odr[1] = GPIOB->ODR;
state->gpio_odr[2] = GPIOC->ODR;
// 保存定时器状态
state->tim2_cr1 = TIM2->CR1;
state->tim2_arr = TIM2->ARR;
state->tim2_psc = TIM2->PSC;
// 保存UART状态
state->uart1_cr1 = UART1->CR1;
state->uart1_cr2 = UART1->CR2;
state->uart1_brr = UART1->BRR;
// 保存时钟配置
state->rcc_cfgr = RCC->CFGR;
state->rcc_cr = RCC->CR;
}
// 外设状态恢复
void restore_peripheral_state(void) {
peripheral_state_t *state = get_peripheral_state();
// 恢复时钟配置
RCC->CR = state->rcc_cr;
RCC->CFGR = state->rcc_cfgr;
// 等待时钟稳定
while (!(RCC->CR & RCC_CR_PLLRDY));
// 恢复GPIO状态
GPIOA->MODER = state->gpio_moder[0];
GPIOB->MODER = state->gpio_moder[1];
GPIOC->MODER = state->gpio_moder[2];
GPIOA->ODR = state->gpio_odr[0];
GPIOB->ODR = state->gpio_odr[1];
GPIOC->ODR = state->gpio_odr[2];
// 恢复定时器状态
TIM2->CR1 = state->tim2_cr1;
TIM2->ARR = state->tim2_arr;
TIM2->PSC = state->tim2_psc;
// 恢复UART状态
UART1->CR1 = state->uart1_cr1;
UART1->CR2 = state->uart1_cr2;
UART1->BRR = state->uart1_brr;
}
待机模式(STANDBY)
待机模式是最深的低功耗模式,除了备份域外所有内容都会丢失:
// 待机模式配置
typedef struct {
bool wakeup_pin_enable; // 唤醒引脚使能
bool rtc_alarm_enable; // RTC闹钟唤醒使能
uint32_t wakeup_pin_polarity; // 唤醒引脚极性
standby_callback_t enter_callback; // 进入待机回调
} standby_config_t;
// 进入待机模式
void enter_standby_mode(standby_config_t *config) {
// 保存关键数据到备份寄存器
save_critical_data_to_backup();
// 配置待机模式
configure_standby_mode(config);
// 调用进入待机回调
if (config->enter_callback) {
config->enter_callback();
}
// 清除唤醒标志
PWR->CR |= PWR_CR_CWUF;
// 设置待机模式
PWR->CR |= PWR_CR_PDDS;
// 设置深度睡眠
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
// 进入待机模式(不会返回)
__WFI();
}
// 配置待机模式
void configure_standby_mode(standby_config_t *config) {
// 使能PWR时钟
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
// 配置唤醒引脚
if (config->wakeup_pin_enable) {
PWR->CSR |= PWR_CSR_EWUP; // 使能唤醒引脚
// 配置唤醒引脚极性
if (config->wakeup_pin_polarity == WAKEUP_PIN_RISING) {
// 上升沿唤醒(默认)
} else {
// 下降沿唤醒需要额外配置
configure_wakeup_pin_falling_edge();
}
}
// 配置RTC闹钟唤醒
if (config->rtc_alarm_enable) {
configure_rtc_alarm_wakeup();
}
}
// 保存关键数据到备份寄存器
void save_critical_data_to_backup(void) {
// 使能备份域访问
PWR->CR |= PWR_CR_DBP;
// 保存系统状态
RTC->BKP0R = get_system_state();
// 保存配置参数
RTC->BKP1R = get_system_config();
// 保存运行时间
RTC->BKP2R = get_system_uptime();
// 保存错误计数
RTC->BKP3R = get_error_count();
// 保存唤醒原因
RTC->BKP4R = WAKEUP_REASON_STANDBY;
// 禁用备份域访问
PWR->CR &= ~PWR_CR_DBP;
}
// 从待机模式唤醒后的处理
void handle_standby_wakeup(void) {
// 检查复位原因
if (RCC->CSR & RCC_CSR_SFTRSTF) {
// 软件复位
handle_software_reset();
} else if (RCC->CSR & RCC_CSR_PORRSTF) {
// 上电复位
handle_power_on_reset();
} else if (PWR->CSR & PWR_CSR_SBF) {
// 从待机模式唤醒
handle_wakeup_from_standby();
}
// 清除复位标志
RCC->CSR |= RCC_CSR_RMVF;
PWR->CR |= PWR_CR_CSBF;
}
// 从待机模式唤醒处理
void handle_wakeup_from_standby(void) {
// 使能备份域访问
PWR->CR |= PWR_CR_DBP;
// 读取保存的数据
uint32_t system_state = RTC->BKP0R;
uint32_t system_config = RTC->BKP1R;
uint32_t system_uptime = RTC->BKP2R;
uint32_t error_count = RTC->BKP3R;
uint32_t wakeup_reason = RTC->BKP4R;
// 恢复系统状态
restore_system_state(system_state);
restore_system_config(system_config);
set_system_uptime(system_uptime);
set_error_count(error_count);
// 记录唤醒事件
log_wakeup_event(wakeup_reason, get_wakeup_source());

最低0.47元/天 解锁文章
513

被折叠的 条评论
为什么被折叠?



