MSP430与ATK-NEO-6M GPS模块

嵌入式ARM 2019-04-25 16:07

本文来源于“21ic TI微控制器&处理器论坛”,原贴见底部“阅读原文”


近短时间在网上买了一个GPS模块,正好正在学习MSP430单片机,于是决心将GPS模块与MSP430结合起来,同时将代码贴出来,发现网上搜到好多资料都要注册才能下载,有些还要钱。自己动脑,才能自娱自乐。


一、测试篇


刚拿到ATK-NEO-6M这个型号的GPS模块,有点不大相信,近100块的东西居然只有3cm那么大一点。之前在网上下载了相关的资料,第一次快速测试肯定是借助电脑,正好msp430开发板上有max232模块,直接将GPS模块的TX接max232的TX,RX同样。PC端安装u-center,u-center 是由ublox 公司提供的GPS 评估软件,功能十分强大,可以对我们的ATK-NEO-6M GPS 模块进行全面的测试。安装好后,点击连接/断开按钮,选择你的串口号,一般测试都是选择自动配置按钮,也就是那个魔法样式的按钮,单击后会自己配置波特率,如果正常通讯的话,在最右下角的状态栏会显示黄色,当GPS模块已经定位成功的话,会在界面上显示当前的基本信息,如经度,纬度等。想查看接收到的原本信息,按F8键即可显示。我测试后工作正常,在屋里基本能搜到9颗卫星信号。


二、开发篇


刚拿到GPS模块,感觉要是开发起来会很麻烦,后来经过实验,其实很简单,因为卖家提供的资料已经足够开发。句段的分析函数都已提供,我们只需将接口写好即可。接下来先看看我的硬件环境。


硬件环境:MPS430开发板,FYD12864LCD显示屏,USB转串口线,ATK-NEO-6M GPS模块


软件环境:IAR集成开发环境,串口调试工具,Secure CRT

实现目标:MSP430通过串口2接收到GPS信息,显示在LCD上,同时通过串口1发送接收到的数据到PC。


1. 先把msp430的句段分析部分调通。


思路:将厂商提过的GPS语句分析部分代码移植过来,串口手动发送GPS数据,分析完后在LCD上显示。

将厂商提供的GPS语句分析代码贴出,(在此仅作为参考学习只用)


GPS.h


<font size="2">#ifndef __GPS_H#define __GPS_H
#include <math.h>#include <string.h>#include <stdarg.h>#include <stdio.h>
#include "../inc/uart.h"
//GPS NMEA-0183协议重要参数结构体定义 //卫星信息typedef struct { uchar num; //卫星编号 uchar eledeg; //卫星仰角 uint azideg; //卫星方位角 uchar sn; //信噪比 }nmea_slmsg; //UTC时间信息typedef struct { uint year; //年份 uchar month; //月份 uchar date; //日期 uchar hour; //小时 uchar min; //分钟 uchar sec; //秒钟}nmea_utc_time; //NMEA 0183 协议解析后数据存放结构体typedef struct { uchar svnum; //可见卫星数 nmea_slmsg slmsg[12]; //最多12颗卫星 nmea_utc_time utc; //UTC时间 int latitude; //纬度 分扩大100000倍,实际要除以100000 uchar nshemi; //北纬/南纬,N:北纬;S:南纬 int longitude; //经度 分扩大100000倍,实际要除以100000 uchar ewhemi; //东经/西经,E:东经;W:西经 uchar gpssta; //GPS状态:0,未定位;1,非差分定位;2,差分定位;6,正在估算. uchar posslnum; //用于定位的卫星数,0~12. uchar possl[12]; //用于定位的卫星编号 uchar fixmode; //定位类型:1,没有定位;2,2D定位;3,3D定位 uint pdop; //位置精度因子 0~500,对应实际值0~50.0 uint hdop; //水平精度因子 0~500,对应实际值0~50.0 uint vdop; //垂直精度因子 0~500,对应实际值0~50.0
int altitude; //海拔高度,放大了10倍,实际除以10.单位:0.1m uint speed; //地面速率,放大了1000倍,实际除以10.单位:0.001公里/小时 }nmea_msg; //////////////////////////////////////////////////////////////////////////////////////////////////// //UBLOX NEO-6M 时钟脉冲配置结构体typedef struct { uint header; //cfg header,固定为0X62B5(小端模式) uint id; //CFG TP ID:0X0706 (小端模式) uint dlength; //数据长度 int interval; //时钟脉冲间隔,单位为us int length; //脉冲宽度,单位为us signed char status; //时钟脉冲配置:1,高电平有效;0,关闭;-1,低电平有效. uchar timeref; //参考时间:0,UTC时间;1,GPS时间;2,当地时间. uchar flags; //时间脉冲设置标志 uchar reserved; //保留 signed short antdelay; //天线延时 signed short rfdelay; //RF延时 signed int userdelay; //用户延时 uchar cka; //校验CK_A uchar ckb; //校验CK_B }_ublox_cfg_tp; //UBLOX NEO-6M 刷新速率配置结构体typedef struct { uint header; //cfg header,固定为0X62B5(小端模式) uint id; //CFG RATE ID:0X0806 (小端模式) uint dlength; //数据长度 uint measrate; //测量时间间隔,单位为ms,最少不能小于200ms(5Hz) uint navrate; //导航速率(周期),固定为1 uint timeref; //参考时间:0=UTC Time;1=GPS Time; uchar cka; //校验CK_A uchar ckb; //校验CK_B }_ublox_cfg_rate; int NMEA_Str2num(uchar *buf,uchar*dx);void GPS_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPGSV_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPGGA_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uchar *buf);void NMEA_GPVTG_Analysis(nmea_msg *gpsx,uchar *buf);void Ublox_Cfg_Tp(int interval,int length,signed char status);void Ublox_Cfg_Rate(uint measrate,uchar reftime);
#endif  /* __GPS_H  */</font>


