CH573 CH582 CH579 peripheral通用外设例子讲解二 HAL SLEEP控制逻辑
peripheral 怎么实现BLE所说的低功耗,下面进行功能讲解
程序烧写进EVT测试板,运行结果和电流测试截图如下
启动后,广播并且受到主机的扫描(打印受到扫描广播包的主机的mac地址),广播间隔设置的是50ms
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms) #define DEFAULT_ADVERTISING_INTERVAL 80 uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL; // Set advertising interval 设置广播间隔 GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt); GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
uint8_t initial_advertising_enable = TRUE; //使能/关闭广播,第三个参数1使能广播,为0则关闭广播 GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
从运行功率来看,下图的电流尖峰是无线收发的电流,尖峰间隔50ms,跟设置的50ms广播间隔是一致的,电流的谷值约为7mA左右(运行电流+1mA(EVT板上的LED红色灯珠))
开启HAL SLEEP后,对比上图可以发现,峰值电流没有变化,谷值电流有7mA降低到1.5mA左右(1mA的LED灯珠电流)
如果仔细观察,会发现原来间隔50ms变成了46ms,因为在系统空闲时,会调用,这个函数里面睡眠启动2段睡眠,先sleep模式,再idle模式,到正常工作,因为sleep模式直接到工作模式,要5ms左右的晶振稳定时间,但是idle到工作模式,几百us就足够
* @param time - 唤醒的时间点(RTC绝对值) * * @return state. */ uint32_t CH58X_LowPower(uint32_t time) { #if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE) uint32_t tmp, irq_status; SYS_DisableAllIrq(&irq_status); tmp = RTC_GetCycle32k(); if((time < tmp) || ((time - tmp) < 30)) { // 检测睡眠的最短时间 SYS_RecoverIrq(irq_status); return 2; } RTC_SetTignTime(time); SYS_RecoverIrq(irq_status); #if(DEBUG == Debug_UART1) // 使用其他串口输出打印信息需要修改这行代码 while((R8_UART1_LSR & RB_LSR_TX_ALL_EMP) == 0) { __nop(); } #endif // LOW POWER-sleep模式 if(!RTCTigFlag) { LowPower_Sleep(RB_PWR_RAM2K | RB_PWR_RAM30K | RB_PWR_EXTEND); if(RTCTigFlag) // 注意如果使用了RTC以外的唤醒方式,需要注意此时32M晶振未稳定 { time += WAKE_UP_RTC_MAX_TIME; if(time > 0xA8C00000) { time -= 0xA8C00000; } RTC_SetTignTime(time); LowPower_Idle(); } HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流) } else { return 3; } #endif return 0; }
睡眠控制的逻辑是开启HAL SLEEP后Tmos会循环调用 CH58X_LowPower 函数,进到函数以后,会先进行参数判断,输入参数是RTC唤醒的绝对时间。
如果不想睡眠,可以在执行 睡眠函数前,直接return