完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、BLE睡眠模式
1、低功耗技术: 第一,它的广播频段和广播时射频开启时间的减少:传统蓝牙使用16~32个频段进行广播,而BLE仅使用3个广播频段;每次广播时的射频开启时间由传统蓝牙的22ms减少为0.6~1.2ms。一旦连接成功后,蓝牙低能耗技术就会切换到37个数据信道之一。在短暂的数据传送期间,无线信号将使用标准蓝牙技术倡导的自适应跳频(AFH)技术以伪随机的方式在信道间切换(虽然标准蓝牙技术使用79个数据信道); 第二,它每次只传输少量数据,传输速率是比较低的。因此适用于从微型无线传感器(每半秒交换一次数据)或使用完全异步通信的遥控器等其它外设传送数据; 第三,标准蓝牙技术使用的数据包长度较长。在发送这些较长的数据包时,无线设备必须在相对较高的功耗状态保持更长的时间,从而容易使硅片发热。这种发热将改变材料的物理特性,进而改变传送频率(中断链路),除非频繁地对无线设备进行再次校准。再次校准将消耗更多的功率(并且要求闭环架构,使得无线设备更加复杂,从而推高设备价格)。相反,蓝牙低功耗技术使用非常短的数据包——这能使硅片保持在低温状态。因此,蓝牙低功耗收发器不需要较耗能的再次校准和闭环架构,这也一定程度降低了功耗。 综合上面三个特点就决定了低功耗蓝牙相对传统蓝牙功耗更低,更节能。 举个例子,像视频传输、高质量音频传输或者传输大量数据的应用就不适合使用低功耗蓝牙;如传输小体量的数据,比如传输传感器的数据到我们的手机可以使用低功耗蓝牙。 2、开启睡眠模式 在Sleep模式时,睡眠函数相关库已经封装好,只需要调用相关函数即可,宏定义添加HAL_SLEEP,如图使用: 蓝牙保持连接和传输数据是通过主从机发包处理的,因此Sleep是基于此进行功耗的降低,即在需要发包处理时则唤醒,无事件处理时则睡眠。 如图可见,我们在开启睡眠模式后,当有箭头时为工作模式,即此时往外发包;空白时为睡眠模式。其具体功耗则为统计时间内所得到的面积大小。 3、降低功耗 上图已经显示出当前状态下芯片的功耗大小,如果需要继续调低,可以通过拉大连接间隔。拉大连接间隔的目的便是为了让蓝牙往外发包的频率降低,这便如同一个人在一分钟内做一个俯卧撑和在一分钟内做是个俯卧撑,做一个俯卧撑所做的功远远小于做十个俯卧撑,但是其效率也会相应的降低。同样蓝牙任务也是如此,连接间隔小可以实现透传速度快,连接间隔大则功耗较低。所以我们在进行蓝牙功耗降低时,一定要根据实际需求出发,而非功耗越低越好。 二、PM睡眠模式 上面我们所讲的是蓝牙的功耗处理,这里也许有人会有疑问:那么我将蓝牙的连接间隔拉大无限大,是不是功耗便无限低了,这当然不可以。蓝牙协议规范要求:BLE主机和BLE从机成功建立连接后,主机从机设备之间的交互频率(握手),其实际连接间隔时间为6~3200,单位是1.25ms。因此我们需要将连接间隔设置为上述范围。 那么一个573芯片在不使用蓝牙功能时,其最低功耗可以为多少呢?这里我们测量一下下电模式(Shutdown),相应的数据如图所示: 这里我们的芯片是贴在开发板上的,相应的功耗元器件还没有去除,这里测试出的3.76uA已满足大多数低功耗工作需求。 系统的睡眠模式总共有四种等级,分别为IDLE mode、Halt mode、sleep mode和Shutdown mode,我们的蓝牙睡眠模式默认为sleep模式,可根据实际需求作相应的修改。 芯片可以睡眠,那么也可以被唤醒。蓝牙可以通过TMOS任务的调度或者外部中断的方式进行唤醒。这里PM的睡眠唤醒也有两种方式,分别为RTC唤醒和外部中断唤醒。 RTC唤醒代码(包含基于RTC的万年历功能) int main() { uint16_t status = 0; SetSysClock(CLK_SOURCE_PLL_60MHz); DelayMs(50); GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU); GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU); GPIOB_ModeCfg(GPIO_Pin_10, GPIO_ModeOut_PP_5mA); //设置模式 输出 /* 配置串口调试 */ DebugInit(); PRINT("Start @ChipID=%02xn", R8_CHIP_ID); DelayMs(200); #if 1 /* 配置唤醒源为 GPIO - PB22 */ GPIOB_ModeCfg(GPIO_Pin_22, GPIO_ModeIN_PU); GPIOB_ITModeCfg(GPIO_Pin_22, GPIO_ITMode_FallEdge); // 下降沿唤醒 PFIC_EnableIRQ(GPIO_B_IRQn); PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Edge_LongDelay); #endif #if 1 LClk32K_Select(Clk32K_LSE);//启用外部32K R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; R8_CK32K_CONFIG |= RB_CLK_XT32K_PON; R8_SAFE_ACCESS_SIG = 0; status = R8_RESET_STATUS; if(((status & 0x07) == 0x01 )|| ((status & 0x07) == 0x03 )){ RTC_InitTime(2022,3,31,23,59,40); printf("Init RTC OKrn"); } if((status & 0x07) == 0x05 ){ printf("RB_RESET_FLAGn"); } RTC_TMRFunCfg(Period_1_S); // RTC_TRIGFunCfg(983040); PFIC_EnableIRQ(RTC_IRQn); PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_RTC_WAKE, Edge_LongDelay ); #endif #if 1 while(1){ // PRINT("Shut Downn"); DelayMs(2); LowPower_Shutdown(0); //全部断电,唤醒后复位 /* 此模式唤醒后会执行复位,所以下面代码不会运行, 注意要确保系统睡下去再唤醒才是唤醒复位,否则有可能变成IDLE等级唤醒 */ HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayMs(100); } #endif } void DebugInit(void) { GPIOA_SetBits(GPIO_Pin_9); GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); UART1_DefInit(); } __attribute__((interrupt("WCH-Interrupt-fast"))) __attribute__((section(".highcode"))) void GPIOB_IRQHandler(void) { GPIOB_ClearITFlagBit(GPIO_Pin_8); } __attribute__((interrupt("WCH-Interrupt-fast"))) __attribute__((section(".highcode"))) void RTC_IRQHandler(void) { UINT16 py; UINT16 pmon; UINT16 pd; UINT16 ph; UINT16 pm; UINT16 ps; RTC_GetTime(&py,&pmon,&pd,&ph,&pm,&ps); printf("%d年%d月%d日%d时%d分%d秒rn",py,pmon,pd,ph,pm,ps); RTC_ClearITFlag(RTC_TMR_EVENT); } |
|
|
|
只有小组成员才能发言,加入小组>>
482 浏览 1 评论
CH579M+RT-Thread,RTC从Sleep模式唤醒失败是什么原因?
2879 浏览 2 评论
2366 浏览 1 评论
821浏览 2评论
CH569通过HSPI实现USB3.0和FPGA高速双向通讯
654浏览 1评论
502浏览 1评论
CH32F103C8T6使用当前官网上的CDC例程会出现设备描述符请求失败
368浏览 1评论
645浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-30 01:53 , Processed in 1.011911 second(s), Total 47, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号