完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1.GPS数据格式
帧格式形如: a a c c c , d d d , d d d , … , d d d ∗ h h ( C R ) ( L F ) 1 、 “ aaccc,ddd,ddd,…,ddd*hh(CR)(LF) 1、 “aaccc,ddd,ddd,…,ddd∗hh(CR)(LF)1、“” :帧命令起始位 2、 aaccc:地址域,前两位为识别符(aa),后三位为语句名(ccc) 3、 ddd…ddd:数据 4、 “” :校验和前缀(也可以作为语句数据结束的标志) 5、 hh:校验和(check sum), $与之间所有字符ASCII码的校验和(各字节做异或运算,得到 校验和后,再转换16进制格式的ASCII字符) 6、 (CR)(LF):帧结束,回车和换行符 一帧数据格式 $GPRMC,032524.00,A,2303.00591,N,11324.42138,E,0.689,270814,D7E $GPVTG,T,M,0.689,N,1.276,K,D23 $GPGGA,032524.00,2303.00591,N,11324.42138,E,2,12,0.78,13.2,M,-5.1,M,00007E $GPGSA,A,3,01,11,08,30,07,32,13,42,28,04,27,17,1.18,0.78,0.8901 $GPGSV,5,1,17,01,69,151,35,04,34,198,31,07,75,258,26,08,79,286,1674 $GPGSV,5,2,17,11,77,052,28,13,15,203,20,16,07,101,17,15,254,2774 $GPGSV,5,3,17,19,29,036,40,20,12,162,23,04,181,08,27,06,052,157A $GPGSV,5,4,17,28,21,314,19,30,49,311,17,32,10,122,20,42,50,128,3973 $GPGSV,5,5,17,50,45,122,334A $GPGLL,2303.00591,N,11324.42138,E,032524.00,A,D68 串口接收流程 定义GPS数据结构体 typedef struct SaveData { char GPS_Buffer[GPS_Buffer_Length]; char isGetData; char isParseData; char UTCTime[UTCTime_Length]; char latitude[latitude_Length]; char N_S[N_S_Length]; char longitude[longitude_Length]; char E_W[E_W_Length]; char isUsefull; } _SaveData; 只接收$GPRMC的内容 开启串口接收中断,接收一个字符存入res中 在串口中断回调函数中,判断当接收到‘$’时是接收到新的一行,u16 point为0 将每次回调接收的res存入 USART_RX_BUF[point]中,[USART_REC_LEN最大200] 判定当USART_RX_BUF[0] == 'KaTeX parse error: Expected 'EOF', got '&' at position 3: ' &̲& USART_RX_BUF[…GPRMC行时 当res==‘n’,即一行结束 将USART_RX_BUF,中point1长的数据存入char GPS_Buffer[GPS_Buffer_Length=80]中,在存入之前要将GPS_Buffer全部清空 判定GPS获得数据isGetData=true,point长度清空, USART_RX_BUF[USART_REC_LEN]清空 如果point >= USART_REC_LEN,point= USART_REC_LEN; 解析GPS数据 如果isGetData==true,令其复为false,打印输出GPS_Buffer以供查看 $GPRMC,032525.00,A,2303.00594,N,11324.42136,E 通过提取subString=strstr(GPS_Buffer, “,”),循环6次 2. 当第一次循环,找不到,时报错errorLog(1);输出error 1; 3. 如果第一次能找到,subString+1到逗号之后 4. 再令subStringNext = strstr(subString, “,”)下一个逗号,如果找不到,则报错2 5. 将每一个从subString开始subStringNext - subString范围的数据依次memcpy存入时间,有效,维度,N,经度,E中 6. 判定isParseData=true解析完成,如果有效为A,isUsefull = true,否则为false 7. 打印GPS数据中各个成员,判定是否有效,如果无效,给定一个默认值 gps.h 编写GPS结构体用来存放接收GPRMC缓存和提取经纬度信息 #define GPS_Buffer_Length 80 #define true 1 #define false 0 #define latitude_Length 10 #define longitude_Length 11 typedef struct GPS_Data { char GPS_Buffer[GPS_Buffer_Length]; char isGetData; char isUseful; char latitude[latitude_Length]; char longitude[longitude_Length]; }_GPS_Data; / void user_common_init(void);//开启串口接收中断,初始化结构体 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//接收缓存 void parseGPS(void);//解析提取经纬度 void printGPS(void);//判断A/V是否有效,否则输出默认经纬度 extern _GPS_Data GPSData; GPS.c #define u8 uint8_t #define u16 uint16_t u8 rdata[1]; u8 rdata1[1]; u16 point; #define RX_BUF_MAXLEN 200 char USART_RX_BUF[RX_BUF_MAXLEN]; _GPS_Data GPSData; u8 latitude[]="2303.00591"; u8 longitude[]="11324.42138"; void user_common_init(void) { do{ }while(HAL_OK!=HAL_UART_Receive_IT(&huart5,(u8*)&rdata,1));//开启接收中断 //清空GPSData memset(GPSData.GPS_Buffer,0,GPS_Buffer_Length); memset(GPSData.latitude,0,latitude_Length); memset(GPSData.longitude,0,longitude_Length); GPSData.isGetData=false; GPSData.isUseful=false; //清空串口发送协议的起止符 serial_rx_data.syn=serial_rx_data.syn_CR=serial_rx_data.syn_LF=serial_rx_data.type=0; } //接收$GPRMC存入GPSData.buffer void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { u8 rec; if(huart->Instance==UART5) { rec=rdata[0]; if(rec=='$') { point=0; } USART_RX_BUF[point++]=rec; if(USART_RX_BUF[0]=='$'&&USART_RX_BUF[4]=='M'&&USART_RX_BUF[5]=='C') { if(rec=='n') { memset(GPSData.GPS_Buffer,0,GPS_Buffer_Length); memcpy(GPSData.GPS_Buffer,USART_RX_BUF,point); memset(USART_RX_BUF,0,RX_BUF_MAXLEN); GPSData.isGetData=true; point=0; } } if(point>=RX_BUF_MAXLEN) { point=RX_BUF_MAXLEN; } HAL_UART_Receive_IT(&huart5,(u8*)&rdata,1); } } //解析GPS void parseGPS() { char *subString; char *subNext; if(GPSData.isGetData) { GPSData.isGetData=false; //HAL_UART_Transmit(&huart1,(u8*)GPSData.GPS_Buffer,sizeof(GPSData.GPS_Buffer),1000); for(int i=0;i<9;i++) { if((subString=strstr(GPSData.GPS_Buffer,","))!=NULL) { subString++; if((subNext=strstr(subString,","))!=NULL) { char usefullBuffer[2]; switch(i) { case 1:memcpy(usefullBuffer,subString,subNext-subString); case 2:memcpy(GPSData.latitude,subString,subNext-subString); break; case 4:memcpy(GPSData.longitude,subString,subNext-subString); break; default:break; } subString=subNext; if(usefullBuffer[0]=='A') GPSData.isUseful=true; else if(usefullBuffer[0]=='V') { GPSData.isUseful=false; } } } } } } //使用默认 void printGPS() { parseGPS(); if(!GPSData.isUseful)//如果无效,则使用默认GPS { memcpy(GPSData.latitude,latitude,sizeof(latitude)); memcpy(GPSData.longitude,longitude,sizeof(longitude)); } GPSData.isGetData=false; } } 串口发送协议 使用结构体和枚举型,选择不同类型TYPE数据发送 #ifndef _USER_PROTCOL_H_ #define _USER_PROTCOL_H_ #include "stdio.h" /*protcol*/ enum _ptl_type { VAL_START=0, VAL_POSE, VAL_IMU_RAW, VAL_VEL, VAL_PID, VAL_IMU, VAL_GPS, VAL_END }; #define _SERIAL_SYN_CODE_START 0XFA #pragma pack(1) typedef struct _serial_data { uint8_t syn; uint8_t type; union{ struct{ float liner[3],angular[3]; }vel; struct{ bool rot_ok,acc_ok,mag_ok; double rot[3],acc[3],mag[3]; }imu; struct{ char latitude[11],longitude[12]; }gps; float pid[3]; }dat; uint8_t syn_CR; uint8_t syn_LF; }serialData; #pragma pack() #endif 发送 void serial2_ros_data() { static serialData data; data.syn=_SERIAL_SYN_CODE_START; data.syn_CR='r'; data.syn_LF='n'; float *quar_rpy; /*************************************VEL*********************************************/ while(HAL_UART_GetState(&huart4)==HAL_UART_STATE_BUSY_TX_RX) {} data.type=VAL_POSE; data.dat.vel.liner[0]=xrobot->robot_linear_vel_x; data.dat.vel.liner[1]=0; data.dat.vel.liner[2]=0; HAL_UART_Transmit_DMA(&huart4,(uint8_t*)&data,sizeof(serialData)); /******************************************IMU*************************************/ quar_rpy=imu_print(); while(HAL_UART_GetState(&huart4)==HAL_UART_STATE_BUSY_TX_RX){} data.type=VAL_IMU; data.dat.vel.angular[0]=quar_rpy[0]; data.dat.vel.angular[1]=quar_rpy[1]; data.dat.vel.angular[2]=quar_rpy[2]; HAL_UART_Transmit_DMA(&huart4,(uint8_t*)&data,sizeof(data)); /***************************GPS***********************/ while(HAL_UART_GetState(&huart4)==HAL_UART_STATE_BUSY_TX_RX){} data.type=VAL_GPS; memcpy(data.dat.gps.latitude, GPSData.latitude,sizeof(GPSData.latitude)); memcpy(data.dat.gps.longitude, GPSData.longitude,sizeof(GPSData.longitude)); HAL_UART_Transmit_DMA(&huart4,(uint8_t*)&data,sizeof(serialData)); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 00:33 , Processed in 0.771221 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号