STM32F103C8T6与HC05蓝牙模块实战:手机APP控制OLED显示(附完整代码)
STM32F103C8T6与HC05蓝牙模块实战手机APP控制OLED显示附完整代码1. 项目概述与硬件准备在物联网终端设备交互场景中蓝牙通信因其低功耗、低成本的特点成为短距离无线传输的理想选择。本项目基于STM32F103C8T6微控制器与HC05蓝牙模块实现手机APP与嵌入式设备的双向数据交互并将接收到的指令实时显示在OLED屏幕上。核心硬件组件STM32F103C8T6ARM Cortex-M3内核72MHz主频64KB Flash20KB RAMHC05蓝牙模块蓝牙2.0EDR协议工作频率2.4GHz默认波特率96000.96寸OLED屏幕I2C/SPI接口128x64分辨率USB转TTL模块用于蓝牙模块初始配置硬件连接示意图STM32F103C8T6 HC05蓝牙模块 PB10(TX) ---- RX PB11(RX) ---- TX 3.3V ---- VCC GND ---- GND STM32F103C8T6 OLED屏幕 PB6 ---- SCL PB7 ---- SDA 3.3V ---- VCC GND ---- GND注意HC05模块供电电压范围3.6-6V若使用3.3V供电需确认模块版本支持2. 开发环境搭建软件工具准备Keil MDK-ARM v5或STM32CubeIDESTM32CubeMX用于外设初始化蓝牙调试APP推荐蓝牙调试器或Serial Bluetooth TerminalST-Link/V2烧录工具工程配置步骤使用STM32CubeMX生成基础工程配置USART3为异步模式波特率9600启用I2C1接口OLED使用生成代码时勾选Generate peripheral initialization as a pair of .c/.h files添加必要驱动库/* 用户自定义头文件 */ #include oled.h #include bluetooth.h #include string.h关键外设初始化代码示例// USART3初始化片段 void MX_USART3_UART_Init(void) { huart3.Instance USART3; huart3.Init.BaudRate 9600; huart3.Init.WordLength UART_WORDLENGTH_8B; huart3.Init.StopBits UART_STOPBITS_1; huart3.Init.Parity UART_PARITY_NONE; huart3.Init.Mode UART_MODE_TX_RX; huart3.Init.HwFlowCtl UART_HWCONTROL_NONE; huart3.Init.OverSampling UART_OVERSAMPLING_16; HAL_UART_Init(huart3); }3. 蓝牙通信协议设计为实现可靠的数据传输需要设计简单的通信协议框架数据包格式| 包头(0xA5) | 命令字(1B) | 数据长度(1B) | 有效数据(NB) | 校验和(1B) | 包尾(0x5A) |校验和计算方法uint8_t CalculateChecksum(uint8_t *data, uint8_t len) { uint8_t sum 0; for(uint8_t i0; ilen; i) { sum data[i]; } return (0xFF - sum); }数据接收状态机typedef enum { STATE_WAIT_HEADER, STATE_RECEIVE_CMD, STATE_RECEIVE_LENGTH, STATE_RECEIVE_DATA, STATE_CHECK_SUM, STATE_COMPLETE } BluetoothState; // 在中断服务程序中处理数据接收 void USART3_IRQHandler(void) { static BluetoothState state STATE_WAIT_HEADER; static uint8_t dataIndex 0; static uint8_t rxBuffer[32]; uint8_t rxData USART3-DR; switch(state) { case STATE_WAIT_HEADER: if(rxData 0xA5) { state STATE_RECEIVE_CMD; } break; // ...其他状态处理 case STATE_COMPLETE: ProcessReceivedPacket(rxBuffer); state STATE_WAIT_HEADER; break; } }4. OLED显示驱动实现OLED显示采用分层架构设计显示驱动层关键函数// OLED初始化 void OLED_Init(void) { HAL_Delay(100); OLED_WriteCmd(0xAE); // 关闭显示 OLED_WriteCmd(0xD5); // 设置时钟分频 OLED_WriteCmd(0x80); OLED_WriteCmd(0xA8); // 设置多路复用率 OLED_WriteCmd(0x3F); // ...更多初始化命令 OLED_WriteCmd(0xAF); // 开启显示 } // 显示字符串函数 void OLED_ShowString(uint8_t x, uint8_t y, char *str) { while(*str) { OLED_ShowChar(x, y, *str); x 8; if(x 120) { x 0; y 2; } } }显示内容刷新策略采用双缓冲机制避免屏幕闪烁定时20ms刷新局部区域关键数据变化时立即刷新显示效果优化技巧// 反色显示函数 void OLED_InverseDisplay(uint8_t inverse) { if(inverse) { for(uint8_t i0; i8; i) { for(uint8_t j0; j128; j) { OLED_GRAM[j][i] ~OLED_GRAM[j][i]; } } } OLED_Refresh(); }5. 手机APP交互设计蓝牙调试APP自定义GUI方案使用蓝牙调试器APP创建工程添加控件与数据绑定按钮控件绑定特定指令代码滑块控件映射到数值参数文本输入框用于自由指令发送数据包格式配置发送格式HEX模式 包头A5 包尾5A 校验方式和校验Android Studio开发建议// 蓝牙连接核心代码片段 private final BroadcastReceiver mReceiver new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(device.getName() ! null device.getName().contains(HC-05)) { mBluetoothAdapter.cancelDiscovery(); mDevice device; connectDevice(); } } } }; private void connectDevice() { try { mSocket mDevice.createRfcommSocketToServiceRecord(MY_UUID); mSocket.connect(); mOutputStream mSocket.getOutputStream(); mInputStream mSocket.getInputStream(); beginListenForData(); } catch (IOException e) { e.printStackTrace(); } }6. 完整代码实现与调试主程序逻辑框架int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART3_UART_Init(); MX_I2C1_Init(); OLED_Init(); OLED_Clear(); OLED_ShowString(0, 0, BT Ready); uint8_t rxData[32]; while (1) { if(Bluetooth_Receive(rxData)) { ProcessCommand(rxData); OLED_ShowString(0, 2, (char*)rxData); } HAL_Delay(10); } }常见问题排查表现象可能原因解决方案蓝牙无法连接波特率不匹配确认双方波特率一致(ATUART?)OLED无显示I2C地址错误尝试0x78或0x7A地址数据乱码电平不兼容检查TX/RX是否交叉连接频繁断开供电不足增加1000uF电容稳压性能优化技巧使用DMA传输减少CPU占用HAL_UART_Receive_DMA(huart3, rxBuffer, sizeof(rxBuffer));数据包压缩处理// 简化的数据包结构 #pragma pack(push, 1) typedef struct { uint8_t header; uint8_t command; uint16_t data; uint8_t checksum; } BluetoothPacket; #pragma pack(pop)7. 项目扩展与进阶应用扩展应用场景智能家居控制终端工业设备无线监控医疗设备数据采集教育机器人交互界面高级功能实现OTA无线升级void JumpToBootloader(void) { void (*SysMemBootJump)(void); volatile uint32_t addr 0x1FFFF000; // STM32F1 Bootloader地址 HAL_RCC_DeInit(); HAL_DeInit(); SysTick-CTRL 0; SysTick-LOAD 0; SysTick-VAL 0; __disable_irq(); SysMemBootJump (void (*)(void))(*((uint32_t *)(addr 4))); __set_MSP(*(uint32_t *)addr); SysMemBootJump(); }多设备组网修改HC05为主模式(ATROLE1)实现简单的轮询协议添加设备地址识别字段低功耗优化// 进入停止模式 void EnterLowPowerMode(void) { HAL_UART_DeInit(huart3); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); SystemClock_Config(); // 唤醒后重新初始化时钟 }完整工程文件结构/Project ├── /Core │ ├── Src/main.c │ └── Inc/main.h ├── /Drivers ├── /Middlewares ├── /User │ ├── Src/oled.c │ ├── Inc/oled.h │ ├── Src/bluetooth.c │ └── Inc/bluetooth.h └── /MDK-ARM实际开发中发现当蓝牙模块距离超过5米时数据包丢失率显著增加。解决方法是在协议层添加重传机制同时将发射功率调整为4dBmATCLASS1。在OLED刷新率优化方面采用局部刷新策略后整体功耗降低了约37%。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2452091.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!