找回密码
 立即注册

微信扫码登录

查看: 38|回复: 1

[BLE SDK] BLE 825X 32K小晶振开启后引起定时器0/1外设产生的定时节拍变慢

[复制链接]

1

主题

1

回帖

9

积分

英勇黄铜

积分
9
发表于 昨天 10:33 | 显示全部楼层 |阅读模式 来自 广东深圳
Information
说明:   建议参照本版块置顶帖内容输入必要信息
芯片型号: 8250,8253,825x
SDK及版本: tc_ble_single_sdk-V3.4.2.7
825x的BLE 单链接SDK:
     最近采用8250芯片开发一个蓝牙温控器的项目, 利用定时器0,1在中断中产生一个10ms定时标志,在主循环中执行10ms的定时任务,同时需要睡眠唤醒。  调试时发现,当不开启32K RC或外部32K小时钟时, 主循环10ms的应用任务正常,不过无法执行睡眠唤醒操作。  但是如果开启32K小时钟(不管内部32K RC 或 外部32K 小晶振),定时器0/1产生的10ms中断的速度变慢,同时造成主循环10ms的应用任务执行节拍也会变慢,差不多慢10倍左右。        
   
下面为部分参考代码:

_attribute_ram_code_ int main (void)    //must run in ramcode
{
        DBG_CHN0_LOW;   //debug
        //blc_pm_select_internal_32k_crystal();                //此接口开启后,定时器0的运行感觉不正常,24M 的秒中断变成12秒左右
        blc_pm_select_external_32k_crystal();                       
        #if(MCU_CORE_TYPE == MCU_CORE_825x)
                cpu_wakeup_init();
        #else
                cpu_wakeup_init(LDO_MODE,INTERNAL_CAP_XTAL24M);
        #endif
        int deepRetWakeUp = pm_is_MCU_deepRetentionWakeup();  //MCU deep retention wakeUp
        clock_init(SYS_CLK_TYPE);                        //24MHz的系统节拍
        clock_32k_init(CLK_32K_XTAL);                //小晶振初始化
        rf_drv_ble_init();
        gpio_init(!deepRetWakeUp);  //analog resistance will keep available in deepSleep mode, so no need initialize again
        bsp_init();                //硬件初始化: 按键,温度采集的IO初始化
        if( deepRetWakeUp ){
                user_init_deepRetn();
        }
        else{
                user_init_normal();
                SetInterface(&itf_PowerOn);       
        }
        system_timerInit();//定时器初始化;
        systemFun_setSleepRemainTm(1000);        //设置系统允许睡眠的最小时间(应用),单位10ms,   即10秒后进入睡眠;
        bsp_debug_gpio_config();        //io口调试
        irq_enable();
        while (1) {
#if (MODULE_WATCHDOG_ENABLE && (MCU_CORE_TYPE != MCU_CORE_TC321X))
                wd_clear(); //clear watch dog
#endif
                main_loop();
                debug_gpio_toggle();
        }
}

//中断处理

_attribute_ram_code_ void irq_handler(void)
{
        irq_blt_sdk_handler();
        system_timerIrqPro(); //定时器中断
}


//系统定时器初始化
_Type_ramCode_ void  system_timerInit (void)
{
        timer1_set_mode(TIMER_MODE_SYSCLK,  0,  10 * DEF_CLOCK_SYS_CLOCK_1MS);        //定时器1产生10ms中断
        timer_start(TIMER1);

}
//系统定时器中断处理;
_Type_ramCode_ int  system_timerIrqPro (void)
{
        _Type_SleepRetenData_ static u8  s_timer = 0;
        _Type_SleepRetenData_ static u8  s_timer1 = 0;       
        if(reg_tmr_sta & FLD_TMR_STA_TMR1)
        {
                reg_tmr_sta = FLD_TMR_STA_TMR1;        //clear irq status
                g_strSysTimeFlags.flg10ms = 1;           //产生10ms节拍
                s_timer++;
                if(s_timer%5 == 0){
                        g_strSysTimeFlags.flg50ms = 1;
                }
                if(s_timer >= 10){
                        g_strSysTimeFlags.flg100ms = 1;
                        s_timer = 0;       
                }
                s_timer1++;
                if(s_timer1 >= 100){
                        g_strSysTimeFlags.flg1Sec = 1;
                        g_strSysTimeFlags.powerTimer++;
                        s_timer1 = 0;       
                }
        }
}

//主循环部分