gps.c


#include "../inc/gps.h"
/*******************************************函数名称:NMEA_Comma_Pos功 能:从buf里面得到第cx个逗号所在的位置参 数:返回值 :0~0XFE,代表逗号所在位置的偏移 0XFF,代表不存在第cx个逗号********************************************/uchar NMEA_Comma_Pos(uchar *buf,uchar cx){ uchar *p=buf; while(cx) { if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号 if(*buf==',')cx--; buf++; } return buf-p; }
/*******************************************函数名称:NMEA_Pow功 能:m^n函数参 数:返回值 :m^n次方.********************************************/int NMEA_Pow(uchar m,uchar n){ int result=1; while(n--)result*=m; return result;}
/*******************************************函数名称:NMEA_Str2num功 能:str转换为数字,以','或者'*'结束参 数:buf:数字存储区;dx:小数点位数,返回给调用函数返回值 :转换后的数值********************************************/int NMEA_Str2num(uchar *buf,uchar*dx){ uchar *p=buf; int ires=0,fres=0; uchar ilen=0,flen=0,i; uchar mask=0; int res; while(1) //得到整数和小数的长度 { if(*p=='-'){mask|=0X02;p++;} //是负数 if(*p==','||(*p=='*'))break; //遇到结束了 if(*p=='.'){mask|=0X01;p++;} //遇到小数点了 else if(*p>'9'||(*p<'0')) //有非法字符 { ilen=0; flen=0; break; } if(mask&0X01)flen++; else ilen++; p++; } if(mask&0X02)buf++; //去掉负号 for(i=0;i<ilen;i++) //得到整数部分数据 { ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0'); } if(flen>5)flen=5; //最多取5位小数 *dx=flen; //小数点位数 for(i=0;i<flen;i++) //得到小数部分数据 { fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0'); } res=ires*NMEA_Pow(10,flen)+fres; if(mask&0X02)res=-res; return res;}
/*******************************************函数名称:NMEA_GPGSV_Analysis功 能:分析GPGSV信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void NMEA_GPGSV_Analysis(nmea_msg *gpsx,uchar *buf){ uchar *p,*p1,dx; uchar len,i,j,slx=0; uchar posx; p=buf; p1=(uchar*)strstr((const char *)p,"$GPGSV"); len=p1[7]-'0'; //得到GPGSV的条数 posx=NMEA_Comma_Pos(p1,3); //得到可见卫星总数 if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx); for(i=0;i<len;i++) { p1=(uchar*)strstr((const char *)p,"$GPGSV"); for(j=0;j<4;j++) { posx=NMEA_Comma_Pos(p1,4+j*4); if(posx!=0XFF)gpsx->slmsg[slx].num=NMEA_Str2num(p1+posx,&dx); //得到卫星编号 else break; posx=NMEA_Comma_Pos(p1,5+j*4); if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx);//得到卫星仰角 else break; posx=NMEA_Comma_Pos(p1,6+j*4); if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx);//得到卫星方位角 else break; posx=NMEA_Comma_Pos(p1,7+j*4); if(posx!=0XFF)gpsx->slmsg[slx].sn=NMEA_Str2num(p1+posx,&dx); //得到卫星信噪比 else break; slx++; } p=p1+1;//切换到下一个GPGSV信息 } }
/*******************************************函数名称:NMEA_GPGGA_Analysis功 能:分析GPGGA信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void NMEA_GPGGA_Analysis(nmea_msg *gpsx,uchar *buf){ uchar *p1,dx; uchar posx; p1=(uchar*)strstr((const char *)buf,"$GPGGA"); posx=NMEA_Comma_Pos(p1,6); //得到GPS状态 if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx); posx=NMEA_Comma_Pos(p1,7); //得到用于定位的卫星数 if(posx!=0XFF)gpsx->posslnum=NMEA_Str2num(p1+posx,&dx); posx=NMEA_Comma_Pos(p1,9); //得到海拔高度 if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx); }
/*******************************************函数名称:NMEA_GPGSA_Analysis功 能:分析GPGSA信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf){ uchar *p1,dx; uchar posx; uchar i; p1=(uchar*)strstr((const char *)buf,"$GPGSA"); posx=NMEA_Comma_Pos(p1,2); //得到定位类型 if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx); for(i=0;i<12;i++) //得到定位卫星编号 { posx=NMEA_Comma_Pos(p1,3+i); if(posx!=0XFF)gpsx->possl[i]=NMEA_Str2num(p1+posx,&dx); else break; } posx=NMEA_Comma_Pos(p1,15); //得到PDOP位置精度因子 if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx); posx=NMEA_Comma_Pos(p1,16); //得到HDOP位置精度因子 if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx); posx=NMEA_Comma_Pos(p1,17); //得到VDOP位置精度因子 if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx); }
/*******************************************函数名称:NMEA_GPRMC_Analysis功 能:分析GPRMC信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uchar *buf){ uchar *p1,dx; uchar posx; int temp; float rs; p1=(uchar*)strstr((const char *)buf,"$GPRMC"); posx=NMEA_Comma_Pos(p1,1); //得到UTC时间 if(posx!=0XFF) { temp=NMEA_Str2num(p1+posx,&dx)/NMEA_Pow(10,dx); //得到UTC时间,去掉ms gpsx->utc.hour=temp/10000; gpsx->utc.min=(temp/100)%100; gpsx->utc.sec=temp%100; } posx=NMEA_Comma_Pos(p1,3); //得到纬度 if(posx!=0XFF) { temp=NMEA_Str2num(p1+posx,&dx); gpsx->latitude=temp/NMEA_Pow(10,dx+2); //得到° rs=temp%NMEA_Pow(10,dx+2); //得到' gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° } posx=NMEA_Comma_Pos(p1,4); //南纬还是北纬 if(posx!=0XFF)gpsx->nshemi=*(p1+posx); posx=NMEA_Comma_Pos(p1,5); //得到经度 if(posx!=0XFF) { temp=NMEA_Str2num(p1+posx,&dx); gpsx->longitude=temp/NMEA_Pow(10,dx+2); //得到° rs=temp%NMEA_Pow(10,dx+2); //得到' gpsx->longitude=gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° } posx=NMEA_Comma_Pos(p1,6); //东经还是西经 if(posx!=0XFF)gpsx->ewhemi=*(p1+posx); posx=NMEA_Comma_Pos(p1,9); //得到UTC日期 if(posx!=0XFF) { temp=NMEA_Str2num(p1+posx,&dx); //得到UTC日期 gpsx->utc.date=temp/10000; gpsx->utc.month=(temp/100)%100; gpsx->utc.year=2000+temp%100; } }
/*******************************************函数名称:NMEA_GPVTG_Analysis功 能:分析GPVTG信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void NMEA_GPVTG_Analysis(nmea_msg *gpsx,uchar *buf){ uchar *p1,dx; uchar posx; p1=(uchar*)strstr((const char *)buf,"$GPVTG"); posx=NMEA_Comma_Pos(p1,7); //得到地面速率 if(posx!=0XFF) { gpsx->speed=NMEA_Str2num(p1+posx,&dx); if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx); //确保扩大1000倍 }}
/*******************************************函数名称:GPS_Analysis功 能:提取NMEA-0183信息参 数:gpsx:nmea信息结构体;buf:接收到的GPS数据缓冲区首地址返回值 :********************************************/void GPS_Analysis(nmea_msg *gpsx,uchar *buf){ NMEA_GPGSV_Analysis(gpsx,buf); //GPGSV解析 NMEA_GPGGA_Analysis(gpsx,buf); //GPGGA解析 NMEA_GPGSA_Analysis(gpsx,buf); //GPGSA解析 NMEA_GPRMC_Analysis(gpsx,buf); //GPRMC解析 NMEA_GPVTG_Analysis(gpsx,buf); //GPVTG解析}
/*******************************************函数名称:Ublox_CheckSum功 能:GPS校验和计算参 数:buf:数据缓存区首地址;len:数据长度;cka,ckb:两个校验结果.返回值 :********************************************/void Ublox_CheckSum(uchar *buf,uint len,uchar* cka,uchar*ckb){ uint i; *cka=0;*ckb=0; for(i=0;i<len;i++) { *cka=*cka+buf[i]; *ckb=*ckb+*cka; }}
/*******************************************函数名称:Ublox_Cfg_Tp功 能:配置UBLOX NEO-6的时钟脉冲输出参 数:interval:脉冲间隔 length:脉冲宽度 status:脉冲配置:1,高电平有效;0,关闭;-1,低电平有效.返回值 :********************************************/void Ublox_Cfg_Tp(int interval,int length,signed char status){/* _ublox_cfg_tp *cfg_tp=(_ublox_cfg_tp *)USART2_TX_BUF; cfg_tp->header=0X62B5; //cfg header cfg_tp->id=0X0706; //cfg tp id cfg_tp->dlength=20; //数据区长度为20个字节. cfg_tp->interval=interval; //脉冲间隔,us cfg_tp->length=length; //脉冲宽度,us cfg_tp->status=status; //时钟脉冲配置 cfg_tp->timeref=0; //参考UTC 时间 cfg_tp->flags=0; //flags为0 cfg_tp->reserved=0; //保留位为0 cfg_tp->antdelay=820; //天线延时为820ns cfg_tp->rfdelay=0; //RF延时为0ns cfg_tp->userdelay=0; //用户延时为0ns Ublox_CheckSum((uchar*)(&cfg_tp->id),sizeof(_ublox_cfg_tp)-4,&cfg_tp->cka,&cfg_tp->ckb); while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成 UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_tp)); //通过dma发送出去 */}
/*******************************************函数名称:Ublox_Cfg_Rate功 能:配置UBLOX NEO-6的更新速率 参 数:measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz) reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)返回值 :********************************************/void Ublox_Cfg_Rate(uint measrate,uchar reftime){/* _ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF; if(measrate<200)return; //小于200ms,直接退出 cfg_rate->header=0X62B5; //cfg header cfg_rate->id=0X0806; //cfg rate id cfg_rate->dlength=6; //数据区长度为6个字节. cfg_rate->measrate=measrate;//脉冲间隔,us cfg_rate->navrate=1; //导航速率(周期),固定为1 cfg_rate->timeref=reftime; //参考时间为GPS时间 Ublox_CheckSum((uchar*)(&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发送出去 */}


以上为GPS相关代码,下面为MSP430相关代码

uart.h


#ifndef _UART_H_#define _UART_H_
#include <msp430f149.h>
void UartInit(void);void SendData(uchar dat);void SendByte(uchar *pData);void SendString(char *s);
#endif /* __UART_H */


uart.c


#include "../inc/uart.h"
void UartInit(void){ //串口1配置 P3DIR |= BIT4; //p3.4设为输出 P3SEL |= BIT4 + BIT5; //P3.4,5设置为TXD/RXD ME1 |= UTXE0 + URXE0; //enable tx and rx UCTL0 = 0x00; //reset as 0 UCTL0 |= CHAR; //8 bit transfer UTCTL0 = 0x00; //reset as 0 UTCTL0 |= SSEL0; //select aclk(8M) UBR00 = 0x03; UBR10 = 0x00; //波特率为 9600(ACLK为8MHz) UMCTL0 = 0x4A; UCTL0 &= ~SWRST; // reset UART IE1 |= URXIE0; // enable rx inerrupt //串口2配置 P3DIR |= BIT6; //p3.6设为输出 P3SEL |= BIT6 + BIT7; //P3.6,7设置为TXD/RXD ME2 |= URXE1 + UTXE1; //enable tx and rx UCTL1 = 0x00; //reset as 0 UCTL1 |= CHAR; //8 bit transfer UTCTL1 = 0x00; //reset as 0 UTCTL1 |= SSEL0; //select mclk UBR01 = 0x03; UBR11 = 0x00; //波特率为 9600(ACLK为8MHz) UMCTL1 = 0x4A; UCTL1 &= ~SWRST; // reset UART IE2 |= URXIE1; // enable rx inerrupt}
void SendData(unsigned char dat){ TXBUF0 = dat; while(!(IFG1 & UTXIFG0)); //IFG1 &= ~(UTXIFG0);}
void SendString(char *s){ while(*s){ SendData(*s++); }}
void SendByte(uchar *pData){ uchar i; for(i = 0; i < 8; i++){ SendData(pData[i]); }}


该串口操作为配置串口1和串口2波特率都为9600(之前看了GPS模块的应用手册,发现默认的波特率为38400



但我将430的波特率设为38400发现接收到的数据为乱码,于是干脆直接将GPS的波特率设为9600,我直接将模块上的R5电阻取了,终于接收到正常的数据.)


main.c


#include <msp430f149.h>#include "inc/lcd_fyd12864.h"#include "inc/uart.h"#include "inc/gps.h"
uchar Welcom1[] = "欢迎来到嵌入式";uchar Welcom2[] = "************";uchar Welcom3[] = "版主:*******";uchar Welcom4[] = "DIY 实验室";
uchar latitude[] = "Lat: ";uchar longitude[] = "Long: ";uchar elevation[] = "Ele: ";uchar currTime[] = "Time: ";const uchar *mode[4] = {"Fail", "Fail", "2D", "3D"};
uchar RxBuf[300], TxBuf[300],RxData[9];uchar RxLen = 0;uchar RxTempLen = 0;uchar rev_flag = 0;char dtbuf[50];nmea_msg gpsx;uchar swt = 1;
void Show_GPS_Info1(nmea_msg gpsx){ float tp; //得到经度字符串 tp=gpsx.longitude; sprintf((char *)dtbuf,"Lon: %.5f %1c",tp/=100000,gpsx.ewhemi); DisplayString(0, 0, dtbuf); //得到纬度字符串 tp=gpsx.latitude; sprintf((char *)dtbuf,"Lat: %.5f %1c",tp/=100000,gpsx.nshemi); DisplayString(0, 1, dtbuf); //得到高度字符串 tp=gpsx.altitude; sprintf((char *)dtbuf,"Alt: %.1fm",tp/=10); DisplayString(0, 2, dtbuf); //得到速度字符串 tp=gpsx.speed; sprintf((char *)dtbuf,"Speed:%.3fkm/h",tp/=1000); DisplayString(0, 3, dtbuf);}
void Show_GPS_Info2(nmea_msg gpsx){ //定位状态 if(gpsx.fixmode<=3){ sprintf((char *)dtbuf,"Fix Mode: %s",mode[gpsx.fixmode]); DisplayString(0, 0, dtbuf); } //用于定位的卫星数 sprintf((char *)dtbuf,"Val sat: %02d",gpsx.posslnum); DisplayString(0, 1, dtbuf); //可见卫星数 sprintf((char *)dtbuf,"Vis sat: %02d",gpsx.svnum%100); DisplayString(0, 2, dtbuf); }
void Show_GPS_Info3(nmea_msg gpsx){ //显示UTC日期 sprintf((char *)dtbuf,"Date:%04d/%02d/%02d",gpsx.utc.year,gpsx.utc.month,gpsx.utc.date); DisplayString(0, 0, dtbuf); //显示UTC时间 sprintf((char *)dtbuf,"Time:%02d:%02d:%02d",gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec); DisplayString(0, 1, dtbuf);}

void main(){ volatile uint i; WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
BCSCTL1 &= ~XT2OFF; // XT2= HF XTAL do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0xFF; i > 0; i--); // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? //MCLK=8M,SCLK=1M BCSCTL2 |= SELM_2 + SELS + DIVS_3; // MCLK= XT2 (safe) Delay_ms(500); UartInit(); Delay_ms(500); P3DIR &= (~BIT2 + ~BIT3); LCDReset(); DisplayString(1, 0, Welcom1); DisplayString(1, 1, Welcom2); DisplayString(1, 2, Welcom3); DisplayString(1, 3, Welcom4); Delay_ms(2000); LCDClear(); Delay_ms(1000);/* DisplayString(0, 0, latitude); DisplayString(0, 1, longitude); DisplayString(0, 2, elevation); DisplayString(0, 3, currTime);*/ SendString("Lixiaoming\n"); _EINT(); while(1){ //SendString("UART0 test!\n"); if(!(P3IN & BIT2)){ swt++; if(swt == 4) swt = 1; } if(rev_flag == 1){ int i,len = 0; len = RxLen; for(i = 0; i < len; i++) TxBuf[i] = RxBuf[i]; RxLen = 0; TxBuf[i] = 0; GPS_Analysis(&gpsx,TxBuf); switch(swt){ case 1: LCDClear(); Show_GPS_Info1(gpsx); break; case 2: LCDClear(); Show_GPS_Info2(gpsx); break; default: LCDClear(); Show_GPS_Info3(gpsx); break; } SendString(TxBuf); rev_flag = 0; } //Delay_ms(1000); }}
#pragma vector = UART0RX_VECTOR__interrupt void UART0RxISR(void){ //接收来自串口的数据 while(!(IFG1 & UTXIFG0)); RxBuf[RxTempLen++] = RXBUF0; while(RxBuf[RxTempLen-1] == '\n' && RxBuf[RxTempLen-2] == '\r' ){ RxLen = RxTempLen; RxTempLen = 0; rev_flag = 1; }}
#pragma vector = UART1RX_VECTOR__interrupt void UART1RxISR(void){ //接收来自串口的数据 while(!(IFG2 & UTXIFG1)); RxBuf[RxTempLen++] = RXBUF1; while(RxBuf[RxTempLen-1] == '\n'){ RxLen = RxTempLen; RxTempLen = 0; rev_flag = 1; }}


其中,有关LCD显示部分在其他博文中会详细说到.


将程序烧到430后,上电,打开串口调试工具,发送文本如下:


$GPGGA,023543.00,2308.28715,N,11322.09875,E,1,06,1.49,41.6,M,-5.3,M,,*7D


就会收到发回来的数据跟发送的一样,同时LCD上显示海拔为41.6m.

说明能对数据接受并进行正确处理了。


后面要做的便是将串口0的接收中断代码复制到串口1接收中断代码即可。

同样上电,这时LCD可显示信息,但显示的数据都为0,说明GPS还没有定位成功。等2~3分钟左右,GPS模块上的指示灯开始闪烁时,这时从LCD上可看到当前的经度、纬度、高度、UTC时间,同时用ScuetCRT连接,可看到430发回来接受到的原始数据。


下图为实验的结果,时间显示稍微有点问题,因为没有转换还是其他。不过忙了几天终于将GPS弄好了,下一步将编写linux驱动。下面晒一下成果^-^.



PC串口接收到的数据如下:


$GPRMC,134856.00,A,2232.50576,N,11354.64802,E,0.084,,251113,,,A*7E$GPGSV,3,2,09,22,75,191,27,25,58,074,22,29,08,122,16,31,48,276,19*76gpsx->utc temp: 134857gpsx->latitude temp: 223250578gpsx->longitude temp: 1135464798gpsx->utc.date temp: 251113$GPRMC,134857.00,A,2232.50578,N,11354.64798,E,0.173,,251113,,,A*74$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,20*7Egpsx->utc temp: 134858gpsx->latitude temp: 223250575gpsx->longitude temp: 1135464785gpsx->utc.date temp: 251113$GPRMC,134858.00,A,2232.50575,N,11354.64785,E,0.140,,251113,,,A*7A$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,19*74gpsx->utc temp: 134859gpsx->latitude temp: 223250575gpsx->longitude temp: 1135464782gpsx->utc.date temp: 251113$GPRMC,134859.00,A,2232.50575,N,11354.64782,E,0.130,,251113,,,A*7B$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,20*7Egpsx->utc temp: 134900gpsx->latitude temp: 223250570gpsx->longitude temp: 1135464784gpsx->utc.date temp: 251113$GPRMC,134900.00,A,2232.50570,N,11354.64784,E,0.112,,251113,,,A*75
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论
  • By Toradex胡珊逢简介嵌入式领域的部分应用对安全、可靠、实时性有切实的需求,在诸多实现该需求的方案中,QNX 是经行业验证的选择。在 QNX SDP 8.0 上 BlackBerry 推出了 QNX Everywhere 项目,个人用户可以出于非商业目的免费使用 QNX 操作系统。得益于 Toradex 和 QNX 的良好合作伙伴关系,用户能够在 Apalis iMX8QM 和 Verdin iMX8MP 模块上轻松测试和评估 QNX 8 系统。下面将基于 Apalis iMX8QM 介
    hai.qin_651820742 2024-11-29 15:29 150浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • 随着航空航天技术的迅猛发展,航空电子网络面临着诸多挑战,如多网络并行传输、高带宽需求以及保障数据传输的确定性等。为应对这些挑战,航空电子网络急需一个通用的网络架构,满足布线简单、供应商多、组网成本相对较低等要求。而以太网技术,特别是TSN(时间敏感网络)的出现,为航空电子网络带来了新的解决方案。本文将重点介绍TSN流识别技术在航空电子网络中的应用,以及如何通过适应航空电子网络的TSN流识别技术实现高效的航空电子网络传输。一、航空电子网络面临的挑战航空航天业专用协议包括AFDX、ARINC等,这些
    虹科工业智能互联 2024-11-29 14:18 100浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 157浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 63浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 57浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 88浏览
  • 国产光耦合器因其在电子系统中的重要作用而受到认可,可提供可靠的电气隔离并保护敏感电路免受高压干扰。然而,随着行业向5G和高频数据传输等高速应用迈进,对其性能和寿命的担忧已成为焦点。本文深入探讨了国产光耦合器在高频环境中面临的挑战,并探索了克服这些限制的创新方法。高频性能:一个持续关注的问题信号传输中的挑战国产光耦合器传统上利用LED和光电晶体管进行信号隔离。虽然这些组件对于标准应用有效,但在高频下面临挑战。随着工作频率的增加,信号延迟和数据保真度降低很常见,限制了它们在电信和高速计算等领域的有效
    腾恩科技-彭工 2024-11-29 16:11 106浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 59浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 155浏览
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 117浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 54浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 71浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-29 14:30 118浏览
  • 在现代科技浪潮中,精准定位技术已成为推动众多关键领域前进的核心力量。虹科PCAN-GPS FD 作为一款多功能可编程传感器模块,专为精确捕捉位置和方向而设计。该模块集成了先进的卫星接收器、磁场传感器、加速计和陀螺仪,能够通过 CAN/CAN FD 总线实时传输采样数据,并具备内部存储卡记录功能。本篇文章带你深入虹科PCAN-GPS FD的技术亮点、多场景应用实例,并展示其如何与PCAN-Explorer6软件结合,实现数据解析与可视化。虹科PCAN-GPS FD虹科PCAN-GPS FD的数据处
    虹科汽车智能互联 2024-11-29 14:35 149浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