STM32
直播中

陈秀英

7年用户 1225经验值
私信 关注
[问答]

新手求助怎样才能实现STM32F103T8U6串口的GPS信号收发呢

新手求助怎样才能实现STM32F103T8U6串口的GPS信号收发呢?

回帖(1)

李凯生

2021-12-14 11:04:15
初始化 使能


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);
         }
}
举报

更多回帖

×
20
完善资料,
赚取积分