完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
初始化 使能
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 // MyPrintf("%c",RX2_Temp); } GPS_Temp=0; //自动添加结束符 for(i=0;i } 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); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:35 , Processed in 0.809833 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号