(W-F+2P)/S+1不能为小数,必须是整数

本文探讨了卷积神经网络中关键的超参数设置问题,特别是如何合理设定卷积核大小、填充(padding)和步长(stride),以确保网络各维度的有效利用。通过实例说明不当设置可能引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例如:W=10,P=0且滤波尺寸F=3,则S不可能等于2(因为(W-F+2P)/S+1=(10-3+0)/2+1=4.5,4.5不是整数)。因此,这样设置超参数是无效的且卷积网络库将抛出异常。合适地设置卷积网络的大小使得所有维度都“有用”是一件头疼的事,而用补0和一些设计方法会显著缓解。

二、C语言实现代码 #include <stdio.h> // 卡尔曼滤波器结构体 typedef struct { float x[2]; // 状态向量 [weight, velocity] float P[2][2]; // 误差协方差矩阵 float Q[2]; // 过程噪声方差 [q_weight, q_velocity] float R; // 测量噪声方差 float dt; // 采样时间(s) } KalmanFilter; // 初始化滤波器 void kalman_init(KalmanFilter *kf, float init_weight, float q_w, float q_v, float r, float dt) { kf->x[0] = init_weight; // 初始重量 kf->x[1] = 0.0f; // 初始速度=0 kf->P[0][0] = 1.0f; // 初始协方差 kf->P[0][1] = 0.0f; kf->P[1][0] = 0.0f; kf->P[1][1] = 1.0f; kf->Q[0] = q_w; // 重量过程噪声方差 kf->Q[1] = q_v; // 速度过程噪声方差 kf->R = r; // 测量噪声方差 kf->dt = dt; // 采样间隔 } // 执行预测步骤 void kalman_predict(KalmanFilter *kf) { // 状态预测: x = A * x float weight_pred = kf->x[0] + kf->dt * kf->x[1]; float vel_pred = kf->x[1]; // 协方差预测: P = A * P * A^T + Q float P00 = kf->P[0][0] + kf->dt*(kf->P[1][0] + kf->P[0][1]) + kf->dt*kf->dt*kf->P[1][1]; float P01 = kf->P[0][1] + kf->dt*kf->P[1][1]; float P10 = kf->P[1][0] + kf->dt*kf->P[1][1]; float P11 = kf->P[1][1]; kf->P[0][0] = P00 + kf->Q[0]; kf->P[0][1] = P01; kf->P[1][0] = P10; kf->P[1][1] = P11 + kf->Q[1]; kf->x[0] = weight_pred; kf->x[1] = vel_pred; } // 执行更新步骤 void kalman_update(KalmanFilter *kf, float measurement) { // 计算卡尔曼增益: K = P * H^T / (H * P * H^T + R) float S = kf->P[0][0] + kf->R; float K0 = kf->P[0][0] / S; float K1 = kf->P[1][0] / S; // 更新状态估计 float residual = measurement - kf->x[0]; kf->x[0] += K0 * residual; kf->x[1] += K1 * residual; // 更新协方差 float P00 = (1 - K0) * kf->P[0][0]; float P01 = (1 - K0) * kf->P[0][1]; float P10 = -K1 * kf->P[0][0] + kf->P[1][0]; float P11 = -K1 * kf->P[0][1] + kf->P[1][1]; kf->P[0][0] = P00; kf->P[0][1] = P01; kf->P[1][0] = P10; kf->P[1][1] = P11; } // 示例用法 int main() { KalmanFilter kf; // 参数初始化: q_w=0.01, q_v=0.1, r=0.1, dt=0.1s kalman_init(&kf, 0.0f, 0.01f, 0.1f, 0.1f, 0.1f); // 模拟动态称重数据流 (实际替换为ADS1232读数) float measurements[] = {0.5f, 1.2f, 1.8f, 2.3f, 2.2f, 2.1f}; for(int i=0; i<6; i++) { kalman_predict(&kf); kalman_update(&kf, measurements[i]); // 输出滤波后的重量值 (状态向量第一个元素) printf("Step %d: Raw=%.2fg, Filtered=%.2fg\n", i+1, measurements[i], kf.x[0]); } return 0; } 三、参数调优指南 通过静态测试计算ADC读数方差: // 采集N次静态读数 float sum = 0, sq_sum = 0; for(int i=0; i<100; i++) { float adc_val = read_ads1232(); // 实际读取函数 sum += adc_val; sq_sum += adc_val * adc_val; } float r = (sq_sum - sum*sum/100) / 99; // 样本方差 // 自适应调整(根据残差大小) float residual = measurement - kf->x[0]; if(fabs(residual) > threshold) { kf->Q[1] *= 2.0f; // 增大速度噪声适应突变 } // 使用Q16格式定点数 (16位小数) typedef int32_t fixed_t; #define FLOAT_TO_FIXED(x) ((fixed_t)((x) * 65536.0f)) #define FIXED_TO_FLOAT(x) ((float)(x) / 65536.0f) // 矩阵乘法改用整数运算 fixed_t P00 = ... // 所有计算转换为整数运算 uint32_t last_time = get_timer(); while(1) { uint32_t now = get_timer(); kf.dt = (now - last_time) / 1000.0f; last_time = now; // ...执行滤波 } 五、工业场景增强策略 突变检测机制 if(fabs(residual) > 3*sqrtf(kf->P[0][0])) { // 3σ原则 // 触发重量突变处理 kf->x[0] = measurement; // 重置状态 kf->P[0][0] = kf->R * 10; // 增大不确定性 } 启动收敛加速 初始阶段增大 Q Q 值快速收敛: if(step_count < 10) { // 前10次采样 kf.Q[0] *= 4.0f; kf.Q[1] *= 4.0f; }
最新发布
07-09
#ifndef BSP__GPS_H__ #define BSP__GPS_H__ #include "cmsis_os2.h" #include "hi_io.h" #include "hi_gpio.h" #include "hi_uart.h" // 添加UART专用头文件 #include <stdio.h> #include <string.h> #include "bsp_uart.h" #include "hi_errno.h" // GPS 数据结构定义 typedef struct { float longitude; // 经度 (度) float latitude; // 纬度 (度) char nshemi; // 北纬/南纬 (N/S) char ewhemi; // 东经/西经 (E/W) struct { uint8_t hour; // UTC 小时 uint8_t min; // UTC 分钟 uint8_t sec; // UTC 秒 } utc; uint8_t fixmode; // 定位模式 uint8_t posslnum; // 参与定位的卫星数 float altitude; // 海拔高度 (米) } nmea_msg; #define GPS_UART_IDX HI_UART_IDX_2 // 使用UART1 #define GPS_BAUDRATE 9600 #define RX_BUF_LEN 128 // 定义接收缓冲区大小 // 函数声明 void gps_init(void); void gps_parse_nmea(nmea_msg *gps, const char *buf); void gps_show_data(const nmea_msg *gps); #endif#include "bsp_gps.h" #include <stdlib.h> #include "bsp_uart.h" #include <string.h> // 查找逗号位置 // 计算m的n次方 static uint32_t NMEA_Pow(uint8_t m, uint8_t n) { uint32_t result = 1; while (n--) result *= m; return result; } // 查找逗号位置(修改为接受const指针) uint8_t nmea_comma_pos(const uint8_t *buf, uint8_t cx) { const uint8_t *p = buf; while (cx) { if (*buf == '*' || *buf < ' ' || *buf > 'z') return 0xFF; // 错误终止符 if (*buf == ',') cx--; buf++; } return buf - p; } // 字符串转数字(修改为接受const指针) int nmea_str2num(const uint8_t *buf, uint8_t *dx) { const uint8_t *p = buf; uint32_t ires = 0, fres = 0; uint8_t ilen = 0, flen = 0, i; uint8_t mask = 0; int res; while (1) { if (*p == '-') { mask |= 0x02; p++; } // 负数标记 if (*p == ',' || *p == '*') break; // 结束符 if (*p == '.') { mask |= 0x01; p++; } // 小数点 else if (*p > '9' || *p < '0') { // 非法字符 ilen = 0; flen = 0; break; } if (mask & 0x01) flen++; else ilen++; p++; } if (mask & 0x02) buf++; // 跳过负号 for (i = 0; i < ilen; i++) // 整数部分 ires += NMEA_Pow(10, ilen - 1 - i) * (buf[i] - '0'); if (flen > 5) flen = 5; // 最多5位小数 if (dx) *dx = flen; // 安全处理空指针 for (i = 0; i < flen; i++) // 小数部分 fres += NMEA_Pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0'); res = ires * NMEA_Pow(10, flen) + fres; if (mask & 0x02) res = -res; return res; } // 解析 GPRMC 语句 static void parse_gprmc(nmea_msg *gps, const char *buf) { const char *p = strstr(buf, "GPRMC"); if (!p) return; uint8_t pos = nmea_comma_pos((const uint8_t *)p, 1); // UTC 时间 if (pos != 0xFF) { uint32_t time = nmea_str2num((const uint8_t *)(p + pos), NULL); gps->utc.hour = time / 10000; gps->utc.min = (time % 10000) / 100; gps->utc.sec = time % 100; } pos = nmea_comma_pos((const uint8_t *)p, 3); // 纬度 if (pos != 0xFF) { float lat = nmea_str2num((const uint8_t *)(p + pos), NULL) / 100000.0f; gps->latitude = (int)(lat / 100) + (lat - (int)(lat / 100) * 100) / 60.0f; } pos = nmea_comma_pos((const uint8_t *)p, 4); // 纬度半球 if (pos != 0xFF) gps->nshemi = *(p + pos); pos = nmea_comma_pos((const uint8_t *)p, 5); // 经度 if (pos != 0xFF) { float lon = nmea_str2num((const uint8_t *)(p + pos), NULL) / 100000.0f; gps->longitude = (int)(lon / 100) + (lon - (int)(lon / 100) * 100) / 60.0f; } pos = nmea_comma_pos((const uint8_t *)p, 6); // 经度半球 if (pos != 0xFF) gps->ewhemi = *(p + pos); } // 解析 GPGGA 语句 (添加此函数) static void parse_gpgga(nmea_msg *gps, const char *buf) { const char *p = strstr(buf, "GPGGA"); if (!p) return; // UTC时间 uint8_t pos = nmea_comma_pos((const uint8_t *)p, 1); if (pos != 0xFF) { uint32_t time = nmea_str2num((const uint8_t *)(p + pos), NULL); gps->utc.hour = time / 10000; gps->utc.min = (time % 10000) / 100; gps->utc.sec = time % 100; } #include <stdio.h> #include <unistd.h> #include <string.h> // 添加memset头文件 #include "ohos_init.h" #include "cmsis_os2.h" #include "bsp_gps.h" #include "hi_uart.h" // 添加UART操作头文件 #include "hi_time.h" // 添加时间函数头文件 // 全局变量 static nmea_msg g_gps_data = {0}; // 初始化GPS数据结构 static uint8_t rx_buf[RX_BUF_LEN] = {0}; // 初始化接收缓冲区 static osThreadId_t GPS_Task_ID; // 任务ID // 修正任务函数名 void gps_task(void *argument) { (void)argument; gps_init(); // 初始化GPS // 添加启动延迟,等待GPS模块初始化 sleep(2); while (1) { uint32_t len = hi_uart_read(GPS_UART_IDX, rx_buf, sizeof(rx_buf) - 1); if (len > 0) { rx_buf[len] = '\0'; // 打印原始数据用于调试 // printf("Raw: %s\n", rx_buf); gps_parse_nmea(&g_gps_data, (const char*)rx_buf); // 添加时间戳 printf("\n[%02d:%02d:%02d] GPS Data:\n", g_gps_data.utc.hour, g_gps_data.utc.min, g_gps_data.utc.sec); gps_show_data(&g_gps_data); memset(rx_buf, 0, sizeof(rx_buf)); } // 设置合适的刷新率(500ms) sleep(1); } } void gps_task_create(void) { osThreadAttr_t taskOptions; taskOptions.name = "GPSTask"; // 任务的名字 taskOptions.attr_bits = 0; // 属性位 taskOptions.cb_mem = NULL; // 堆空间地址 taskOptions.cb_size = 0; // 堆空间大小 taskOptions.stack_mem = NULL; // 栈空间地址 taskOptions.stack_size = 4096; // 栈空间大小 单位:字节 taskOptions.priority = osPriorityNormal; // 任务的优先级 GPS_Task_ID = osThreadNew(gps_task, NULL, &taskOptions); // 创建任务 if (GPS_Task_ID != NULL) { printf("ID = %p, Create GPS_Task is OK!\n", GPS_Task_ID); }; } static void template_demo(void) { printf("普中-Hi3861开发板--GPS实验\r\n"); gps_task_create(); } SYS_RUN(template_demo); 该代码是基于海思hi 3861外接NEO-6M-0-001在串口助手上显示经纬度和当前北京时间的代码但在串口助手上显示以下内容是什么原因并进行修改�� � ���� ��N�B����������� �!��� � ����� ��F�0� ���������~�B���1�!��� �� ��~�*��� � �� �� ���� ��� ������ ��~��� � �� ��B�1��� �F�1�N��� �� ������� �*�! ��^�*� ��B�1��� ��� ��^� ���^� ���� �����~��� ������ ��� �!��F��� �!� ���^�:����� ���������� � �� ���� ���� ������B��� �1�!�� � ���� ���� �����B�0� ��B�1� ���� � �� ��~� �1� � ���� �B�2� �������2��B��� ��� ��� ����������_�����B���^�2��� � �х����N���B����� ��� ��� �N����^���������
07-07
[OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c: In function 'gps_init': [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:115:5: error: unknown type name 'hi_uart_attribute'; did you mean '__has_attribute'? [OHOS ERROR] hi_uart_attribute config = { [OHOS ERROR] ^~~~~~~~~~~~~~~~~ [OHOS ERROR] __has_attribute [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:116:9: error: field name not in record or union initializer [OHOS ERROR] .baud_rate = 9600, // NEO-6M默认波特率 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:116:9: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:9: error: field name not in record or union initializer [OHOS ERROR] .data_bits = HI_UART_DATA_BIT_8, // 8位数据位 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:9: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:22: error: 'HI_UART_DATA_BIT_8' undeclared (first use in this function); did you mean 'HI_ERR_DMA_BUSY'? [OHOS ERROR] .data_bits = HI_UART_DATA_BIT_8, // 8位数据位 [OHOS ERROR] ^~~~~~~~~~~~~~~~~~ [OHOS ERROR] HI_ERR_DMA_BUSY [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:22: note: each undeclared identifier is reported only once for each function it appears in [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:22: warning: excess elements in scalar initializer [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:117:22: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:118:9: error: field name not in record or union initializer [OHOS ERROR] .stop_bits = HI_UART_STOP_BIT_1, // 1位停止位 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:118:9: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:118:22: error: 'HI_UART_STOP_BIT_1' undeclared (first use in this function); did you mean 'HI_UART_DATA_BIT_8'? [OHOS ERROR] .stop_bits = HI_UART_STOP_BIT_1, // 1位停止位 [OHOS ERROR] ^~~~~~~~~~~~~~~~~~ [OHOS ERROR] HI_UART_DATA_BIT_8 [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:118:22: warning: excess elements in scalar initializer [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:118:22: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:119:9: error: field name not in record or union initializer [OHOS ERROR] .parity = HI_UART_PARITY_NONE, // 无校验 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:119:9: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:119:19: error: 'HI_UART_PARITY_NONE' undeclared (first use in this function); did you mean 'HI_UART_DATA_BIT_8'? [OHOS ERROR] .parity = HI_UART_PARITY_NONE, // 无校验 [OHOS ERROR] ^~~~~~~~~~~~~~~~~~~ [OHOS ERROR] HI_UART_DATA_BIT_8 [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:119:19: warning: excess elements in scalar initializer [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:119:19: note: (near initialization for 'config') [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:120:9: error: field name not in record or union initializer [OHOS ERROR] .fifo_enable = HI_TRUE // 启用FIFO [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:120:9: note: (near initialization for 'config') [OHOS ERROR] In file included from ../../../device/hisilicon/hispark_pegasus/sdk_liteos/include/hi_io.h:26:0, [OHOS ERROR] from ../../../vendor/pzkj/pz_hi3861/common/bsp/include/bsp_gps.h:6, [OHOS ERROR] from ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:1: [OHOS ERROR] ../../../device/hisilicon/hispark_pegasus/sdk_liteos/include/hi_types_base.h:284:26: warning: excess elements in scalar initializer [OHOS ERROR] #define HI_TRUE 1 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:120:24: note: in expansion of macro 'HI_TRUE' [OHOS ERROR] .fifo_enable = HI_TRUE // 启用FIFO [OHOS ERROR] ^~~~~~~ [OHOS ERROR] ../../../device/hisilicon/hispark_pegasus/sdk_liteos/include/hi_types_base.h:284:26: note: (near initialization for 'config') [OHOS ERROR] #define HI_TRUE 1 [OHOS ERROR] ^ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:120:24: note: in expansion of macro 'HI_TRUE' [OHOS ERROR] .fifo_enable = HI_TRUE // 启用FIFO [OHOS ERROR] ^~~~~~~ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:124:18: warning: implicit declaration of function 'hi_uart_init'; did you mean 'uart0_init'? [-Wimplicit-function-declaration] [OHOS ERROR] hi_u32 ret = hi_uart_init(HI_UART_IDX_2, &config); [OHOS ERROR] ^~~~~~~~~~~~ [OHOS ERROR] uart0_init [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:124:31: error: 'HI_UART_IDX_2' undeclared (first use in this function); did you mean 'HI_GPIO_IDX_2'? [OHOS ERROR] hi_u32 ret = hi_uart_init(HI_UART_IDX_2, &config); [OHOS ERROR] ^~~~~~~~~~~~~ [OHOS ERROR] HI_GPIO_IDX_2 [OHOS ERROR] you can check build log in D:\hi3861\hi3861_hdu_iot_application\src\out\hispark_pegasus\wifiiot_hispark_pegasus\build.log [OHOS ERROR] command: "D:\hi3861\hi3861_hdu_iot_application\src\prebuilts\build-tools\win64-x64\bin\ninja.exe -w dupbuild=warn -C D:\hi3861\hi3861_hdu_iot_application\src\out\hispark_pegasus\wifiiot_hispark_pegasus" failed [OHOS ERROR] return code: 1 [OHOS ERROR] execution path: D:\hi3861\hi3861_hdu_iot_application\src scons: *** [src\out\hispark_pegasus\wifiiot_hispark_pegasus\target.elf] Error -1请根据该错误对VSCODE以下代码进行修改#ifndef BSP__GPS_H__ #define BSP__GPS_H__ #include "cmsis_os2.h" #include "hi_io.h" #include "hi_gpio.h" #include <stdio.h> #include <string.h> #include "bsp_uart.h" #include "hi_errno.h" // GPS 数据结构定义 typedef struct { float longitude; // 经度 (度) float latitude; // 纬度 (度) char nshemi; // 北纬/南纬 (N/S) char ewhemi; // 东经/西经 (E/W) struct { uint8_t hour; // UTC 小时 uint8_t min; // UTC 分钟 uint8_t sec; // UTC 秒 } utc; uint8_t fixmode; // 定位模式 uint8_t posslnum; // 参与定位的卫星数 float altitude; // 海拔高度 (米) } nmea_msg; // 定义UART2引脚配置 #define GPS_UART_IDX HI_UART_IDX_2 #define GPS_BAUDRATE 9600 // NEO-6M默认波特率 // 函数声明 void gps_init(void); void gps_parse_nmea(nmea_msg *gps, const char *buf); void gps_show_data(const nmea_msg *gps); #endif#include "bsp_gps.h" #include <stdlib.h> #include "bsp_uart.h" // 添加必要的UART头文件 // 查找逗号位置 // 计算m的n次方 static uint32_t NMEA_Pow(uint8_t m, uint8_t n) { uint32_t result = 1; while (n--) result *= m; return result; } // 查找逗号位置(修改为接受const指针) uint8_t nmea_comma_pos(const uint8_t *buf, uint8_t cx) { const uint8_t *p = buf; while (cx) { if (*buf == '*' || *buf < ' ' || *buf > 'z') return 0xFF; // 错误终止符 if (*buf == ',') cx--; buf++; } return buf - p; } // 字符串转数字(修改为接受const指针) int nmea_str2num(const uint8_t *buf, uint8_t *dx) { const uint8_t *p = buf; uint32_t ires = 0, fres = 0; uint8_t ilen = 0, flen = 0, i; uint8_t mask = 0; int res; while (1) { if (*p == '-') { mask |= 0x02; p++; } // 负数标记 if (*p == ',' || *p == '*') break; // 结束符 if (*p == '.') { mask |= 0x01; p++; } // 小数点 else if (*p > '9' || *p < '0') { // 非法字符 ilen = 0; flen = 0; break; } if (mask & 0x01) flen++; else ilen++; p++; } if (mask & 0x02) buf++; // 跳过负号 for (i = 0; i < ilen; i++) // 整数部分 ires += NMEA_Pow(10, ilen - 1 - i) * (buf[i] - '0'); if (flen > 5) flen = 5; // 最多5位小数 if (dx) *dx = flen; // 安全处理空指针 for (i = 0; i < flen; i++) // 小数部分 fres += NMEA_Pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0'); res = ires * NMEA_Pow(10, flen) + fres; if (mask & 0x02) res = -res; return res; } // 解析 GPRMC 语句 static void parse_gprmc(nmea_msg *gps, const char *buf) { const char *p = strstr(buf, "GPRMC"); if (!p) return; // 显式类型转换解决警告(函数参数已改为const uint8_t*) uint8_t pos = nmea_comma_pos((const uint8_t *)p, 1); // UTC 时间 if (pos != 0xFF) { uint32_t time = nmea_str2num((const uint8_t *)(p + pos), NULL); gps->utc.hour = time / 10000; gps->utc.min = (time % 10000) / 100; gps->utc.sec = time % 100; } pos = nmea_comma_pos((const uint8_t *)p, 3); // 纬度 if (pos != 0xFF) { float lat = nmea_str2num((const uint8_t *)(p + pos), NULL) / 100000.0f; gps->latitude = (int)(lat / 100) + (lat - (int)(lat / 100) * 100) / 60.0f; } pos = nmea_comma_pos((const uint8_t *)p, 4); // 纬度半球 if (pos != 0xFF) gps->nshemi = *(p + pos); pos = nmea_comma_pos((const uint8_t *)p, 5); // 经度 if (pos != 0xFF) { float lon = nmea_str2num((const uint8_t *)(p + pos), NULL) / 100000.0f; gps->longitude = (int)(lon / 100) + (lon - (int)(lon / 100) * 100) / 60.0f; } pos = nmea_comma_pos((const uint8_t *)p, 6); // 经度半球 if (pos != 0xFF) gps->ewhemi = *(p + pos); } // 主解析函数 void gps_parse_nmea(nmea_msg *gps, const char *buf) { if (strstr(buf, "$GPRMC")) parse_gprmc(gps, buf); // 修正:移除多余空格 // 可扩展其他语句解析 (如GPGGA, GPGSA等) } void gps_init(void) { // 初始化GPIO子系统 (必须首先调用) hi_gpio_init(); // ===== 配置TX引脚 (GPIO11 - 输出) ===== hi_io_set_pull(HI_IO_NAME_GPIO_11, HI_IO_PULL_UP); // 上拉模式 hi_io_set_func(HI_IO_NAME_GPIO_11, HI_IO_FUNC_GPIO_11_UART2_TXD); // UART TX功能 hi_gpio_set_dir(HI_IO_NAME_GPIO_11, HI_GPIO_DIR_OUT); // 输出方向 // ===== 配置RX引脚 (GPIO12 - 输入) ===== hi_io_set_pull(HI_IO_NAME_GPIO_12, HI_IO_PULL_NONE); // 浮空模式(推荐) hi_io_set_func(HI_IO_NAME_GPIO_12, HI_IO_FUNC_GPIO_12_UART2_RXD); // UART RX功能 hi_gpio_set_dir(HI_IO_NAME_GPIO_12, HI_GPIO_DIR_IN); // 输入方向 // ===== UART参数配置 ===== hi_uart_attribute config = { .baud_rate = 9600, // NEO-6M默认波特率 .data_bits = HI_UART_DATA_BIT_8, // 8位数据位 .stop_bits = HI_UART_STOP_BIT_1, // 1位停止位 .parity = HI_UART_PARITY_NONE, // 无校验 .fifo_enable = HI_TRUE // 启用FIFO }; // 初始化UART2 hi_u32 ret = hi_uart_init(HI_UART_IDX_2, &config); if (ret != HI_ERR_SUCCESS) { printf("GPS UART init failed! Error: 0x%X\n", ret); } } // 显示GPS数据 void gps_show_data(const nmea_msg *gps) { printf("Longitude: %.5f%c\n", gps->longitude, gps->ewhemi); printf("Latitude: %.5f%c\n", gps->latitude, gps->nshemi); printf("UTC Time: %02d:%02d:%02d\n", gps->utc.hour, gps->utc.min, gps->utc.sec); printf("Satellites: %d\n", gps->posslnum); printf("Altitude: %.1fm\n", gps->altitude); }
07-07
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值