板子是ch57XEvt 191121, 上边的ch330、1117等元件已经去掉, 发光二极管也去掉了, 直接3.3v供电, 程序下载的是 CH579EVT\EVT\EXAM\PM下的demo程序, 万用表测得各个模式中最低的耗电为0.066mA, 与手册上的掉电模式0.2uA相差太大, 请问需要怎样处理才能达到低于2uA的效果?
这是板子的原理图
没人吗? 在线等回答
您好,可以参考:https://bbs.21ic.com/icview-2892728-1-1.html
所有的IO口初始化了吗?可以参考EVT内的PM文件夹例子。
就是用的EVT内PM文件夹的例子
下边是原理图与电路板照片 ,红色部分的均已移除
最新版的官方例程, 21ic帖子里面的配置都已具备 //-------------------------------------------- //Main.c //-------------------------------------------- void DebugInit(void) { GPIOA_SetBits(GPIO_Pin_9); GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); UART1_DefInit(); } int main() { DelayMs(2); SetSysClock( CLK_SOURCE_HSE_32MHz ); // 设置外部32M做主频 GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); GPIOB_SetBits(GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14); /* 配置串口调试 */ DebugInit(); PRINT( "Start @ChipID=%02x\n", R8_CHIP_ID ); DelayMs(200); #if 1 /* 配置唤醒源为 GPIO - PA6&PA5 */ GPIOA_ModeCfg( GPIO_Pin_6|GPIO_Pin_5, GPIO_ModeIN_PU ); GPIOA_ITModeCfg( GPIO_Pin_6|GPIO_Pin_5, GPIO_ITMode_FallEdge ); // 下降沿唤醒 NVIC_EnableIRQ( GPIO_IRQn ); PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE ); #endif #if 1 PRINT( "IDLE mode sleep \n"); DelayMs(1); LowPower_Idle(); PRINT( "wake.. \n"); DelayMs(500); #endif #if 1 PRINT( "Halt_1 mode sleep \n"); DelayMs(1); LowPower_Halt_1(); /* 使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙 DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5) */ if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电 PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电 DelayUs((1200)/5); } else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源 DelayUs((1200-330)/5); } HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayUs(5/5); // 等待稳定 1-5us SetSysClock( CLK_SOURCE_HSE_32MHz ); PRINT( "wake.. \n"); DelayMs(500); #endif #if 1 PRINT( "Halt_2 mode sleep \n"); DelayMs(1); LowPower_Halt_2(); /* 使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙 DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5) */ if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电 PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电 DelayUs((1200)/5); } else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源 DelayUs((1200-330)/5); } HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayUs(5/5); // 等待稳定 1-5us SetSysClock( CLK_SOURCE_HSE_32MHz ); PRINT( "wake.. \n"); DelayMs(500); #endif #if 1 PRINT( "sleep mode sleep \n"); DelayMs(1); LowPower_Sleep( RB_PWR_RAM14K|RB_PWR_RAM2K ); //只保留14+2K SRAM 供电 /* 使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙 DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5) */ if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电 PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电 DelayUs((1200)/5); } else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源 DelayUs((1200-330)/5); } HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayUs(5/5); // 等待稳定 1-5us SetSysClock( CLK_SOURCE_HSE_32MHz ); PRINT( "wake.. \n"); DelayMs(500); #endif #if 1 PRINT( "shut down mode sleep \n"); DelayMs(1); LowPower_Shutdown( NULL ); //全部断电,唤醒后复位 /* 此模式唤醒后会执行复位,所以下面代码不会运行, 注意要确保系统睡下去再唤醒才是唤醒复位,否则有可能变成IDLE等级唤醒 */ /* 使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙 DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5) */ if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电 PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电 DelayUs((1200)/5); } else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源 DelayUs((1200-330)/5); } HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayUs(5/5); // 等待稳定 1-5us SetSysClock( CLK_SOURCE_HSE_32MHz ); PRINT( "wake.. \n"); DelayMs(500); #endif while(1); } void GPIO_IRQHandler(void) { GPIOA_ClearITFlagBit( GPIO_Pin_6|GPIO_Pin_5 ); } //-------------------------------------------- //ch57x_init.c //-------------------------------------------- /******************************************************************************* * Function Name : LowPower_Shutdown * Description : 低功耗-Shutdown模式。 此低功耗切到HSI/5时钟运行,唤醒后需要用户自己重新选择系统时钟源 注意调用此函数,DCDC功能强制关闭,唤醒后可以手动再次打开 * Input : rm: RB_PWR_RAM2K - 最后2K SRAM 供电 NULL - 以上单元都断电 * Return : None *******************************************************************************/ //__attribute__((section("NMICode"))) void LowPower_Shutdown( UINT8 rm ) { UINT8 x32Kpw, x32Mpw; x32Kpw = R8_XT32K_TUNE; x32Mpw = R8_XT32M_TUNE; x32Mpw = (x32Mpw&0xfc)|0x03; // 150%额定电流 if(R16_RTC_CNT_32K>0x3fff){ // 超过500ms x32Kpw = (x32Kpw&0xfc)|0x01; // LSE驱动电流降低到额定电流 } R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; R16_POWER_PLAN = RB_PWR_PLAN_EN \ |RB_PWR_MUST_0010 \ |rm; R8_SAFE_ACCESS_SIG = 0; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; R8_BAT_DET_CTRL = 0; // 关闭电压监控 R8_XT32K_TUNE = x32Kpw; R8_XT32M_TUNE = x32Mpw; R16_CLK_SYS_CFG = 5; // 降频 HSI/5=6.4M R8_SAFE_ACCESS_SIG = 0; SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk; //deep sleep __WFI(); R8_SAFE_ACCESS_SIG = 0; /* 开启电压监控 */ R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; R8_BAT_DET_CFG = 1; // 2.05V - 2.33V R8_BAT_DET_CTRL = RB_BAT_DET_EN; R8_SAFE_ACCESS_SIG = 0; __nop(); __nop(); R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; R8_BAT_DET_CTRL = RB_BAT_LOW_IE|RB_BAT_LOWER_IE|RB_BAT_DET_EN; R8_SAFE_ACCESS_SIG = 0; }
/////////////////////////////////////////////////////////
@zpf_wch 你好, 用刚刚你给的链接中的的demo程序, 依然是66uA的电流
CH579 芯片的GPIO的内部上下拉典型的电阻为50K,而你测出来是66uA,当3.3v供电时候,内部上下拉有一个电平不对,就是66uA.
由于该板子不是官方板子,我们这边无法掌握品控,不排除可能存在的硬件问题.
建议在休眠前,把PA,PB的port寄存器打印出来,看是否全都是0xffff,以确定是否由于板子硬件问题,导致上拉漏电.
感谢tech46, 经测量发现一个引脚为低电平(板子没有把此引进接地), 把这个引脚设置为高阻输入或下拉输入后, 电流变为10uA 。但是10uA仍然不是正常电流, 按手册应该是0.2uA 至少应该2uA一下的
已经降到0.2uA , 原来是板子上cpu引脚PA12与地短路了, 重新焊接cpu后此问题消失