上一期我们介绍了如何在STM32WBA中实现低功耗蓝牙的服务特性功能并且利用软件定时器和任务通知实现当用户订阅,但是我们在测试阶段比较粗糙,采用的是一个递增数据来进行测试。
我们在使用的过程观察到,STM32WBA中有一个特殊的内置温度传感器:
STM32WBA的内置温度传感器无需外部元件即可直接监测芯片结温,这对于优化系统功耗管理、实现温度补偿或触发过热保护等应用至关重要,极大地增强了设备在各种环境下的可靠性和集成度。
STM32WBA内置的温度传感器一个至关重要的应用,是用于对其集成的2.4GHz射频收发器的晶振频率进行温度补偿。由于晶体振荡器的频率会随环境温度变化而发生漂移,这将直接导致射频载波频率偏差,从而削弱无线通信的链路质量和稳定性。STM32WBA可通过定期读取内部温度传感器的值,并依据预存的校准参数,动态调整射频系统的相关寄存器,对温度引起的频率误差进行实时补偿。这一机制能确保蓝牙或Zigbee等无线信号在整个工作温度范围内都保持极高的频率精度和稳定性。
本期我们就利用片内温度传感器和BLE功能实现一个BLE温度传感器。
1、蓝牙配置
首先我们沿用上一期工程,配置一个CubeMX的BLE工程,创建一个服务,其UUID为Health Thermometer用于健康检测。
添加一个特性选择Temperature Measurement标志着这个特性的功能是温度测量。
具体的BLE配置参考上一篇文章。
2、温度传感器设置
在ADC配置界面中,我们可以看到ADC有着一个Temperature Sensoor Channel选项代表着温度传感器通道,勾选这个选项就可以开启温度传感器的使用。
STM32WBA的转换时间有两种模式,我们设置其中一种为长周期,这里我选择SamplingTime Common2并为温度传感器通道配置方式二,即长时间转换。
同时,ADC的触发方式选择使用定时器1的触发信号2,这样子我们可以使用软件来触发定时器采样而不是通过调用HAL_ADC_Start函数来启动采样。
设置一个10ms的定时器来触发ADC通道采样(采样率好像有点高,也可以用软件定时器来触发采样)
3、代码修改
在 APP_Init函数中添加蓝牙广播代码,添加这个代码之后STM32WBA就可以对外开始广播低功耗蓝牙。
typedefstruct{TEST_APP_SendInformation_t Temm_Notification_Status;TEST_APP_SendInformation_t Temm_Indication_Status;/* USER CODE BEGIN Service1_APP_Context_t */UTIL_TIMER_Object_t UpDate_Id;/* USER CODE END Service1_APP_Context_t */uint16_t ConnectionHandle;} TEST_APP_Context_t;
在任务句柄中添加一个更新特征值任务。添加定时器句柄。
case TEST_TEMM_NOTIFY_ENABLED_EVT:/* USER CODE BEGIN Service1Char1_NOTIFY_ENABLED_EVT */HAL_ADC_Start_DMA(&hadc4,(uint32_t *)ADC_Value,1);HAL_TIM_Base_Start(&htim1);UTIL_TIMER_Start(&(TEST_APP_Context.UpDate_Id));/* USER CODE END Service1Char1_NOTIFY_ENABLED_EVT */break;case TEST_TEMM_NOTIFY_DISABLED_EVT:/* USER CODE BEGIN Service1Char1_NOTIFY_DISABLED_EVT */HAL_TIM_Base_Stop(&htim1);UTIL_TIMER_Stop(&(TEST_APP_Context.UpDate_Id));/* USER CODE END Service1Char1_NOTIFY_DISABLED_EVT */break;
接收到订阅之后,单片机开启定时器触发采样并开启软件定时器定期上传。
取消订阅后,单片机关闭定时器采样并关闭通知。
voidUpdate_Timer_Callback(void * arg){UTIL_SEQ_SetTask(1 << CFG_TASK_UPDATE_MEAS_REQ_ID, CFG_SEQ_PRIO_1);}uint16_t value;voidUPDATE_REQ(void){local_data[1] = (uint8_t)(ADC_Value[0] & 0xFF);local_data[0] = (uint8_t)((ADC_Value[0]>>8) & 0xFF);msg_conf.p_Payload = local_data;msg_conf.Length = 2;TEST_UpdateValue(TEST_TEMM, &msg_conf);HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);}
软件定时器以0.25s触发回调函数上传温度值。
4、数值计算
STM32WBA提供了两个地址,分别用来存放30℃时候的温度传感器读书和130℃时候的温度传感器读数。
constint CAL1 = 0x03FF;constint CAL2 = 0x0546;constint T_CAL1 = 30; // 30 °Cconstint T_CAL2 = 130; // 130 °
这里我分别读取了这个两个地址的数据,并根据公式计算实际的温度数据。
5、APP测试
可以看到随着手放在芯片上,其温度也在缓慢上升,证明温度传感器的可用性。
1881