中新生态城建设局门户网站,网站业务员好做吗,网站建设网站徒手整形培训,建设工程项目在哪个网站查询一、硬件连接
模块引脚 连接目标 说明
TX 串口助手接收端(RX) 交叉连接#xff0c;用于模块发送数据到上位机
RX 不接 测试阶段无需发送指令#xff0c;可悬空
VCC 5V/3.3V 根据模块版本选择#xff1a;多数ATGM336H型号需5V供电#xff08;具体以规格书为准用于模块发送数据到上位机RX 不接 测试阶段无需发送指令可悬空VCC 5V/3.3V 根据模块版本选择多数ATGM336H型号需5V供电具体以规格书为准GND GND 必须与上位机共地否则会导致数据乱码或通信失败注意1、模块上的led灯闪烁时相当于提示定位信息获取到了常量表示定位失效。2、断电重启模块更新信息状态。3、定位时天线上的陶瓷片向上陶瓷片上的金属小点一面朝向天空朝向空旷的天空高楼会遮挡信号导致定位不到。4、模块的通信默认用9600波特率通信的。二、代码部分定义部分#defineDMA_BUF_SIZE256// DMA接收缓冲区大小#defineNMEA_QUEUE_LEN8// NMEA帧队列长度#defineGNGGA_HEAD$GNGGA#defineLAT_LON_SCALE60.0f// 度分转度的系数#defineGNGGA_MIN_FIELD_CNT6typedefstruct{uint8_tvalid;// 定位有效标志1有效0无效chartime[7];// UTC时间HHMMSSfloatlatitude;// 纬度度charlat_dir;// 纬度方向N/Sfloatlongitude;// 经度度charlon_dir;// 经度方向E/Wuint8_tsat_num;// 锁定卫星数新增适配GNGGAuint8_tparse_ok;// 解析成功标志}GnssInfo_t;externGnssInfo_t gnss_info;floatnmea_degree_convert(char*str);// 度分转度externuint8_tdma_rx_buf[DMA_BUF_SIZE];externvolatileuint16_tdma_rx_len;// 开启USART2空闲中断__HAL_UART_ENABLE_IT(huart2,UART_IT_IDLE);// 启动DMA接收循环模式HAL_UART_Receive_DMA(huart2,dma_rx_buf,DMA_BUF_SIZE);voidUSART2_IRQHandler(void){HAL_UART_IRQHandler(huart2);USART2_IDLE_IRQHandler();// 处理空闲中断}// 打印定位信息voidUSART2_IDLE_IRQHandler(void){if(__HAL_UART_GET_FLAG(huart2,UART_FLAG_IDLE)!RESET){__HAL_UART_CLEAR_IDLEFLAG(huart2);// 清除空闲中断标志HAL_UART_DMAStop(huart2);// 停止DMA接收// 计算接收长度dma_rx_lenDMA_BUF_SIZE-__HAL_DMA_GET_COUNTER(hdma_usart2_rx);}}floatnmea_degree_convert(char*str){if(strNULL||strlen(str)4||strchr(str,.)NULL){return0.0f;}floatdegree0.0f;floatminute0.0f;chartemp[16]{0};intdot_posstrchr(str,.)-str;// 纬度DDMM.mmmm → 前2位度if(strlen(str)4dot_pos2){strncpy(temp,str,2);degreeatof(temp);minuteatof(str2);}// 经度DDDMM.mmmm → 前3位度elseif(strlen(str)5dot_pos3){strncpy(temp,str,3);degreeatof(temp);minuteatof(str3);}else{return0.0f;}// 防止转换后为0有效经纬度不可能为0floatresdegree(minute/LAT_LON_SCALE);return(res0.0f)?res:0.0f;}任务调用部分//获取信息voidStartTask01(void*argument){uint8_tnmea_buf[DMA_BUF_SIZE]{0};for(;;){if(dma_rx_len0){// 拷贝DMA接收的数据到临时缓冲区memcpy(nmea_buf,dma_rx_buf,dma_rx_len);nmea_buf[dma_rx_len]\0;// 字符串结束符//输出串口接收信息HAL_UART_Transmit(huart1,(uint8_t*)dma_rx_buf,dma_rx_len,8000);printf(\r\n);// 发送到NMEA解析队列osMessageQueuePut(myQueue01Handle,nmea_buf,0,100);// 重置DMA接收dma_rx_len0;memset(dma_rx_buf,0,DMA_BUF_SIZE);HAL_UART_Receive_DMA(huart2,dma_rx_buf,DMA_BUF_SIZE);}osDelay(5);}}//解析部分voidStartTask02(void*argument){uint8_tnmea_buf[DMA_BUF_SIZE]{0};for(;;){// 解析任务核心逻辑if(osMessageQueueGet(myQueue01Handle,nmea_buf,NULL,100)osOK){gnss_info.parse_ok0;char*gngga_framestrstr((char*)nmea_buf,GNGGA_HEAD);if(gngga_frame!NULLstrlen(gngga_frame)20){char*tokenNULL;char*save_ptrNULL;intfield_idx0;intfield_cnt0;// 临时变量先存储经纬度字符串等定位质量解析后再转换charlat_str[16]{0};charlon_str[16]{0};tokenstrtok_r(gngga_frame,,,save_ptr);while(token!NULL){field_cnt;if(strlen(token)0){tokenstrtok_r(NULL,,,save_ptr);field_idx;continue;}switch(field_idx){case0:// $GNGGA帧头校验if(strcmp(token,GNGGA_HEAD)!0){field_idx-1;break;}break;case1:// UTC时间HHMMSS.ssif(strlen(token)6){strncpy(gnss_info.time,token,6);gnss_info.time[6]\0;}else{memset(gnss_info.time,0,sizeof(gnss_info.time));}break;// 先存储经纬度字符串不立即转换case2:// 纬度字符串DDMM.mmmmstrncpy(lat_str,token,sizeof(lat_str)-1);break;case3:// 纬度方向N/Sif(token[0]N||token[0]S){gnss_info.lat_dirtoken[0];}else{gnss_info.lat_dir\0;}break;case4:// 经度字符串DDDMM.mmmmstrncpy(lon_str,token,sizeof(lon_str)-1);break;case5:// 经度方向E/Wif(token[0]E||token[0]W){gnss_info.lon_dirtoken[0];}else{gnss_info.lon_dir\0;}break;case6:// 定位质量核心先解析gnss_info.valid(atoi(token)1)?1:0;// 定位有效时再转换经纬度关键修复if(gnss_info.valid){if(strlen(lat_str)4)gnss_info.latitudenmea_degree_convert(lat_str);if(strlen(lon_str)5)gnss_info.longitudenmea_degree_convert(lon_str);}break;case7:// 卫星数gnss_info.sat_numatoi(token);break;default:if(field_idx8)// 解析到卫星数后停止{tokenNULL;break;}break;}if(field_idx-1){tokenNULL;break;}tokenstrtok_r(NULL,,,save_ptr);field_idx;}// 放宽最终校验条件适配实际场景if(field_cnt7// 至少7个字段核心字段gnss_info.valid1// 定位质量1gnss_info.lat_dir!\0// 纬度方向有效gnss_info.lon_dir!\0// 经度方向有效gnss_info.latitude0.0f// 纬度0有效范围gnss_info.longitude0.0f// 经度0有效范围gnss_info.sat_num1)// 卫星数≥1放宽{gnss_info.parse_ok1;// 【调试打印】解析成功提示printf(解析成功纬度%.6f%c经度%.6f%c,utc时间%s,定位质量%d卫星数%d\r\n,gnss_info.latitude,gnss_info.lat_dir,gnss_info.longitude,gnss_info.lon_dir,gnss_info.time,gnss_info.valid,gnss_info.sat_num);}else{memset(gnss_info,0,sizeof(GnssInfo_t));printf(解析失败字段数%d定位质量%d卫星数%d\r\n,field_cnt,gnss_info.valid,gnss_info.sat_num);}}}osDelay(10);}}测试效果示意图