1. 硬件选型与电路设计STM32F103C8T6作为性价比极高的Cortex-M3内核微控制器搭配HC05蓝牙模块的方案特别适合物联网数据透传场景。我在实际项目中验证过这套组合的成本可以控制在50元以内但性能完全能满足大多数传感器数据采集需求。核心硬件参数对比表模块关键参数典型应用场景STM32F103C8T672MHz主频/64KB Flash/20KB RAM传感器数据采集与预处理HC05蓝牙模块经典蓝牙2.1EDR/10米传输距离短距离无线数据传输电路连接时有个容易踩坑的地方HC05的VCC引脚必须接3.3V电源。我刚开始用5V供电导致模块频繁重启后来用万用表测量才发现问题。推荐连接方式TXD接STM32的PA10USART1_RXRXD接STM32的PA9USART1_TXKEY引脚悬空默认AT指令模式提示焊接时建议先给排针上锡再用热风枪固定。直接用电烙铁容易导致塑料外壳变形。2. 开发环境搭建推荐使用Keil MDKSTM32CubeMX的组合开发环境这是我测试过最稳定的配置。最近帮学员调试时发现如果用PlatformIO开发会出现HAL库版本兼容问题新手建议避开这个坑。具体安装步骤安装Keil MDK-ARM记得注册破解安装STM32CubeMX并下载F1系列HAL库配置USART1为异步模式波特率9600开启DMA传输可以降低CPU负载// CubeMX生成的USART初始化代码片段 huart1.Instance USART1; huart1.Init.BaudRate 9600; huart1.Init.WordLength UART_WORDLENGTH_8B; huart1.Init.StopBits UART_STOPBITS_1; huart1.Init.Parity UART_PARITY_NONE;记得在工程设置里勾选Use MicroLIB否则printf重定向会出问题。这个细节很多教程都没提但我调试时花了两个小时才找到原因。3. 蓝牙协议栈开发HC05模块出厂默认波特率是9600建议先用AT指令配置为115200以提高传输效率。分享一个实用的AT指令调试技巧用串口助手发送时要在结尾加\r\n模块返回OK才算成功。完整的AT指令配置流程按住模块按键上电进入AT模式发送ATUART115200,0,0设置波特率ATROLE0设为从机模式ATPSWD1234设置配对密码数据透传的关键在于处理好数据分包。我封装了个实用的发送函数void Bluetooth_Send(uint8_t* data, uint16_t len) { uint16_t chunkSize 20; // 每包20字节 for(uint16_t i0; ilen; ichunkSize){ uint16_t remain len - i; uint16_t sendLen remain chunkSize ? chunkSize : remain; HAL_UART_Transmit(huart1, datai, sendLen, 100); HAL_Delay(10); // 防止缓冲区溢出 } }实测发现连续发送超过64字节容易丢包所以要做分包处理。加10ms延时后传输稳定性显著提升。4. 手机APP开发实战采用Android StudioJava开发监控APP比跨平台方案更稳定。之前尝试用Flutter开发发现蓝牙延迟高达200ms换成原生开发后降到50ms以内。核心功能实现步骤在AndroidManifest.xml添加蓝牙权限uses-permission android:nameandroid.permission.BLUETOOTH/ uses-permission android:nameandroid.permission.BLUETOOTH_ADMIN/ uses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION/蓝牙设备扫描代码BluetoothAdapter bluetoothAdapter BluetoothAdapter.getDefaultAdapter(); if (!bluetoothAdapter.isEnabled()) { Intent enableBtIntent new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } SetBluetoothDevice pairedDevices bluetoothAdapter.getBondedDevices(); if (pairedDevices.size() 0) { for (BluetoothDevice device : pairedDevices) { if(device.getName().equals(HC05)){ connectDevice(device); } } }数据接收线程处理private class ConnectedThread extends Thread { public void run() { byte[] buffer new byte[1024]; while (true) { try { int bytes mmInStream.read(buffer); String data new String(buffer, 0, bytes); runOnUiThread(() - textView.append(data)); } catch (IOException e) { break; } } } }界面设计建议用ConstraintLayout实现自适应布局我在GitHub上开源了一个数据可视化控件库可以直接引入使用。5. 数据协议设计自定义协议要包含帧头、数据长度、校验位等字段。这是我设计的协议格式字段长度(字节)说明帧头2固定为0xAA55数据类型10x01温度 0x02湿度数据长度1有效数据长度数据内容N实际数据CRC8校验1校验和协议解析代码示例typedef struct { uint16_t header; uint8_t type; uint8_t len; uint8_t data[32]; uint8_t crc; } SensorFrame; void ParseProtocol(uint8_t* raw) { SensorFrame* frame (SensorFrame*)raw; if(frame-header ! 0xAA55) return; uint8_t crc CalculateCRC8(raw, 4frame-len); if(crc ! frame-crc) return; switch(frame-type){ case 0x01: ProcessTemperature(frame-data); break; case 0x02: ProcessHumidity(frame-data); break; } }这种协议结构在项目中验证过能有效避免数据错乱问题。建议在数据内容字段采用JSON格式方便手机端解析。6. 低功耗优化技巧虽然STM32F103不是低功耗芯片但通过合理配置仍能降低能耗修改时钟配置RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(RCC_OscInitStruct);蓝牙模块电源管理void Bluetooth_Sleep(void) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 控制MOS管断电 }采集间隔优化void HAL_SYSTICK_Callback(void) { static uint32_t tick 0; if(tick 60000){ // 1分钟采集一次 tick 0; Wakeup_Peripherals(); } }实测这些优化可使系统待机电流从25mA降到8mA。如果换用STM32L系列效果会更好但成本要增加30%左右。7. 常见问题排查问题1蓝牙连接不稳定检查天线是否完全展开用示波器测量电源纹波建议50mV修改MTU值为128以下ATPOLAR1,1,128,1000问题2数据丢包严重在STM32端添加软件流控降低波特率到57600测试在APP端添加数据重传机制问题3手机搜不到设备确认HC05处于可发现模式LED快闪检查模块是否设置为从机模式ATROLE0避免2.4G频段干扰远离WiFi路由器最近帮客户调试时遇到个典型案例蓝牙传输距离只有2米后来发现是PCB天线旁边有金属螺丝。改用陶瓷天线后距离恢复到8米以上。