打印
[技术问答]

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

[复制链接]
1122|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于华大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_Rcl  LPUart_Pclk
#define LUART_RX_SCLK_DIV      LPUartDiv1

//Luart_mode_config         //LPUartLPMode  LPUartNoLPMode
#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_t  stcConfig;
   stc_lpuart_irq_cb_t  stcLPUartIrqCb;
   stc_lpuart_multimode_t  stcMulti;
   stc_lpuart_sclk_sel_t  stcLpuart_clk;
   stc_lpuart_mode_t  stcRunMode;
   stc_lpuart_baud_config_t  stcBaud;
   stc_bt_config_t  stcBtConfig;

   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_t  stcConfig;
    stc_lpuart_irq_cb_t stcLPUartIrqCb;
    stc_lpuart_multimode_t stcMulti;
    stc_lpuart_sclk_sel_t  stcLpuart_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[0] == 0x55)&&(u8RxData[1] == 0x44)&&(u8RxData[2] == 0x33)&&(u8RxData[3] == 0x22)&&(u8RxData[4] == 0x11))
       {
            u8RxCnt = 0;
            Gpio_SetIO(0,3,0);
       }

    }
}


使用特权

评论回复
地板
martinhu| | 2020-4-8 19:02 | 只看该作者
例程哪里把Rx设置为输出了?这段才是Rx的功能配置,上面那个只是IO的初始化,


使用特权

评论回复
5
jiangshaoling| | 2020-4-9 09:50 | 只看该作者
华大代理 有技术团队 可提供服务 联系方式15323794243微信同号

使用特权

评论回复
6
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过来的呀

使用特权

评论回复
7
huaxiauolu|  楼主 | 2020-4-10 09:12 | 只看该作者
martinhu 发表于 2020-4-8 19:02
例程哪里把Rx设置为输出了?这段才是Rx的功能配置,上面那个只是IO的初始化,

可以了,谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

9

帖子

0

粉丝