每日更新教程,评论区答疑解惑,小白也能变大神!"
目录
一.CW32F030C8T6 电源管理
1.1概述
- CW32x030 工作时需要两组电源供电:工作电源(VDD、VSS)和模拟电源(VDDA、VSSA)。用户可以选择工作 电源和模拟电源使用同一电源,也可以使用两组不同电源,但是二者相差不能超过 0.3V,详细电源内容请参阅数 据手册相关章节。
- CW32x030 内嵌一路 1.5V 低压差 LDO 稳压器,为芯片内部数字电源域供电。
- 芯片内置参考电压生成器(BGR)电路,可为其他模拟模块提供参考电压。
- 注意: 模拟电源电压与参考电压的压差须高于 0.3V。
- 关于电压参考的详细参数请参阅数据手册相关章节。
- 芯片内部电源域的划分与分配,如下图所示:
1.2电源监控
- 上电复位(POR)/ 掉电复位(BOR) CW32x030 集成了上电复位(POR)和掉电复位(BOR)电源监控电路,电源上电后始终处于工作状态。POR/ BOR 同时监控 VDD 和 VDDA 电源电压,当监测到电源电压低于复位阈值(VBOR)时,系统会进入复位状态。用户 无需额外增加外部硬件复位电路。
- 电源上电启动以及电源跌落阶段的复位信号波形,如下图所示:
1.3工作模式
- CW32x030 支持三种工作模式,由内嵌的电源管理模块自动完成电源的统一管理。三种工作模式是:
- 运行模式(Active mode)
- 休眠模式(Sleep mode)
- 深度休眠模式(DeepSleep mode)
- 电源上电后,系统自动进入运行模式。用户可通过软件程序,进入休眠或深度休眠两种低功耗运行状态;在低功 耗运行状态时,可通过硬件中断触发唤醒机制,使系统返回到运行模式。 三种工作模式的转换机制,如下图所示:
1.4 进入休眠模式或深度休眠模式
- 使用 M0+ 内核的 ARM 等待中断专用指令,WFI(Wait for Interrupt),配合 M0+ 内核的系统控制寄存器(SCR, System Control Register)的 SLEEPONEXIT 和 SLEEPDEEP 位域,可实现立即进入或退出(中断服务程序)时进 入休眠模式或深度休眠模式。
- 立即进入 执行 WFI 指令,MCU 将立即进入休眠模式(SLEEPDEEP 为 0 时)或深度休眠模式(SLEEPDEEP 为 1 时)。
- 退出时进入 将 SLEEPONEXIT 位置 1,当退出最低优先级的中断服务程序后,MCU 会进入休眠模式(SLEEPDEEP 为 0 时) 或深度休眠模式(SLEEPDEEP 为 1 时),而不需执行 WFI 指令 。
1.5退出休眠模式或深度休眠模式
- 在休眠模式或深度休眠模式下,均可通过中断来唤醒 CPU,返回到运行模式。但是,值得注意的是,如果用户在 中断服务程序中执行 WFI 命令进入休眠(包括深度休眠),则需要比此中断更高优先级的中断才能唤醒 CPU,因此, 我们强烈建议用户在准备进入休眠前,应先处理完所有中断服务程序,并且清除所有中断请求和中断标志。
- 不同工作模式下,CPU 可响应的中断类型,如下表所示:
1.6工作模式与复位源
1.7低功耗应用
- 休眠模式下,CPU 停止运行,所有外设保持运行,包括 ARM® Cortex®-M0+ 内核外设,比如 NVIC、SysTick 等外设。 休眠模式的功耗低于运行模式。 深度休眠模式下,CPU 停止运行,高速时钟关闭,低速时钟保持状态不变,部分外设可以配置为继续运行,NVIC 中断处理仍然工作。深度休眠模式的功耗远小于休眠模式。 用户可以通过以下方式降低系统运行功耗: 降低系统时钟频率
- 使用低频率的高速时钟 HSI、HSE 或低速时钟 LSI、LSE。
- 通过编程预分频寄存器,降低 SYSCLK、HCLK、PCLK 的频率:
- ‒ 设置 SYSCTRL_CR0 寄存器的 SYSCLK 位域,选择适当的时钟源。
- ‒ 设置 SYSCTRL_CR0 寄存器的 HCLKPRS 位域,降低 HCLK 频率。
- ‒ 设置 SYSCTRL_CR0 寄存器的 PCLKPRS 位域,降低 PCLK 频率。 关闭休眠期间不使用的时钟和外设
- AHB 总线时钟 HCLK 和 APB 总线时钟 PCLK,可以根据需要关闭。
- 关闭与唤醒无关的外设的时钟:
- ‒ AHB 外设时钟使能控制寄存器,SYSCTRL_AHBEN。
- ‒ APB 外设时钟使能控制寄存器 1,SYSCTRL_APBEN1。
- ‒ APB 外设时钟使能控制寄存器 2,SYSCTRL_APBEN2。
1.8寄存器
二.案例-MCU通过按键进入/退出休眠和深度休眠模式
主函数 int main(void)
{
RCC_HSI_Enable(RCC_HSIOSC_DIV2); //配置系统时钟为HSI 24M
//Enable Systick Clk
InitTick(24000000ul); //初始化SysTick,系统时钟频率为24MHz
//Test only.
HclkOutTest(); //测试时钟输出功能(具体实现未展示)
//LED初始化
LED_Init(); //初始化LED引脚(PB8和PB9)
while (1)
{
/* Configure User push-button as external interrupt generator */
BSP_PB_Init(); //初始化按键PA1为外部中断源(下降沿触发)
gKeyStatus = 0; //清除按键状态标志
/* Wait until User push-button is pressed to enter the Low Power mode.
In the meantime, LED is blinks */
do
{
/* Toggle LED */
PB09_TOG(); //切换PB9电平(LED闪烁)
SysTickDelay(1000); //1s延时(基于SysTick)
}
while (gKeyStatus == 0); //等待按键按下(gKeyStatus由中断服务程序修改)
/* Make sure LED is turned off to
reduce low power mode consumption */
PB09_SETLOW(); //关闭LED以降低功耗
#if defined (SLEEP_MODE)
/* Sleep Mode Entry
- System Running at HSI (24 MHz)
- Code running from Internal FLASH
- All peripherals disabled.
- Wakeup using EXTI Line (User push-button PA.01)
*/
SleepModeTest(); //进入睡眠模式测试
#elif defined (DEEPSLEEP_MODE)
/* DeepSleep Mode Entry
- No IWDG
- Wakeup using EXTI Line (User push-button PA.01)
*/
DeepSleepModeTest(); //进入深度睡眠模式测试
#else
#error "Please select low power mode first!" //编译时检查是否定义了低功耗模式
#endif /* SLEEP_MODE */
//Test only.
HclkOutTest(); //唤醒后再次测试时钟输出
}
}
按键初始化函数 BSP_PB_Init
void BSP_PB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打开GPIO时钟
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk); //使能GPIOA时钟
GPIO_InitStructure.Pins = GPIO_PIN_1; //配置PA1引脚
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP; //上拉输入模式
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; //高速模式
//Configure Button pin as input with External interrupt
GPIO_InitStructure.IT = GPIO_IT_FALLING; //下降沿触发中断
GPIO_Init(CW_GPIOA, &GPIO_InitStructure); //应用配置
//Enable and set Button EXTI Interrupt to the lowest priority
NVIC_SetPriority(GPIOA_IRQn, 0x03); //设置GPIOA中断优先级为最低(0x03)
//清除中断标志并使能NVIC
GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN1_Msk); //清除PA1中断标志
NVIC_EnableIRQ(GPIOA_IRQn); //使能NVIC中的GPIOA中断
}
LED初始化函数 LED_Init
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打开GPIO时钟
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOB_Msk); //使能GPIOB时钟
/* Configure the GPIO_LED pin */
GPIO_InitStructure.Pins = GPIO_PIN_8 | GPIO_PIN_9; //配置PB8和PB9
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出模式
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; //高速模式
GPIO_Init(CW_GPIOB, &GPIO_InitStructure); //应用配置
//LEDs are off.
PB08_SETLOW(); //PB8初始化为低电平(LED灭)
PB09_SETLOW(); //PB9初始化为低电平(LED灭)
}
错误处理函数 Error_Handler
void Error_Handler(void)
{
while (1)
{
/* Turn LED1,LED2 on */
PB08_SETHIGH(); //PB8置高(LED亮)
PB09_SETHIGH(); //PB9置高(LED亮)
}
}
SysTick中断服务程序 SysTick_Handler
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn */
uwTick += uwTickFreq; //更新系统计时变量(通常用于延时功能)
/* USER CODE END SysTick_IRQn */
}
关键点说明
- 低功耗模式选择:通过预编译宏
SLEEP_MODE
或DEEPSLEEP_MODE
决定进入哪种低功耗模式。 - 中断唤醒:按键PA1的中断用于从低功耗模式唤醒系统。
- LED控制:PB8和PB9分别控制两个LED,闪烁指示系统运行状态。
- 时钟配置:系统使用HSI(内部高速时钟)24MHz,分频系数为2。