CH32V208系列单片机的低功耗测试(附部分代码供参考)
本次测试总结如下表:
CH32V208低功耗测试 | |
停止模式下平均功耗(uA) | |
调压器工作状态下 | 258.34 |
调压器低功耗状态下 | 22.87 |
调压器低功耗状态下,RTC周期性唤醒,唤醒后运行2ms延时程序后继续进入停止模式实际时间测试 | ||||||||||
停止模式低功耗期间平均功耗电流 | RTC唤醒周期时间 | 外部电容充电期间平均功耗电流 | 外部电容充电持续时间 | 外部低速时钟恢复期间平均功耗电流 | 时钟恢复工作持续时间(72MHz) | 唤醒后工作平均功耗电流 | 主程序延时2ms主体实测消耗时间 | 一个周期(RTC唤醒+2ms延时)平均功耗值 | ||
RTC定时1s周期性唤醒 | 22.36uA | 974.4ms | 7.04mA | 67us | 1.45mA | 455us |
7.19mA | 1.960ms | 59.43uA | |
RTC定时300ms周期性唤醒 | 22.51uA | 294.0ms | 8.27mA | 57us | 1.33mA | 460us |
7.30mA | 1.983ms | 109.63uA |
所用测试版如图所示,板子已拆除电源指示灯,LDO(低压差线性稳压器),以及R2电阻,避免有多余电流消耗。
上图为手册中在停止模式下的功耗值,以此为参考依据。
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
1、所有IO管脚,如果高阻状态端口是高电平,就设成上拉输入,如果高阻状态是低电平,设成下拉输入,如果高阻是中间状态,设成模拟输入。必须用到输出时,硬件上必须加上下拉。
2、不用的IO口可以设置为IPU/IPD/PP,如果IO为浮空状态,外部电路必须要用上拉或下拉,引脚浮空非常耗电。
3、芯片与外设相连时,外设脚为高电平芯片脚配成上拉,外设为低芯片也要为低电平,这样就能避免有电流。
4、睡眠模式不要使用外部晶振,两个晶振输入脚要remap成普通IO,并配置成IPU/IPD/PP,千万不能浮空,时钟使用内部RC振荡器。
5、如果用在32里:pwr的时钟要使能,即RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
6、关闭JTAG口,并设成普通IO;
7、不用的外设,复用的时钟要关闭。当用中断唤醒时,切记要保留。
先是测试调压器为运行状态下的功耗,
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* 开启单片机电源供应 */
PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);/* 使能调压器为正常运行模式 */
配置完成后,测得结果如下图:
平均为258.34uA左右,略高5uA。
紧接着将调压器改为低功耗模式,
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);/* 将调压器配置为低功耗模式 */
测得结果如下:
平均为22.87uA左右,与手册中23.8uA相差不大。
接下来测一下,当系统在停止模式下被RTC闹钟唤醒时需要多长时间,结果如下:
放大后查看,对比两个时间点:
实测唤醒时间约为333us,手册中参数为299us,相差不大。
接下来使用RTC定1s的闹钟,以1s为周期将MCU从停止模式中唤醒,主程序则使用2ms延时时间做主体:
while(1)
{
Delay_Ms(2);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}
测得结果如下图:
周期符合所定的1s,接下来放大看下,
此处实测时间为HSI内部时钟72MHz下测得,另外也测试过HSE外部时钟下该时间在1.4ms左右;
测完1sRTC闹钟,再测一次300msRTC闹钟检验一下,
参考代码:
/***********RTC初始化**************/
void RTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
/* enable LSI */
RCC_LSICmd(ENABLE);
/* wait for LSI to stabilize */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* select LSI as rtc clock */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask();
RTC_WaitForSynchro();
/* enable Alarm interrupt */
RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();
/* set RTC prescaler value */
RTC_SetPrescaler(9830); /* 此处为得到300ms定时,且低速外部时钟LSE晶振为32.768KHz,此处9830由32.768*1000*0.3≈9830得到,下同1s定时; */
//RTC_SetPrescaler(32768);
RTC_WaitForLastTask();
}
/***********RTC闹钟中断函数**************/
void RTCAlarm_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_ClearITPendingBit(RTC_IT_ALR);
if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
{
/* clear wakeup flag */
PWR_ClearFlag(PWR_FLAG_WU);
}
SystemInit();
printf("RTCAlarm_IRQHandler\r\n");
/* set alarm event */
RTC_SetAlarm(RTC_GetCounter()); /* 这里闹钟具体时间由RTC初始化中RTC_SetPrescaler(x)决定; */
RTC_WaitForLastTask();
}