华大HC32D391掉电模式使用分享
#申请原创#@21小跑堂 @21小跑堂 @21小跑堂 一、前言这两年进口的MCU都缺货的紧,要不就是价格涨的太吓人,ST的低功耗L系列还能买到,但是L系列的SRAM都普遍比较小,之前的项目NXP的MCU断货了,只能找一下国产替代。找代理推荐了华大的MCU,说是目前国产里面做的比较好的了,目前这种情况,申请样品肯定没什么指望了,自己买吧。立创上倒是有货,直接下单,选择了HC32D391FEUA-TFN32TR这一款。 二、学习时钟树搞到片子之后准备去官网下资料,发现这款没什么资料,咨询了一下原厂,说是这款就是HC32F460改了一下封装,内核都是一样的,好吧,那就当HC32F460来弄。首先学习时钟树,搞清楚了才能知道MCU处于一个什么状态,外部时钟就不考虑了,直接选择内部时钟,时钟树如下图: 使用内部振荡器初始化函数如下:/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void) //static { stc_clk_sysclk_cfg_t stcSysClkCfg; // stc_clk_xtal_cfg_t stcXtalCfg; /* 配置外部 Xtal */ // stc_clk_xtal32_cfg_t stcXtal32Cfg; /* 配置外部 Xtal32 */ stc_clk_mpll_cfg_t stcMpllCfg; stc_sram_config_t stcSramConfig; #ifdef USE_USB stc_clk_upll_cfg_t stcUpllCfg; #endif MEM_ZERO_STRUCT(stcSysClkCfg); // MEM_ZERO_STRUCT(stcXtalCfg); // MEM_ZERO_STRUCT(stcXtal32Cfg); MEM_ZERO_STRUCT(stcMpllCfg); MEM_ZERO_STRUCT(stcSramConfig); /* Set bus clk div. */ stcSysClkCfg.enHclkDiv = ClkSysclkDiv1; // 当前 128MHz,最大 168MHz stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;// 当前 64MHz,最大 84MHz stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;// 当前 128MHz,最大 168MHz stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;// 当前 64MHz,最大 84MHz stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;// 当前 32MHz,最大 60MHz stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;// 当前 32MHz,最大 42MHz stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;// 当前 64MHz,最大 84MHz CLK_SysClkConfig(&stcSysClkCfg); // /* XTAL的配置 */ // /* Use Xtal as MPLL source. */ // stcXtalCfg.enMode = ClkXtalModeOsc; // stcXtalCfg.enDrv = ClkXtalMidDrv; // stcXtalCfg.enFastStartup = Enable; // CLK_XtalConfig(&stcXtalCfg); // CLK_XtalCmd(Enable); /* 配置 HRC 经过 PLL 后作为系统时钟,而不是直接使用 HRC(HRC 是可以直接作为系统时钟) */ /* 1. 启动 HRC, MCU 启动后默认以 MRC 来工作,以下开始切换到 HRC */ CLK_HrcCmd(Enable); /* 根据手册,需要等待 HRC Ready 后才可以正常使用 */ while(Set != CLK_GetFlagStatus(ClkFlagHRCRdy)); /* 2. 设置 PLL 的时钟源为 HRC */ CLK_SetPllSource(ClkPllSrcHRC); /* 3. MPLL config (主晶振 / pllmDiv * plln / PllpDiv = 128M). */ stcMpllCfg.pllmDiv = 16ul; stcMpllCfg.plln = 256ul; stcMpllCfg.PllpDiv = 2ul; stcMpllCfg.PllqDiv = 8ul; stcMpllCfg.PllrDiv = 2ul; CLK_MpllConfig(&stcMpllCfg); /* Enable MPLL. */ CLK_MpllCmd(Enable); /* flash read wait cycle setting */ EFM_Unlock(); EFM_SetLatency(EFM_LATENCY_3); //??? EFM_Lock(); /* sram init include read/write wait cycle setting */ stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx; stcSramConfig.enSramRC = SramCycle2; stcSramConfig.enSramWC = SramCycle2; stcSramConfig.enSramEccMode = EccMode3; stcSramConfig.enSramEccOp = SramNmi; stcSramConfig.enSramPyOp = SramNmi; SRAM_Init(&stcSramConfig); /* Wait MPLL ready. */ while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy)); /* Switch system clock source to MPLL. */ CLK_SetSysClkSource(CLKSysSrcMPLL); #if (DDL_RTC_ENABLE == DDL_ON) // CLK_LrcCmd(Enable); //Enable LRC for RTC // /* RTC 用 xtal32 */ // stcXtal32Cfg.enFastStartup = Disable; // stcXtal32Cfg.enDrv = ClkXtal32HighDrv; // stcXtal32Cfg.enFilterMode = ClkXtal32FilterModeFull; // CLK_Xtal32Config(&stcXtal32Cfg); // /* Startup xtal32 */ // CLK_Xtal32Cmd(Enable); // /* wait for xtal32 running */ // Ddl_Delay1ms(3000u); #endif} 实际我调试时用到了MRC的8MHZ内部晶振,需要的同学可以参数上面的,是HRC倍频的初始化。 三、焊接最小系统,调试掉电模式功耗 在学习完时钟树后,就把之前画好的PCB打样,准备先做一个最小系统,使用内部时钟跑起来。原理图部分: 打样回来之后,焊了一块最小系统,准备先验证一下功耗是否能到达要求。飞线部分是调试串口,在调试一个没用过的新MCU的时候串口是少不了的,相当于我们的眼睛去看MCU运行状态,哈哈。 焊一个最小系统,来调试功耗,把外围器件都不要来测试功耗,如果功耗不能满足的话,接下来的工作就不用搞了。 四、跑例程,实测功耗PD1模式6ua,PD3模式2ua例程在下图位置, 直接跑官方的例程lpm_lpw,吐槽一下官方,唤醒的例程太少了,只有外部IO事件唤醒的例子,估计是给开发板上的按键做的,实际项目有可能没有按键,那就需要用定时器或者RTC的事件进行唤醒。不过大家有之前ST的经验,应该弄起来快,我之前常用的是飞思卡尔,一言难尽了。只能上网搜资料,我到处找资料发现这个用掉电模式的人真不多。HC32F460去做掉电模式资料基本没有,几个论坛上找最后也不知道有没有人解决这个问题。之前都是用中断唤醒,事件唤醒没接触过。后来找到别人的经验,事件唤醒掉电PowerDown模式,1. RTC配置还是按中断进行配置,也就是满足中断就是触发事件2. 触发事件就会唤醒MCU3. 程序直接复位,重新从0开始执行4. 不会进入RTC中断5. 可以用Ret_SRAM保存数据,复位后数据不会丢我在调试中厚着脸皮不停的问原厂FEA,人都挺好,基本上都帮忙回答了,哈哈。PD1就差不多够用了,PD3的话手册上面是这样写的,不能保证Ret_SRAM的数据了。 希望对大家有点帮助。补个图,哈哈!
实测电压值,可转换电流,待机7ua,PD1模式。
学习了,谢谢楼主分享。 哎哟,楼主有两下子啊 不错啊,国产替代是个漫长的路啊,还需国产厂家给力才是。 天意无罪 发表于 2022-4-25 08:03
不错啊,国产替代是个漫长的路啊,还需国产厂家给力才是。
是啊 低功耗L系列不好买了。 可以产生中断吗? HC32D391掉电模式效果怎么样 主要是降低外设的功耗,保存数据。 HC32D391这个是低功耗的模式吗
页:
[1]