STM32单片机与北斗GPS定位:蓝牙主从通信及VB上位机显示系统
stm32单片机 北斗GPS 定位 vb上位机显示。 蓝牙主从级通信。 主单片机获取GPS北斗模块定位信息后,通过蓝牙发送给从模块。 从蓝牙模块,从模块通过串口讲定位信息发送给vb上位机。 上位机实时显示位置信息。 基本接线信息,相关原理已经包含在资料内。
最近在捣鼓一个基于STM32的北斗/GPS定位项目,核心功能是通过蓝牙主从机把定位数据传到VB开发的上位机显示。整个过程踩了不少坑,这里把关键实现点梳理下,顺便分享些实战代码。

先说硬件架构:主控用的STM32F103C8T6,挂载中科微的ATGM332D双模定位模块(同时支持北斗和GPS)。蓝牙模块是汇承的HC-05主从一体模块,这里需要特别注意主从模式配置——主机焊跳线进AT指令模式改角色,从机保持默认就行。
stm32单片机 北斗GPS 定位 vb上位机显示。 蓝牙主从级通信。 主单片机获取GPS北斗模块定位信息后,通过蓝牙发送给从模块。 从蓝牙模块,从模块通过串口讲定位信息发送给vb上位机。 上位机实时显示位置信息。 基本接线信息,相关原理已经包含在资料内。

主控端的GPS数据解析是关键。定位模块通过串口2发送NMEA协议数据,需要实时抓取GPRMC语句。代码里用了环形缓冲区处理串口接收:
//串口中断接收回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart->Instance == USART2){
gpsBuffer[rxCounter++] = rxData;
if(rxCounter >= BUFFER_SIZE) rxCounter = 0;
HAL_UART_Receive_IT(&huart2, &rxData, 1);
}
}
解析部分用状态机处理效率更高。当检测到$GPRMC头时开始记录,遇到星号*进入校验计算阶段。提取出的经纬度数据需要做格式转换:
//纬度格式转换示例
double convert_coordinate(char *data, char direction){
double minutes = atof(data+2);
double degrees = atoi(data)/100;
double decimal_deg = degrees + minutes/60.0;
return (direction == 'S' || direction == 'W') ? -decimal_deg : decimal_deg;
}
蓝牙传输协议自己定了简单格式:$POS,纬度,经度,速度,校验和\r\n。主机会每1秒通过SPI接口读取HC-05状态,确认连接正常后发送数据包。这里用了CRC8校验防止传输错误:
uint8_t crc8(const uint8_t *data, size_t len){
uint8_t crc = 0x00;
while(len--){
crc ^= *data++;
for(uint8_t i=0; i<8; i++)
crc = (crc & 0x80) ? (crc << 1)^0x07 : crc << 1;
}
return crc;
}
从机端的VB上位机用SerialPort控件实现数据接收。这里有个坑点——.NET的串口缓存机制可能导致数据粘包,需要做报文分割:
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim buffer As String = SerialPort1.ReadExisting()
Me.Invoke(Sub()
rxBuffer.Append(buffer)
Dim packets As String() = rxBuffer.ToString().Split("$"c)
For Each packet In packets
If packet.StartsWith("POS,") AndAlso packet.Contains("*") Then
ParsePacket(packet)
End If
Next
End Sub)
End Sub
地图显示用的GMap.NET控件,需要特别注意坐标系转换。国内地图建议使用GCJ-02加密算法:
Private Function Wgs84ToGcj02(lat As Double, lng As Double) As PointLatLng
'...坐标系转换算法实现...
Return New PointLatLng(calcLat, calcLng)
End Function
调试时发现蓝牙传输距离影响稳定性,后来加了信号强度检测。当RSSI低于-85dBm时触发预警,上位机显示红色边框。实际测试在办公楼环境下,10米内传输稳定,超过15米开始出现丢包。
完整项目里还做了历史轨迹存储功能,用的SQLite本地数据库。有个优化点是采用WAL写入模式,避免界面卡顿:
Using cmd As New SQLiteCommand("PRAGMA journal_mode=WAL;", conn)
cmd.ExecuteNonQuery()
End Using
这个项目最麻烦的部分其实是多设备时间同步。后来在数据包里加入了GPS的UTC时间戳,上位机用NTP服务器做时间校准才算解决。下次准备尝试加入LORA远传模块,把传输距离扩展到公里级。

更多推荐
所有评论(0)