huaxiauolu 发表于 2020-4-8 15:14

HC32L110的LPUART配置后睡眠无法达到睡眠功耗

关于华大HC32L110的LPUART配置,参考手册上说可以在低功耗模式下工作,我这边打开串口后睡眠一直很高大概100ua,但是屏蔽串口初始化就可以达到7ua左右,不知道串口配置这边有什么问题?

/***********************************Lpuart_config************************/
//RX
#define LUART_RX_PORT       2
#define LUART_RX_PIN      5
#define LUART_RX_MODE       GpioDirOut
#define LUART_RX_PULLUP   TRUE
#define LUART_RX_PULLDOWN   FALSE
#define LUART_RX_ODR      FALSE      
#define LUART_RX_DRIVER   FALSE

//Luart_clk_config
#define LUART_RX_SCLK_SEL      LPUart_Rcl       //LPUart_RclLPUart_Pclk
#define LUART_RX_SCLK_DIV      LPUartDiv1

//Luart_mode_config         //LPUartLPModeLPUartNoLPMode
#define LUART_RX_MODE_LP       LPUartLPMode   //低功耗模式(说明默认配置串口波特率:9600(由时钟决定的不可改变))
#define LUART_RXMODE         LPUartMode1      //带奇偶校验功能(MODE1是不带奇偶检验功能)

//tx
#define LUART_TX_PORT       2
#define LUART_TX_PIN      6
#define LUART_TX_MODE       GpioDirOut
#define LUART_TX_PULLUP   TRUE
#define LUART_TX_PULLDOWN   FALSE
#define LUART_TX_ODR      FALSE
#define LUART_TX_DRIVER   FALSE

//Luart_clk_config
//#define LUART_TX_SCLK_SEL      LPUart_Pclk      
//#define LUART_TX_SCLK_DIV      LPUartDiv1

//Luart_mode_config         
//#define LUART_TX_MODE_LP       LPUartNoLPMode    //低功耗模式(说明默认配置串口波特率:9600(由时钟决定的不可改变))
//#define LUART_TXMODE          LPUartMode3       //带奇偶校验功能(MODE1是不带奇偶检验功能)


#define LUART_BAUD          9600
/***********************************************************************/


void lpuart_pwr_on(void)
{   

   uint16_t u16timer;
   uint32_t u32sclk;

   stc_lpuart_config_tstcConfig;
   stc_lpuart_irq_cb_tstcLPUartIrqCb;
   stc_lpuart_multimode_tstcMulti;
   stc_lpuart_sclk_sel_tstcLpuart_clk;
   stc_lpuart_mode_tstcRunMode;
   stc_lpuart_baud_config_tstcBaud;
   stc_bt_config_tstcBtConfig;

   DDL_ZERO_STRUCT(stcConfig);
   DDL_ZERO_STRUCT(stcLPUartIrqCb);
   DDL_ZERO_STRUCT(stcMulti);
   DDL_ZERO_STRUCT(stcLpuart_clk);
   DDL_ZERO_STRUCT(stcRunMode);
   DDL_ZERO_STRUCT(stcBaud);
   DDL_ZERO_STRUCT(stcBtConfig);


   //(1)open peripheral clk
   Clk_SetPeripheralGate(ClkPeripheralLpUart,TRUE);
   Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);

   //(2)set IO
   Gpio_InitIOExt(LUART_RX_PORT,LUART_RX_PIN,LUART_RX_MODE,LUART_RX_PULLUP,LUART_RX_PULLDOWN,LUART_RX_ODR,LUART_RX_DRIVER);   
   Gpio_InitIOExt(LUART_TX_PORT,LUART_TX_PIN,LUART_TX_MODE,LUART_TX_PULLUP,LUART_TX_PULLDOWN,LUART_TX_ODR,LUART_TX_DRIVER);

   Gpio_SetFunc_UART2RX_P25();
   Gpio_SetFunc_UART2TX_P26();


   //(3)clk config
   stcLpuart_clk.enSclk_Prs = LUART_RX_SCLK_DIV;
   stcLpuart_clk.enSclk_sel = LUART_RX_SCLK_SEL;
   stcConfig.pstcLpuart_clk = &stcLpuart_clk;

   //(4)mode config
   stcRunMode.enLpMode = LUART_RX_MODE_LP;
   stcRunMode.enMode   = LUART_RXMODE;
   stcConfig.pstcRunMode = &stcRunMode;

   //(5)interrupt function
   stcLPUartIrqCb.pfnRxIrqCb = RxIntCallback;
   stcLPUartIrqCb.pfnTxIrqCb = NULL;
   stcLPUartIrqCb.pfnRxErrIrqCb = NULL;
   stcConfig.pstcIrqCb = &stcLPUartIrqCb;
   stcConfig.bTouchNvic = TRUE;      

   //(6)正常模式
   stcMulti.enMulti_mode = LPUartNormal;
   stcConfig.pstcMultiMode = &stcMulti;
         
         
   LPUart_EnableFunc(LPUartRx);
         M0P_LPUART->ISR_f.RI = 0;
      
   LPUart_EnableIrq(LPUartRxIrq);
   LPUart_Init(&stcConfig);

