完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 MMCU5721167 于 2020-1-15 13:41 编辑 在上一章节,我们了解了MM32W0系列蓝牙模块的软件架构,下面我们来看一下低功耗模式下用到的休眠和时钟配置函数。 目前MM32W0系列有n4和q1两个版本,n4主要针对需要大容量的应用方案,q1针对超低功耗精简型的应用方案,两个型号的低功耗编程操作方式相同,不同的只是MCU的时钟系统控制方式,在参考程序已经提供不同的模式下功能,用户只要改变相对应的宏定义即可实现对应的低功耗功能。 休眠函数 对于低功耗应用来说,休眠是非常关键的一个功能。开启蓝牙广播时MM32W0的控制模块有三种工作模式:正常模式、睡眠模式和停机模式。在stop模式下,射频模块都会通过IRQ引脚定时触发一个外部中断,可以借此唤醒STOP模式中的控制模块。 在阻塞模式中,休眠是蓝牙服务通过调用void McuGotoSleepAndWakeup(void) 函数实现的,对于中断模式,则是用户在代码中主动调用IrqMcuGotoSleepAndWakeup()函数来实现。 void McuGotoSleepAndWakeup(void) // auto goto sleep AND wakeup, porting api { if ((SleepStop)&& //开启休眠功能 (TxTimeout < SysTick_Count)&& (RxTimeout < SysTick_Count)) //UART无收发数据 { if(SleepStop == 1){ //SLEEP SCB->SCR &= 0xfb; __WFE(); }else{ //STOP SysClk48to8(); //HSI 6分频 SCB->SCR |= 0x4; __WFI(); //进入STOP模式 RCC->CR|=RCC_CR_HSION; //从STOP模式唤醒,使能时钟 SysClk8to48(); //PLL倍频至48MHz } } } void IrqMcuGotoSleepAndWakeup(void) // auto goto sleep AND wakeup, porting api { if(ble_run_interrupt_McuCanSleep() == 0) return; #ifdef USE_UART if ((SleepStop)&& (TxTimeout < SysTick_Count)&& (RxTimeout < SysTick_Count)) { if(SleepStop == 1){ //sleep SleepStatus = 1; SCB->SCR &= 0xfb; __WFE(); //控制模块进入睡眠模式 }else{ //stop SleepStatus = 2; SysClk8M(); SCB->SCR |= 0x4; SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; __WFI(); } } #endif } 在中断方式中,需要在中断处理函数中重新配置时钟: void EXTI4_15_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line8); if(2 == SleepStatus){ //stop RCC->CR|=RCC_CR_HSION; //HSI使能 RCC->CR |= RCC_CR_PLLON; //PLL使能 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; SysTick_Config(48000); } SleepStatus = 0; ble_run(0); } 时钟配置 进入低功耗前后需要配置时钟,从低功耗模式恢复时,时钟默认设置为HSI6分频,需要重新配置系统时钟。 注意:下面函数属于蓝牙库接口,没有用到也不要删除。 相关时钟配置: void SysClk48to8(void)1 { RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//selecting PLL clock as sys clock while (RCC_GetSYSCLKSource() != 0x0) {} RCC->CR &=~(RCC_CR_PLLON); //clear PLL SysTick_Config(8000); } void SysClk8to48(void) //从STOP模式中恢复 { SetSysClock_HSI(4);//HSI:12*4=48M RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//selecting PLL clock as sys clock while (RCC_GetSYSCLKSource() != 0x08) {} SysTick_Config(48000); } void SetSysClock_HSI(u8 PLL) //重新配置HSI和PLL { unsigned char temp=0; RCC->CR|=RCC_CR_HSION; while(!(RCC->CR&RCC_CR_HSIRDY)); RCC->CFGR=RCC_CFGR_PPRE1_2; //APB1=DIV2;APB2=DIV1;AHB=DIV1; RCC->CFGR&=~RCC_CFGR_PLLSRC; //PLLSRC ON RCC->CR &=~(RCC_CR_PLLON); RCC->CR &=~(0x1f<<26); //clear PLL RCC->CR|=(PLL - 1) << 26; //setting PLL value 2~16 FLASH->ACR=FLASH_ACR_LATENCY_1|FLASH_ACR_PRFTBE; //FLASH 2 delay clk cycles RCC->CR|=RCC_CR_PLLON; //PLLON while(!(RCC->CR&RCC_CR_PLLRDY));//waiting for PLL locked RCC->CFGR&=~RCC_CFGR_SW; RCC->CFGR|=RCC_CFGR_SW_PLL;//PLL to be the sys clock while(temp!=0x02) //waiting PLL become the sys clock { temp=RCC->CFGR>>2; temp&=0x03; } } 以上时钟配置只是针对MM32W0系列的n4版本,在q1版不需要以上时钟操作。MM32W051PFB(q1)蓝牙功耗参数: |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2253个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11839 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5980 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11126 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4598 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4333 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1326浏览 1评论
857浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 00:09 , Processed in 0.611560 second(s), Total 55, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号