初始化 使能
void USART2_Init_JAVE( u32 bound )
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_DeInit(USART2);
//使能串口3的时钟 和对应GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置TX引脚GPIO
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//配置RX引脚GPIO
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//配置串口2
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
//使能串口2
USART_Cmd(USART2,ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//配置串口2接收中断
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ClearFlag(USART2, USART_FLAG_RXNE);
USART_GetFlagStatus(USART2,USART_FLAG_TC); /* 先读SR,再写DR */
}
串口2中断函数:
void RX2_Handler( void )
{
char temp = 0;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
{
temp = USART_ReceiveData( USART2 ); /* 读取USART2数据,自动清零标志位 RXNE */
if( RX2_Point <= 1999)
{
RX2_Temp[RX2_Point] = temp;
RX2_Point++;
}
else RX2_Point=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
串口2扫描函数:
unsigned short USART2_Scan(u16 *len)
{
unsigned short int ftemp = 0;
ftemp = RX2_Point;
*len=0;
if( ftemp != 0 )
{
delay_ms(100);
while ( ftemp != RX2_Point )
{
ftemp = RX2_Point;
delay_ms(100);
}
RX2_Point = 0; /* 重置指针 */
*len= ftemp;
return 1; /* 扫描到数据,返回1 */
}
return 0;
}
GPS驱动:
//配置UBLOX NEO-6的更新速率
//measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz)
//reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)
//返回值:0,发送成功;其他,发送失败.
unsigned char Ublox_Cfg_Rate(unsigned short measrate,unsigned char reftime)
{
_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF;
if(measrate<200)return 1; //小于200ms,直接退出
cfg_rate->header=0X62B5; //cfg header
cfg_rate->id=0X0806; //cfg rate id
cfg_rate->dlength=6; //数据区长度为6个字节.
cfg_rate->measrate=measrate;//脉冲间隔,ms
cfg_rate->navrate=1; //导航速率(周期),固定为1
cfg_rate->timeref=reftime; //参考时间为GPS时间
Ublox_CheckSum((unsigned char*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
// while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成
// UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate));//通过dma发送出去
Ublox_Send_Date((unsigned char*)cfg_rate,sizeof(_ublox_cfg_rate));//发送数据给NEO-6M
return Ublox_Cfg_Ack_Check();
}
GPS初始化:
unsigned char GPS_Init(void)
{
unsigned char key = 0xFF,cnt=0; //保存配置成功的标志,成功时返回的值是0;
MyPrintf("GPS 初始化rn");
Ublox_Cfg_Prt(38400); //重新设置模块的波特率为38400
while((Ublox_Cfg_Rate(2000,1)!=0)&&key) //持续判断,直到可以检查到NEO-6M,且数据保存成功
{ MyPrintf("2");
USART2_Init_JAVE( 38400 ); //初始化串口2波特率为9600(EEPROM没有保存数据的时候,波特率为9600.)
Ublox_Cfg_Prt(38400); //重新设置模块的波特率为38400
if(++cnt>=5) return 1; //错误
key=Ublox_Cfg_Cfg_Save(); //保存配置,配置成功,返回0
delay_ms(50);
}
return 0;
}
算法处理
//分析GPGGA信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GPGGA_Analysis(GPS_PacketTypeDef *GPS_Packet,u8 *buf)
{
unsigned char *p1,dx,posx;
unsigned int temp;
float rs;
p1=(unsigned char *)strstr((const char *)buf,"$GPGGA"); //此处可改为"$GPGGA"
posx=NMEA_Comma_Pos(p1,9); //得到海拔高度
if(posx!=0XFF){
GPS_Packet->altitude=NMEA_Str2num(p1+posx,&dx);
MyPrintf("altitude=%drn",GPS_Packet->altitude);
}
posx=NMEA_Comma_Pos(p1,2); //得到纬度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
GPS_Packet->latitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2); //得到'
GPS_Packet->latitude=GPS_Packet->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为°
MyPrintf("latitude=%drn",GPS_Packet->latitude);
}
posx=NMEA_Comma_Pos(p1,4); //得到经度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
GPS_Packet->longitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2); //得到'
GPS_Packet->longitude=GPS_Packet->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为°
MyPrintf("longitude=%drn",GPS_Packet->longitude);
}
posx=NMEA_Comma_Pos(p1,6); //定位状态
if(posx!=0XFF){
GPS_Packet->status=*(p1+posx)-'0';
MyPrintf("status=%drn",GPS_Packet->status);
}
}
GPS测试主程序
unsigned char GPS_Run(void)
{
unsigned char flag=0; //定位信息成功标志
unsigned short rxlen,i; //rxlen:数据长度
unsigned char cnt=0;
while(1)
{
if(cnt>2) {sign_run=1;return 0;}
cnt++;
rxlen=0;
USART2_Scan(&rxlen);
if(rxlen !=0)
{
for(i=0;i
GPS_Temp
=RX2_Temp;
// MyPrintf("%c",RX2_Temp);
}
GPS_Temp=0; //自动添加结束符
for(i=0;i
MyPrintf("%c",GPS_Temp);
}
MyPrintf("rn");
if(GPS_Check(GPS_Temp)!=0) {
MyPrintf("无效定位数据rn");
continue ;
}
MyPrintf("开始解析定位数据rn");
NMEA_GPGGA_Analysis(&GPS_Packet,(unsigned char*)GPS_Temp);
//分析GPS模块发送回来的数据,提取经纬度信息并换算成度
flag = GPS_Packet.status; //定位成功的标志
if(flag == 1 || flag == 2) //定位成功->读取数据存入MSG数据包并退出
{
MyPrintf("GPS successrn");
GPS_Show( );
Task_LED( );
return 1;
}
}
delay_ms(50);
}
}
初始化 使能
void USART2_Init_JAVE( u32 bound )
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_DeInit(USART2);
//使能串口3的时钟 和对应GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置TX引脚GPIO
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//配置RX引脚GPIO
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//配置串口2
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
//使能串口2
USART_Cmd(USART2,ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//配置串口2接收中断
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ClearFlag(USART2, USART_FLAG_RXNE);
USART_GetFlagStatus(USART2,USART_FLAG_TC); /* 先读SR,再写DR */
}
串口2中断函数:
void RX2_Handler( void )
{
char temp = 0;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
{
temp = USART_ReceiveData( USART2 ); /* 读取USART2数据,自动清零标志位 RXNE */
if( RX2_Point <= 1999)
{
RX2_Temp[RX2_Point] = temp;
RX2_Point++;
}
else RX2_Point=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
串口2扫描函数:
unsigned short USART2_Scan(u16 *len)
{
unsigned short int ftemp = 0;
ftemp = RX2_Point;
*len=0;
if( ftemp != 0 )
{
delay_ms(100);
while ( ftemp != RX2_Point )
{
ftemp = RX2_Point;
delay_ms(100);
}
RX2_Point = 0; /* 重置指针 */
*len= ftemp;
return 1; /* 扫描到数据,返回1 */
}
return 0;
}
GPS驱动:
//配置UBLOX NEO-6的更新速率
//measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz)
//reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)
//返回值:0,发送成功;其他,发送失败.
unsigned char Ublox_Cfg_Rate(unsigned short measrate,unsigned char reftime)
{
_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF;
if(measrate<200)return 1; //小于200ms,直接退出
cfg_rate->header=0X62B5; //cfg header
cfg_rate->id=0X0806; //cfg rate id
cfg_rate->dlength=6; //数据区长度为6个字节.
cfg_rate->measrate=measrate;//脉冲间隔,ms
cfg_rate->navrate=1; //导航速率(周期),固定为1
cfg_rate->timeref=reftime; //参考时间为GPS时间
Ublox_CheckSum((unsigned char*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
// while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成
// UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate));//通过dma发送出去
Ublox_Send_Date((unsigned char*)cfg_rate,sizeof(_ublox_cfg_rate));//发送数据给NEO-6M
return Ublox_Cfg_Ack_Check();
}
GPS初始化:
unsigned char GPS_Init(void)
{
unsigned char key = 0xFF,cnt=0; //保存配置成功的标志,成功时返回的值是0;
MyPrintf("GPS 初始化rn");
Ublox_Cfg_Prt(38400); //重新设置模块的波特率为38400
while((Ublox_Cfg_Rate(2000,1)!=0)&&key) //持续判断,直到可以检查到NEO-6M,且数据保存成功
{ MyPrintf("2");
USART2_Init_JAVE( 38400 ); //初始化串口2波特率为9600(EEPROM没有保存数据的时候,波特率为9600.)
Ublox_Cfg_Prt(38400); //重新设置模块的波特率为38400
if(++cnt>=5) return 1; //错误
key=Ublox_Cfg_Cfg_Save(); //保存配置,配置成功,返回0
delay_ms(50);
}
return 0;
}
算法处理
//分析GPGGA信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GPGGA_Analysis(GPS_PacketTypeDef *GPS_Packet,u8 *buf)
{
unsigned char *p1,dx,posx;
unsigned int temp;
float rs;
p1=(unsigned char *)strstr((const char *)buf,"$GPGGA"); //此处可改为"$GPGGA"
posx=NMEA_Comma_Pos(p1,9); //得到海拔高度
if(posx!=0XFF){
GPS_Packet->altitude=NMEA_Str2num(p1+posx,&dx);
MyPrintf("altitude=%drn",GPS_Packet->altitude);
}
posx=NMEA_Comma_Pos(p1,2); //得到纬度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
GPS_Packet->latitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2); //得到'
GPS_Packet->latitude=GPS_Packet->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为°
MyPrintf("latitude=%drn",GPS_Packet->latitude);
}
posx=NMEA_Comma_Pos(p1,4); //得到经度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
GPS_Packet->longitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2); //得到'
GPS_Packet->longitude=GPS_Packet->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为°
MyPrintf("longitude=%drn",GPS_Packet->longitude);
}
posx=NMEA_Comma_Pos(p1,6); //定位状态
if(posx!=0XFF){
GPS_Packet->status=*(p1+posx)-'0';
MyPrintf("status=%drn",GPS_Packet->status);
}
}
GPS测试主程序
unsigned char GPS_Run(void)
{
unsigned char flag=0; //定位信息成功标志
unsigned short rxlen,i; //rxlen:数据长度
unsigned char cnt=0;
while(1)
{
if(cnt>2) {sign_run=1;return 0;}
cnt++;
rxlen=0;
USART2_Scan(&rxlen);
if(rxlen !=0)
{
for(i=0;i
GPS_Temp=RX2_Temp;
// MyPrintf("%c",RX2_Temp);
}
GPS_Temp=0; //自动添加结束符
for(i=0;i
MyPrintf("%c",GPS_Temp);
}
MyPrintf("rn");
if(GPS_Check(GPS_Temp)!=0) {
MyPrintf("无效定位数据rn");
continue ;
}
MyPrintf("开始解析定位数据rn");
NMEA_GPGGA_Analysis(&GPS_Packet,(unsigned char*)GPS_Temp);
//分析GPS模块发送回来的数据,提取经纬度信息并换算成度
flag = GPS_Packet.status; //定位成功的标志
if(flag == 1 || flag == 2) //定位成功->读取数据存入MSG数据包并退出
{
MyPrintf("GPS successrn");
GPS_Show( );
Task_LED( );
return 1;
}
}
delay_ms(50);
}
}
举报