BlueNRG-1又要低功耗又要计时器怎么办?
[复制链接]
挑战赛里需要使用BlueNRG-1发送时间到手机,单位是毫秒 计时的我们一搬是通过定时器来实现,BlueNRG-1有2个multifunctions timers (MFT)和一个RTC定时器可供选择 低功耗方面BlueNRG-1有4种工作模式RUNNING、CPU_HALT、WAKETIMER和NOTIMER RUNNING为运行模式功耗最高,CPU_HALT模式下只有CPU停止工作,WAKETIMERT和NOTIMER模式下CPU和所有外设均停止工作(蓝牙除外) 不同的是WAKETIMERT在蓝牙处于广播或连接的时候可以使用一个叫VTimer的定时器唤醒 更多低功耗信息可以参考官方应用笔记AN4820: BlueNRG-1 and BlueNRG-2 low power modes http://www.st.com/content/ccc/resource/technical/document/application_note/group0/17/f2/d8/23/03/01/47/a9/DM00263007/files/DM00263007.pdf/jcr:content/translations/en.DM00263007.pdf 通常情况为了降低整体工作电流我们会在空闲时进入WAKETIMERT或NOTIMER模式,遗憾的是这两种模式下所有外设都被关闭,不仅仅关闭MFT,RTC定时器也无法正常工作 这时候定时工作只能考虑那个用于唤醒的VTimer定时器,还好这个定时器提供了很多我们想要的功能,在bluenrg1_stack.h头文件里有控制VTimer的函数 可以选择4个(0~3)用于唤醒BlueNRG-1的VTimer计数器,和传统定时器类似,超时唤醒在定时器设置的指定时间到达后被触发 例如我们可以设置VTimer分别间隔5s和7s被重复唤醒,同时还可以执行唤醒后的回调函数void HAL_VTimerTimeoutCallback(uint8_t timerNum); timerNum对应4个超时计数器的其中一个 intHAL_VTimerStart_ms(uint8_t timerNum, int32_t msRelTimeout);用于让VTimer定时器的timerNum计数器在msRelTimeout毫秒后唤醒BlueNRG-1 voidHAL_VTimer_Stop(uint8_t timerNum);用于关闭VTimer定时器的timerNum计数器的超时唤醒功能 有了超时唤醒我们可以在VTimerTimeoutCallback中断里对一个变量进行计数,例如1秒钟唤醒一次时计数单位为1秒 不过这会存在一个问题,超时时间设长了时间精度不够,设短了频繁唤醒会增加电流消耗 好在VTimer很够意思,除了超时唤醒它还提供更多我们想要的功能 函数uint32_t HAL_VTimerGetCurrentTime_sysT32(void);用来于返回VTimer计数器的当前计数数值 int32_tHAL_VTimerDiff_ms_sysT32(uint32_t sysTime1, uint32_t sysTime2);用于返回2个数值对应的时间差,单位为毫秒 我们可以在需要计时的时候通过HAL_VTimerGetCurrentTime_sysT32获得当前计数,保存然后在需要获得时间时再获得一次当前计数 然后通过HAL_VTimerDiff_ms_sysT32计数当前与第一次计数之间的时间差 HAL_VTimerDiff_ms_sysT32反回一个int32的数值 int32对应的值为-2147483648~2147483647 测试发现409.6个sysTime会对应1个毫秒,所以HAL_VTimerDiff_ms_sysT32最大可以返回不超过87.3分钟的时间差
|