You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用STM32读取Adafruit GPS数据并发送至树莓派3?

解决STM32 Nucleo-F334R8 GPS数据无法发送到树莓派的问题

首先,先把你的问题和代码贴出来方便参考:

我使用STM32 Nucleo-F334R8开发板与Adafruit Ultimate GPS Breakout V3模块,先尝试通过串口用Putty读取GPS数据,最终目标是在F334R8上获取GPS数据后,通过串口发送至Raspberry Pi 3。目前在线使用Mbed Compiler开发时遇到诸多问题,附上代码后发现树莓派控制台无数据接收,恳请技术支持。

你的代码:

#include "mbed.h"
#include "MTK3339.h"
static int waitData = 0;
static MTK3339 gps(D8, D2);
static float latitude = 0;
static float longitude = 0;
Serial rasp(D15, D14); // D15 = RX, D14 = TX
static void dataAvailable() {
    waitData |= gps.getAvailableDataType();
}
int main(void) {
    gps.start(&dataAvailable, (MTK3339::NmeaGga|MTK3339::NmeaVtg));
    while(1) {
        while(waitData == 0);
        if ((waitData & MTK3339::NmeaGga) != 0) {
            waitData &= ~(MTK3339::NmeaGga);
            latitude = gps.getLatitudeAsDegrees();
            longitude = gps.getLongitudeAsDegrees();
            //printf("%f,%f\n", gps.getLatitudeAsDegrees(), gps.getLongitudeAsDegrees());
            //printf("lat = %f, long = %f",latitude, longitude);
            rasp.printf("%f\n", latitude);
        }
        waitData &= (MTK3339::NmeaGga|MTK3339::NmeaVtg);
    }
}

接下来一步步排查和解决问题:

一、先确认GPS模块是否正常给Nucleo输出数据

这是基础,如果Nucleo都没拿到GPS数据,树莓派肯定收不到:

  • 先做本地调试:把代码里的rasp.printf换成printf,然后用Putty连接Nucleo的USB虚拟调试串口(波特率默认9600),看能不能打印出经纬度。如果没输出:
    • 检查接线:Adafruit GPS的TX要接Nucleo的D8(你的代码里gps对象的RX引脚),GPS的RX接Nucleo的D2(gps的TX引脚),别搞反了!另外VCC接3.3V(Nucleo的3.3V引脚),GND必须和开发板共地。
    • 确认波特率:MTK3339默认是9600波特率,你可以在初始化gps时明确指定,改成static MTK3339 gps(D8, D2, 9600);避免库默认值不一致。
    • 给GPS足够定位时间:第一次定位需要在开阔地方(窗边或户外)等几分钟,看模块的LED灯——定位成功后会每秒闪一次,未定位是每10秒闪一次。

二、确认Nucleo和树莓派的串口通信本身正常

跳过GPS,先测试串口链路是否通畅:

  • 写个极简测试代码:
    #include "mbed.h"
    Serial rasp(D15, D14);
    int main() {
        rasp.baud(9600); // 和树莓派端波特率保持一致
        while(1) {
            rasp.printf("Hello from Nucleo!\n");
            thread_sleep_for(1000); // 每秒发一次测试消息
        }
    }
    
  • 树莓派端操作:
    1. 先通过raspi-config启用硬件UART:进入Interface Options → Serial,关掉"Serial port login shell",打开"Serial port hardware",重启树莓派。
    2. 用screen /dev/ttyAMA0 9600或者minicom打开串口,看能不能收到"Hello from Nucleo!"。如果收不到:
      • 检查接线:Nucleo的D14(TX)要接树莓派的RX(GPIO15),D15(RX)接树莓派的TX(GPIO14),别接反!
      • 确认树莓派串口设备:如果禁用了蓝牙,可能是/dev/ttyS0,可以用ls /dev/tty*查看可用的串口设备。

三、修改你的GPS代码,提升可靠性

解决上面两个环节后,再优化你的代码:

  • 给rasp串口明确设置波特率,在main开头加rasp.baud(9600);,默认波特率可能不匹配导致通信失败。
  • 增加调试输出,确认GPS数据是否被触发:
    static void dataAvailable() {
        waitData |= gps.getAvailableDataType();
        printf("GPS data received, type: %d\n", waitData); // 调试用,看回调是否触发
    }
    
  • 过滤无效GPS数据:GPS未定位时会输出0,这时候没必要发去树莓派,加个判断:
    if ((waitData & MTK3339::NmeaGga) != 0) {
        waitData &= ~(MTK3339::NmeaGga);
        latitude = gps.getLatitudeAsDegrees();
        longitude = gps.getLongitudeAsDegrees();
        // 只发送有效定位数据
        if (latitude != 0.0f && longitude != 0.0f) {
            rasp.printf("Lat: %f, Lon: %f\n", latitude, longitude);
        } else {
            rasp.printf("Waiting for GPS fix...\n");
        }
    }
    
  • 去掉代码里的waitData &= (MTK3339::NmeaGga|MTK3339::NmeaVtg);,这行逻辑有问题,会保留未处理的Vtg标志,导致循环一直触发却没有对应处理逻辑,反而干扰程序运行。

修改后的完整代码:

#include "mbed.h"
#include "MTK3339.h"
static int waitData = 0;
static MTK3339 gps(D8, D2, 9600); // 明确指定波特率
static float latitude = 0;
static float longitude = 0;
Serial rasp(D15, D14); // D15 = RX, D14 = TX

static void dataAvailable() {
    waitData |= gps.getAvailableDataType();
    printf("GPS data callback triggered!\n"); // 调试用
}

int main(void) {
    rasp.baud(9600); // 树莓派串口波特率匹配
    gps.start(&dataAvailable, MTK3339::NmeaGga); // 只启用GGA,减少数据量
    while(1) {
        while(waitData == 0); // 等待GPS数据
        if ((waitData & MTK3339::NmeaGga) != 0) {
            waitData &= ~(MTK3339::NmeaGga); // 清除GGA标志
            latitude = gps.getLatitudeAsDegrees();
            longitude = gps.getLongitudeAsDegrees();
            
            // 发送有效数据到树莓派
            if (latitude != 0.0f && longitude != 0.0f) {
                rasp.printf("%f,%f\n", latitude, longitude);
                printf("Sent to Pi: %f, %f\n", latitude, longitude); // 本地调试
            } else {
                rasp.printf("No GPS fix yet\n");
                printf("Waiting for fix...\n");
            }
        }
    }
}

按照这个步骤一步步排查,应该能解决树莓派收不到数据的问题。

内容的提问来源于stack exchange,提问作者Rosbibif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:02:18