//(1)
if(LPUart_Pclk == stcLpuart_clk.enSclk_sel)
      u32sclk = Clk_GetPClkFreq();
else if(LPUart_Rcl == stcLpuart_clk.enSclk_sel)
      u32sclk = 38400;
else
      u32sclk = 32768;
            
stcBaud.u32Baud = LUART_BAUD;
stcBaud.bDbaud = 0;
stcBaud.u8LpMode = LUART_RX_MODE_LP;
stcBaud.u8Mode = LUART_RXMODE;

LPUart_EnableIrq(LPUartRxIrq);
      LPUart_EnableFunc(LPUartRx);
         
u16timer = LPUart_SetBaudRate(u32sclk,stcLpuart_clk.enSclk_Prs,&stcBaud);
stcBtConfig.enMD = BtMode2;
stcBtConfig.enCT = BtTimer;
stcBtConfig.enTog = BtTogEnable;
Bt_Init(TIM2, &stcBtConfig);
Bt_ARRSet(TIM2,u16timer);
Bt_Cnt16Set(TIM2,u16timer);
Bt_Run(TIM2);

}


我这边main函数是:
int main(void)
{
delay1ms(3000);   //延时避免睡眠无法烧录。
Allgpio_Init();
Led_init_task();
key_init_task();
lpuart_pwr_on();

while(1)
{
      keyL_scan();      
      Real_exe();                                                                                                      
      Mcu_Sleep();

}
}

martinhu 发表于 2020-4-8 16:50

lpuart如果要在deepsleep下正常接收,需要使用低速时钟作为时钟源,而不是PCLK。
关于引脚配置,Rx应该是输入,而不是输出,好像Tx Rx也不用设置上拉
这个功能在驱动库的例子里面都有的吧
另外,如果想要功耗更低,需要把悬空的引脚配置为输入上拉。

huaxiauolu 发表于 2020-4-8 18:10

martinhu 发表于 2020-4-8 16:50
lpuart如果要在deepsleep下正常接收,需要使用低速时钟作为时钟源,而不是PCLK。
关于引脚配置,Rx应该是输 ...

有啊,但是例程都要RX TX设置成输出,冤枉啊!!!(请问有你的联系方式吗,方便请教你问题,谢谢),目前将IO设置输出函数删除已经降到27ua,继续排查问题,谢谢!!


