打印
[技术问答]

38.4k低速运行切换主频时钟到4M,很容易卡在定时器中断处,应该怎么解决呢?hc32l110

[复制链接]
58|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
38.4k低速运行切换主频时钟到4M,很容易卡在定时器中断处,应该怎么解决呢?hc32l110


代码配置如下

int32_t main(void)
{   
    uint8_t falg=0;
                uint8_t i = 0;
                uint8_t txLen = 0;
          volatile uint8_t u8TestFlag = 0;

    uint8_t arr[5]={1,2,3,4,5};
       
    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;
          stc_wdt_config_t  stcWdt_Config;


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


    Clk_Enable(ClkRCL, TRUE);

    Clk_SetRCLFreq(ClkFreq38_4K);//内部38.4K   ClkFreq32768  ClkFreq38_4K
        Clk_SwitchTo(ClkRCL);//使用rcl做主时钟,串口9600唤醒有问题,300波特率可以接收完整数据唤醒




//看门狗配置
    stcWdt_Config.u8LoadValue = 0x0b;//3.2s
    stcWdt_Config.enResetEnable = WINT_EN;//WRESET_EN;////
    stcWdt_Config.pfnWdtIrqCb = WdtCallback;//
               
                Clk_SetPeripheralGate(ClkPeripheralWdt,TRUE);//
                Wdt_Init(&stcWdt_Config);
                Wdt_Start();
               
//LpTimer配置
    LptTimerTest();

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

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

    Gpio_SetFunc_UART2RX_P25();
    Gpio_SetFunc_UART2TX_P26();


                stcLpuart_clk.enSclk_sel = LPUart_Rcl;//LPUart_Pclk   LPUart_Rcl

    stcLpuart_clk.enSclk_Prs = LPUartDiv32;//Div:1-9600,32-300bps,4-2400bps
    stcConfig.pstcLpuart_clk = &stcLpuart_clk;

    stcRunMode.enLpMode = LPUartLPMode;//正常工作模式或低功耗工作模式配置,Baud = fclk/(prescale*4)
    stcRunMode.enMode   = LPUartMode1;//LPUartMode3
    stcConfig.pstcRunMode = &stcRunMode;

    stcLPUartIrqCb.pfnRxIrqCb = bspLPUuart_RxIntCallback;//RxIntCallback  bspLPUuart_RxIntCallback
    stcLPUartIrqCb.pfnTxIrqCb = NULL;
    stcLPUartIrqCb.pfnRxErrIrqCb = NULL;
    stcConfig.pstcIrqCb = &stcLPUartIrqCb;
    stcConfig.bTouchNvic = TRUE;

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

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

                for(txLen=0;txLen<sizeof(u8TxData);txLen++)
                {
                        LPUart_SendData(u8TxData[txLen]);
                }



    LPUart_EnableFunc(LPUartRx);               


    for (i = 0; i < ARRAY_SZ(gGpiolist); i++)
    {
        Gpio_InitIOExt(gGpiolist.u8Port,
        gGpiolist.u8Pin,
        GpioDirIn, TRUE, FALSE, FALSE, FALSE);
    }
               


                delay1ms(2500);
                //Gpio_SetIO(0,3,0);



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

    Lpm_Config(&stcLpmCfg);


//    change_clock();
//    Gpio_InitIO(0,3,GpioDirOut);
//                SCB->SCR |= 0x4;       //sleepdeep
//    __NOP();
//    __NOP();
//    __NOP();
//    __NOP();
//    __NOP();


//    Lpm_GotoLpmMode();
#endif   
    while (1)
    {

      Wdt_Feed();


    }
}


en_result_t LptTimerTest(void)
{
    stc_lpt_config_t stcConfig;
    //en_result_t      enResult = Error;
    //uint16_t         u16ArrData = 0;//这个是初始值,就算从这个值计时到0xffff

    stc_lpm_config_t stcLpmCfg;

  Clk_SetPeripheralGate(ClkPeripheralLpTim, TRUE);

    stcConfig.enGateP  = LptPositive; //高电平有效
    stcConfig.enGate   = LptGateDisable;//无门控
    stcConfig.enTckSel = LptIRC32K;//时钟选择
    stcConfig.enTog    = LptTogDisable;
    stcConfig.enCT     = LptTimer;//定时器功能
    stcConfig.enMD     = LptMode2;//模式2

    stcConfig.pfnLpTimCb = LptInt;//中断函数配置
    Lpt_Init(&stcConfig);
//    if (Ok != Lpt_Init(&stcConfig))
//    {
//        //enResult = Error;
//    }

    //Lpm Cfg低功耗配置
    stcLpmCfg.enSEVONPEND   = Se***dDisable;
    stcLpmCfg.enSLEEPDEEP   = SlpDpEnable;
    stcLpmCfg.enSLEEPONEXIT = SlpExtDisable;
    Lpm_Config(&stcLpmCfg);

    //Lpt 中断使能
    M0P_LPTIMER->ICLR_f.TFC = FALSE;//Lpt_ClearIntFlag();
    M0P_LPTIMER->CR_f.IE = TRUE;//Lpt_EnableIrq();
    EnableNvic(LPTIM_IRQn, 3, TRUE);


    //设置重载值,计数初值,启动计数
    Lpt_ARRSet(0xffff-387);//32k

    M0P_LPTIMER->CR_f.TR = TRUE;//Lpt_Run();

    ccccaaaa=Clk_GetPClkFreq();//获得PCLK



    return 1;
}



切换的步骤是这样的,先从38.4k切换到4M,再由4M切换到38.4k,这样子操作

切换4M的操作:
     Lpt_ClearIntFlag();
      M0P_LPTIMER->CR_f.IE = FALSE;
     change_clock();
      LptTimerTest();               


void change_clock(void)
{

    Clk_Enable(ClkRCH, TRUE);
    Clk_SetRCHFreq(ClkFreq4Mhz);

    while(0==Clk_GetClkRdy(ClkRCH))
    {
      delay1ms(1);
    };

    Clk_Enable(ClkRCL, FALSE);      // 关闭RCL
    Clk_SwitchTo(ClkRCH);           // 切换到RCH主时钟


}


切换38.4k的操作
Lpt_ClearIntFlag();
      M0P_LPTIMER->CR_f.IE = FALSE;
     change_low();
      LptTimerTest();



void change_low(void)
{

    Clk_Enable(ClkRCL, TRUE);
    Clk_SetRCLFreq(ClkFreq38_4K);

    while(0==Clk_GetClkRdy(ClkRCL))
    {
      delay1ms(1);
    };

    Clk_Enable(ClkRCH, FALSE);      // 关闭RCL
    Clk_SwitchTo(ClkRCL);           // 切换到RCH主时钟

}


经常性卡在低功耗定时器中断里边,或者这个函数里边



目前没有找到解决办法,看看有没有大佬遇到这种情况,或者有没有更好的解决办法

使用特权

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

本版积分规则

5

主题

13

帖子

0

粉丝