_attribute_no_inline_ void main_loop(void)
{
        ////////////////////////////////////// BLE entry /////////////////////////////////
        blt_sdk_main_loop();
        ///////////////////////////////////// Battery Check ////////////////////////////////
        #if (APP_BATT_CHECK_ENABLE)
                if(battery_get_detect_enable() && clock_time_exceed(lowBattDet_tick, 5000000) ){        //执行电池电压检测,时间节拍正常;
                        lowBattDet_tick = clock_time();
                        user_battery_power_check(VBAT_DEEP_THRES_MV);
                }
        #endif
        //应用任务开始
        mainLoop_pro();
        if(systemTimer_getFlg10ms()){        //10ms任务处理
                timer_10ms_task();
        }
        if(systemTimer_getFlg1Sec()){        //1秒任务处理
                mainLoop_1Sectask();        //调试打印信息
        }
        ////////////////////////////////////// PM Process /////////////////////////////////
        //blt_pm_proc();                //睡眠唤醒处理放到10ms的任务处理中;
}


/* 本界面10ms定时任务,被10ms任务处理调用 */
static void Time10ms(void)
{
       ....
        readRoomTempPro();   //3) 房间温度处理;
        //4) 睡眠唤醒处理;
        if(check_can_sleep()){
                before_sleep(); // 休眠前的操作
                //执行睡眠
                tlkapi_printf(APP_LOG_EN, "cpu_sleep_wakeup...\n");
                //配置按键的低电平唤醒;
                bsp_key_gpio_wakeup_config();
                //设置睡眠唤醒的模式,如果存在定时唤醒,则采用定时的方式
                cpu_sleep_wakeup(DEEPSLEEP_MODE_RET_SRAM_LOW32K, PM_WAKEUP_TIMER|PM_WAKEUP_PAD, clock_time() + 15*CLOCK_16M_SYS_TIMER_CLK_1S);
                after_weakup(); // 唤醒后的操作
        }
}

/* ,被1秒的任务处理调用 */

void mainLoop_1Sectask(void)                       
{
        static   uint8_t  s_printTimer  = 0;
        s_printTimer++;
        if(s_printTimer>=3){
                tlkapi_printf(APP_LOG_EN, "systemTimer_getFlg1Sec,time:%d, sleepTm:%d...\n", systemTimer_getPowerTime(),systemFun_getSleepRemainTm()); //打印信息
                s_printTimer = 0;
                //bsp_mcu_reboot();        //测试重启
        }
}


调试串口打印日志信息(异常):

[10:15:51.767]收←◆systemTimer_getFlg1Sec,time:125, sleepTm:500...    //此为定时器1外设的10ms中断产生的节拍计时; 记录系统上电125秒,离睡眠剩下5000ms
[10:15:52.566]收←◆app_driver_sensor_start_sample()...
[10:15:53.432]收←◆result, temperature:262,humidity:562 ...
[10:15:55.875]收←◆[APP][BAT] The battery power is 2593mV!    //此为系统定时器产生的5秒电池检测,  系统定时器的节拍吻合;
[10:16:00.890]收←◆[APP][BAT] The battery power is 2594mV!
[10:16:05.890]收←◆[APP][BAT] The battery power is 2592mV!
[10:16:10.922]收←◆[APP][BAT] The battery power is 2592mV!
[10:16:15.937]收←◆[APP][BAT] The battery power is 2592mV!
[10:16:20.952]收←◆[APP][BAT] The battery power is 2592mV!
[10:16:22.468]收←◆systemTimer_getFlg1Sec,time:128, sleepTm:200... //此为定时器1外设的10ms中断产生的节拍计时; 记录系统上电128秒,离睡眠剩下2000ms, 实际31秒,但定时器1仅运行3秒
[10:16:25.983]收←◆[APP][BAT] The battery power is 2594mV!
[10:16:30.995]收←◆[APP][BAT] The battery power is 2595mV!
[10:16:36.030]收←◆[APP][BAT] The battery power is 2594mV!
[10:16:41.042]收←◆[APP][BAT] The battery power is 2593mV!
[10:16:42.740]收←◆cpu_sleep_wakeup...                                          //进入睡眠状态,  
[10:16:57.769]收←◆[APP][INI] user_init_deepRetn                            //15秒之后,唤醒了;  与设定的定时时间一致;
[APP][BAT] The battery power is 2597mV!
[10:17:02.784]收←◆[APP][BAT] The battery power is 2592mV!
[10:17:07.800]收←◆[APP][BAT] The battery power is 2593mV!


同时在调试中发现,在主循环中 屏蔽blt_sdk_main_loop()时, 10ms的节拍任务恢复正常。






48

主题

307

回帖

1141

积分

版主

积分
1141
发表于 2 小时前 | 显示全部楼层 来自 上海
需要使用soft timer去建立定时任务,让底层帮你做睡眠调度。直接调用cpu sleep会导致一些状态丢失
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Telink forum ( 沪ICP备17008231号-1 )

GMT+8, 2025-10-16 23:00 , Processed in 0.104962 second(s), 20 queries .

Powered by Telink 隐私政策

泰凌微电子版权所有 © 。保留所有权利。 2024

快速回复 返回顶部 返回列表