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主时钟
}
经常性卡在低功耗定时器中断里边,或者这个函数里边
目前没有找到解决办法,看看有没有大佬遇到这种情况,或者有没有更好的解决办法
|
|