匿名飞控写了一部分的gps解析的代码,但在实际应用时候发现了问题,使用之前给pixhawk配的gps,debug中断调试发现也是收到数据了,但是消息数全是错的很杂乱,再去翻文档,发现匿名飞控支持的gps协议为u-blox的,再去网上搜u-blox协议,发现之前用的就是u-blox协议,然后顺便又发现了个软件u-center,是专门调试u-blox协议的导航模块,然后使用串口接上gps模块,发现了波特率的设置为9600,而且可以更改,u-center使用说明网上可以搜到
再去看匿名飞控的波特率接收设置,文件目录 SRC/drivers/Drv_gps.c
void Drv_GpsPin_Init(void)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1,ENABLE );
RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOA, ENABLE );
//???????
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_UART1_P;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_UART1_S;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init ( &NVIC_InitStructure );
GPIO_PinAFConfig ( GPIOA, GPIO_PinSource9, GPIO_AF_USART1 );
GPIO_PinAFConfig ( GPIOA, GPIO_PinSource10, GPIO_AF_USART1 );
//??PC12??UART5 Tx
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init ( GPIOA, &GPIO_InitStructure );
//??PD2??UART5 Rx
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
GPIO_Init ( GPIOA, &GPIO_InitStructure );
USART_DeInit(GPS_UART);
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;//38400;//9600;//38400;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(GPS_UART,&USART_InitStructure);
USART_Cmd(GPS_UART,ENABLE);
gps_baudrate_config();
// USART_Cmd(GPS_UART,DISABLE);
USART_InitStructure.USART_BaudRate = 38400;//38400;//9600;//38400;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(GPS_UART,&USART_InitStructure);
USART_Cmd(GPS_UART,ENABLE);
gps_baudrate_config();
// USART_Cmd(GPS_UART,DISABLE);
//??UART5
//??????
USART_InitStructure.USART_BaudRate = 115200; //????????????
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8???
USART_InitStructure.USART_StopBits = USART_StopBits_1; //??????1????
USART_InitStructure.USART_Parity = USART_Parity_No; //??????
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //???????
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //???????
USART_Init ( GPS_UART, &USART_InitStructure );
USART_Cmd ( GPS_UART, ENABLE );
gps_config();
//??UART5????
USART_ITConfig ( GPS_UART, USART_IT_RXNE, ENABLE );
//??USART5
}
发现三次波特率设置,最后一次是115200,将gps波特率改为115200发现就调通了,为了方便之后更换gps,还是只改飞控,把后面两个波特率注释掉,使用默认的9600即可。
再次调试时发现,协议解析的函数和发送过来的消息不匹配,又杂乱消息发送过来。仔细去查ublox协议内容
ublox协议三个特点
1. 1字节对齐 2. low-overhead 校验算法 3. 两级消息标识符,分为class id和消息id
帧结构
• ublox数据,帧头为0xB5 0x62
• 帧头之后紧接一个字节的class id和message id(会有很多条消息)
• LENGTH为两个字节的消息长度,此长度仅仅包含PAYLOADA ,字节序为低字节序
• PAYLOAD为输出GPS数据
• CK_A 和 CK_B 都是一个字节的校验位,校验算法如下:
CK_A = 0, CK_B = 0 For(I=0;I<N;I++) { CK_A = CK_A + Buffer[I] CK_B = CK_B + CK_A }
再打开u-center,发现确实是发送多条消息,而匿名飞控只默认 解析一种消息,这条是class=1,msg=7的消息,包含了gps地理坐标和速度以及星数,其实一般我们用这条消息就够了,使用u-center可以修改成我们需要的消息,但我们总不能每个导航模块都去改吧,所以加个if判断只解析需要的消息
void GPS_data_analysis(void)
{
/********************************************************************
*说明:gps消息解析,根据ublox协议,取class id0x01 msg id 0x07的消息读取所需消息
*作者 :yh
*********************************************************************/
if (GPS_data_buff[2] == 0x01 && GPS_data_buff[3] == 0x07)//不解析其他类型的消息
{
Gps_information.last_N_vel = (float)Gps_information.N_vel; //记录上次南北向速度
Gps_information.last_E_vel = (float)Gps_information.E_vel; //记录上次东西向速度
Gps_information.satellite_num = GPS_data_buff[29]; //卫星数量
Gps_information.longitude = GPS_data_buff[30] + (GPS_data_buff[31]<<8) + (GPS_data_buff[32]<<16) + (GPS_data_buff[33]<<24); //经度
Gps_information.latitude = GPS_data_buff[34] + (GPS_data_buff[35]<<8) + (GPS_data_buff[36]<<16) + (GPS_data_buff[37]<<24); //纬度
Gps_information.N_vel = GPS_data_buff[54] + (GPS_data_buff[55]<<8) + (GPS_data_buff[56]<<16) + (GPS_data_buff[57]<<24); //南北向速度
Gps_information.E_vel = GPS_data_buff[58] + (GPS_data_buff[59]<<8) + (GPS_data_buff[60]<<16) + (GPS_data_buff[61]<<24); //东西向速度
Gps_information.N_vel /=10; //单位换算 cm/s
Gps_information.E_vel /=10; //单位换算 cm/s
if (Gps_information.satellite_num >= 6 && Gps_information.new_pos_get == 0) //卫星数量到达6颗,且第一次获取经纬度点
{
Gps_information.new_pos_get = 1;
Gps_information.start_longitude = Gps_information.longitude;
Gps_information.start_latitude = Gps_information.latitude;
Gps_information.hope_latitude = 0;
Gps_information.hope_longitude = 0;
}
if (Gps_information.new_pos_get)
{
Gps_information.latitude_offset = Gps_information.latitude - Gps_information.start_latitude;
Gps_information.longitude_offset = Gps_information.longitude - Gps_information.start_longitude;
}
Gps_information.run_heart++;
}
}
修改完再次编译运行程序,发现这次读取到了准确的gps信息,调试完成。