近短时间在网上买了一个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: ";
- uchar RxBuf[300], TxBuf[300];
- uchar RxLen = 0;
- uchar RxTempLen = 0;
- uchar rev_flag = 0;
- char dtbuf[50];
- nmea_msg gpsx;
- 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)
-
- UartInit();
- Delay_ms(500);
-
- 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("**************\n");
- _EINT();
- while(1){
- //SendString("UART0 test!\n");
- 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);
- Show_GPS_Info(gpsx);
- SendString(TxBuf);
- }
- //Delay_ms(1000);
- }
- }
- void Show_GPS_Info(nmea_msg gpsx)
- {
- float tp;
- //得到经度字符串
- tp=gpsx.longitude;
- sprintf((char *)dtbuf,"Long:%.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);
- //显示UTC时间
- sprintf((char *)dtbuf,"UTC:%02d:%02d:%02d",gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec);
- DisplayString(0, 3, dtbuf);
- }
- #pragma vector = UART0RX_VECTOR
- __interrupt void UART0RxISR(void)
- {
- //接收来自串口的数据
- while(!(IFG1 & UTXIFG0));
- RxBuf[RxTempLen++] = RXBUF0;
- while(RxBuf[RxTempLen-1] == '\n'){
- RxLen = RxTempLen;
- RxTempLen = 0;
- rev_flag = 1;
- }
- }
- #pragma vector = UART1RX_VECTOR
- __interrupt void UART1RxISR(void)
- {
- //接收来自串口的数据
- while(!(IFG2 & UTXIFG1));
- P2OUT = RXBUF1;
- }
其中,有关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驱动。。。下面晒一下成果^-^.
补充: 之前忙于工作,现在回头看看,发现对收到的数据进行分析显示后结果不对,很有可能是数据溢出导致,通过串口1发送到PC的数据可以看到,收到GPS模块的数据是正确的。唯一可能的是在数据进行分析时出错。果然,追踪到gps.c中可以看到,对数据处理的数据超大,而msp430的int只为16位,最大值为65536,所以在对数据进行装载时肯定会溢出。这也是今天上班偶尔看看才发现的。回去后将所用的int类型替换为long型,应该就正确了,期待回去后验证。。。。
原贴链接:https://www.cnblogs.com/lixiaoming90/p/3438015.html
|