//lpuart_lpmode 例程
int32_t main(void)
{   

    stc_lpuart_config_tstcConfig;
    stc_lpuart_irq_cb_t stcLPUartIrqCb;
    stc_lpuart_multimode_t stcMulti;
    stc_lpuart_sclk_sel_tstcLpuart_clk;
    stc_lpuart_mode_t       stcRunMode;

    stc_bt_config_t stcBtConfig;
    stc_lpm_config_t stcLpmCfg;

    DDL_ZERO_STRUCT(stcConfig);
    DDL_ZERO_STRUCT(stcLPUartIrqCb);
    DDL_ZERO_STRUCT(stcMulti);
    DDL_ZERO_STRUCT(stcBtConfig);
    DDL_ZERO_STRUCT(stcLpmCfg);


    stcLpmCfg.enSLEEPDEEP = SlpDpEnable;//SlpDpDisable;//
    stcLpmCfg.enSLEEPONEXIT = SlpExtDisable;//唤醒后不自动进入睡眠

    Clk_Enable(ClkRCL, TRUE);
    Clk_SetRCLFreq(ClkFreq38_4K);//内部38.4K

    Clk_SetPeripheralGate(ClkPeripheralLpUart,TRUE);//使能LPUART时钟
    Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);

    //通道端口配置
    Gpio_InitIOExt(2,5,GpioDirOut,TRUE,FALSE,FALSE,FALSE);
    Gpio_InitIOExt(2,6,GpioDirOut,TRUE,FALSE,FALSE,FALSE);

    Gpio_SetFunc_UART2RX_P25();
    Gpio_SetFunc_UART2TX_P26();

    Gpio_InitIO(T1_PORT,T1_PIN,GpioDirIn);
    Gpio_InitIO(0,3,GpioDirOut);


    stcLpuart_clk.enSclk_sel = LPUart_Rcl;//LPUart_Pclk;//

    stcLpuart_clk.enSclk_Prs = LPUartDiv1;
    stcConfig.pstcLpuart_clk = &stcLpuart_clk;

    stcRunMode.enLpMode = LPUartLPMode;//正常工作模式或低功耗工作模式配置
    stcRunMode.enMode   = LPUartMode3;
    stcConfig.pstcRunMode = &stcRunMode;

    stcLPUartIrqCb.pfnRxIrqCb = RxIntCallback;
    stcLPUartIrqCb.pfnTxIrqCb = TxIntCallback;
    stcLPUartIrqCb.pfnRxErrIrqCb = ErrIntCallback;
    stcConfig.pstcIrqCb = &stcLPUartIrqCb;
    stcConfig.bTouchNvic = TRUE;

    stcMulti.enMulti_mode = LPUartNormal;//只有模式2/3才有多主机模式

    stcConfig.pstcMultiMode = &stcMulti;
    LPUart_EnableIrq(LPUartRxIrq);
    LPUart_Init(&stcConfig);

    LPUart_EnableFunc(LPUartRx);
    Gpio_SetIO(0,3,1);
#if 1
    while(1 == Gpio_GetIO(T1_PORT,T1_PIN));//注意:此处用户不能屏蔽,否则进入深度休眠模式导致SWD连接不上
    Lpm_Config(&stcLpmCfg);
    Lpm_GotoLpmMode();
#endif   
    while (1)
    {

       if((u8RxData == 0x55)&&(u8RxData == 0x44)&&(u8RxData == 0x33)&&(u8RxData == 0x22)&&(u8RxData == 0x11))
       {
            u8RxCnt = 0;
            Gpio_SetIO(0,3,0);
       }

    }
}


martinhu 发表于 2020-4-8 19:02

例程哪里把Rx设置为输出了?这段才是Rx的功能配置,上面那个只是IO的初始化,


jiangshaoling 发表于 2020-4-9 09:50

华大代理 有技术团队 可提供服务 联系方式15323794243微信同号

huaxiauolu 发表于 2020-4-9 09:51

martinhu 发表于 2020-4-8 19:02
例程哪里把Rx设置为输出了?这段才是Rx的功能配置,上面那个只是IO的初始化,




    //通道端口配置
    Gpio_InitIOExt(2,5,GpioDirOut,TRUE,FALSE,FALSE,FALSE);
    Gpio_InitIOExt(2,6,GpioDirOut,TRUE,FALSE,FALSE,FALSE);

    这个不是设置成了输出上拉吗,关键是我之前发出来的code就是从例程copy过来的呀

huaxiauolu 发表于 2020-4-10 09:12

martinhu 发表于 2020-4-8 19:02
例程哪里把Rx设置为输出了?这段才是Rx的功能配置,上面那个只是IO的初始化,




可以了,谢谢
页: [1]
查看完整版本: HC32L110的LPUART配置后睡眠无法达到睡眠功耗