//MCU Atmega128
#define mclk 16000000
unsigned char speed_km[7]; //速度km/h
unsigned char JD[11]; //经度
unsigned char JD_a; //经度方向
unsigned char WD[10]; //纬度
unsigned char WD_a; //纬度方向
unsigned char date_y[5]={"2000"}; //年
unsigned char date_m[3]={"00"}; //月
unsigned char date_d[3]={"00"}; //日
unsigned char time_s[3]={"00"}; //时
unsigned char time_f[3]={"00"}; //分
unsigned char time_m[3]={"00"}; //秒
unsigned char speed[7]; //速度 1海里=1.852M/H
unsigned char high[8]; //高度
unsigned char DD[3]; //二维三维定位标志
unsigned char angle[6]; //方位角
unsigned char use_sat[3]; //使用的卫星数
unsigned char total_sat[4]; //天空中总卫星数
unsigned char DW[3]; //定位标志 V未定位 A已定位
//串口中断需要的变量
unsigned char seg_count; //逗号计数器
unsigned char dot_count; //小数点计数器
unsigned char byte_count; //位数计数器
unsigned char cmd_number; //命令类型
unsigned char mode; //0:结束模式,1:命令模式,2:数据模式
volatile unsigned char buf_full;//1//:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5]; //命令类型存储数组
//显示需要的变量
unsigned char dsp_count; //刷新次数计数器
unsigned char time_count; //?
volatile unsigned char high_num,a_num,s_num;//?
//void init_set(void);//?
unsigned char direction[11];
unsigned char direction0[11];
unsigned int direction_int;
unsigned char direction_num;
void usart_Init(unsigned int baud)
{
UCSR0B=0x00;
UCSR0A=0x00; //控制寄存器清零
UCSR0C=(0<<UPM00)|(3<<UCSZ00);
//选择UCSRC,异步模式,禁止
// 校验,1位停止位,8位数据位
baud="mclk/16/baud-1" ; //波特率最大为65K
UBRR0L=baud;
UBRR0H=baud>>8; //设置波特率
UCSR0B=(1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);
//接收、发送使能,接收中断使能
SREG="BIT"(7); //全局中断开放
DDRE|=BIT(1); //配置TX为输出(很重要)
//总中断允许
}
//串口接收中断
void uart_rx0 (void)//串口0接收中断服务程序GPS
{
unsigned char tmp;
tmp=UDR0;
switch(tmp){
case '$':
cmd_number=0; //命令类型清空
mode="1"; //接收命令模式
byte_count=0; //接收位数清空
break;
case ',':
seg_count++; //逗号计数加1
byte_count=0;
break;
case '*':
switch(cmd_number){
case 1:
buf_full|=0x01;
break;
case 2:
buf_full|=0x02;
break;
case 3:
buf_full|=0x04;
break;
case 4:
buf_full|=0x08;
break;
case 5:
buf_full|=0x16;
break;
case 6:
buf_full|=0x32;
break;
}
mode="0";
break;
default:
if(mode==1){
//命令种类判断
cmd[byte_count]=tmp; //接收字符放入类型缓存
if(byte_count>=4){ //如果类型数据接收完毕,判断类型
if(cmd[0]=='G'){
if(cmd[1]=='P'){
if(cmd[2]=='V'){
if(cmd[3]=='T'){
if(cmd[4]=='G'){
cmd_number=6;
mode="2";
seg_count=0;
}
}
}
if(cmd[2]=='G'){
if(cmd[3]=='G'){
if(cmd[4]=='A'){
cmd_number=1;
mode="2";
seg_count=0;
byte_count=0;
high_num=0;
}
}
else if(cmd[3]=='S'){
if(cmd[4]=='V'){
cmd_number=2;
mode="2";
seg_count=0;
byte_count=0;
}
if(cmd[4]=='A'){
cmd_number=5;
mode="2";
seg_count=0;
byte_count=0;
}
}
}
else if(cmd[2]=='R'){
if(cmd[3]=='M'){
if(cmd[4]=='C'){
cmd_number=3;
mode="2";
seg_count=0;
byte_count=0;
a_num=0;
s_num=0;
}
}
}
else if(cmd[2]=='Z'){
if(cmd[3]=='D'){
if(cmd[4]=='A'){
cmd_number=4;
mode="2";
seg_count=0;
byte_count=0;
}
}
}
}
}
}
}
else if(mode==2){
//接收数据处理
switch (cmd_number){
case 1: //类型1数据接收。GPGGA
switch(seg_count){
case 2: //纬度处理
if(byte_count<9){
WD[byte_count]=tmp;
}
break;
case 3: //纬度方向处理
if(byte_count<1){
WD_a=tmp;
}
break;
case 4: //经度处理
if(byte_count<10){
JD[byte_count]=tmp;
}
break;
case 5: //经度方向处理
if(byte_count<1){
JD_a=tmp;
}
break;
case 7: //定位使用的卫星数
if(byte_count<2){
use_sat[byte_count]=tmp;
}
break;
case 9: //高度处理
if(byte_count<6){
high[byte_count]=tmp;
high_num++;
}
break;
}
break;
case 2: //类型2数据接收。GPGSV
switch(seg_count){
case 3: //天空中的卫星总数
if(byte_count<2){
total_sat[byte_count]=tmp;
}
break;
}
break;
case 3: //类型3数据接收。GPRMC
switch(seg_count){
case 1:
if(byte_count<2){ //时间处理
time_s[byte_count]=tmp;
break;
}
if(byte_count<4){ //时间处理
time_f[byte_count-2]=tmp;
break;
}
if(byte_count<6){ //时间处理
time_m[byte_count-4]=tmp;
}
break;
case 2 : //定位标志
if(byte_count<1){
DW[byte_count]=tmp;
}
break;
case 7: //速度处理,单位节,1节=1852M/H
if(byte_count<5){
speed[byte_count]=tmp;
s_num++;
}
break;
case 8: //方位角处理
if(byte_count<5){
angle[byte_count]=tmp;
//a_num++;
}
break;
case 9:
if(byte_count<2){ //时间处理
date_d[byte_count]=tmp;
break;
}
if(byte_count<4){ //时间处理
date_m[byte_count-2]=tmp;
break;
}
if(byte_count<6){ //时间处理
date_y[byte_count-2]=tmp;
}
break;
}
break;
case 4: //类型4数据接收。GPZDA
switch(seg_count){
/*case 1:
if(byte_count<2){ //时间处理
time_s[byte_count]=tmp;
break;
}
if(byte_count<4){ //时间处理
time_s[byte_count]=tmp;
break;
}
if(byte_count<6){ //时间处理
time_s[byte_count]=tmp;
}
break;*/
case 2:
if(byte_count<2){
date_d[byte_count]=tmp;
}
break;
case 3:
if(byte_count<2){
date_m[byte_count]=tmp;
}
break;
case 4:
if(byte_count<4){
date_y[byte_count]=tmp;
}
break;
}
break;
case 5: //类型数据接收。GPGSA
switch(seg_count){
case 2:
if(byte_count<1){ //二维三维定位标志处理
DD[byte_count]=tmp;
}
break;
}
break;
case 6: //类型数据接收。GPVTG
switch(seg_count){
case 7:
if(byte_count<5){ //速度,单位KM/H
speed_km[byte_count]=tmp;
}
break;
}
break;
}
}
byte_count++; //接收数位加1
break;
}
}
NMEA协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。
NMEA-0183协议是GPS接收机应当遵守的标准协议,也是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。
NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。下面给出这些常用NMEA-0183语句的字段定义解释。
$GPGGA
例:$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
字段0:$GPGGA,语句ID,表明该语句为Global Positioning System Fix Data(GGA)GPS定位信息
字段1:UTC 时间,hhmmss.sss,时分秒格式
字段2:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段3:纬度N(北纬)或S(南纬)
字段4:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段5:经度E(东经)或W(西经)
字段6:GPS状态,0=未定位,1=非差分定位,2=差分定位,3=无效PPS,6=正在估算
字段7:正在使用的卫星数量(00 - 12)(前导位数不足则补0)
字段8:HDOP水平精度因子(0.5 - 99.9)
字段9:海拔高度(-9999.9 - 99999.9)
字段10:地球椭球面相对大地水准面的高度
字段11:差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
字段12:差分站ID号0000 - 1023(前导位数不足则补0,如果不是差分定位将为空)
字段13:校验值
$GPGSA
例:$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A
字段0:$GPGSA,语句ID,表明该语句为GPS DOP and Active Satellites(GSA)当前卫星信息
字段1:定位模式,A=自动手动2D/3D,M=手动2D/3D
字段2:定位类型,1=未定位,2=2D定位,3=3D定位
字段3:PRN码(伪随机噪声码),第1信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段4:PRN码(伪随机噪声码),第2信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段5:PRN码(伪随机噪声码),第3信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段6:PRN码(伪随机噪声码),第4信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段7:PRN码(伪随机噪声码),第5信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段8:PRN码(伪随机噪声码),第6信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段9:PRN码(伪随机噪声码),第7信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段10:PRN码(伪随机噪声码),第8信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段11:PRN码(伪随机噪声码),第9信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段12:PRN码(伪随机噪声码),第10信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段13:PRN码(伪随机噪声码),第11信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段14:PRN码(伪随机噪声码),第12信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)
字段15:PDOP综合位置精度因子(0.5 - 99.9)
字段16:HDOP水平精度因子(0.5 - 99.9)
字段17:VDOP垂直精度因子(0.5 - 99.9)
字段18:校验值
$GPGSV
例:$GPGSV,3,1,10,20,78,331,45,01,59,235,47,22,41,069,,13,32,252,45*70
字段0:$GPGSV,语句ID,表明该语句为GPS Satellites in View(GSV)可见卫星信息
字段1:本次GSV语句的总数目(1 - 3)
字段2:本条GSV语句是本次GSV语句的第几条(1 - 3)
字段3:当前可见卫星总数(00 - 12)(前导位数不足则补0)
字段4:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)
字段5:卫星仰角(00 - 90)度(前导位数不足则补0)
字段6:卫星方位角(00 - 359)度(前导位数不足则补0)
字段7:信噪比(00-99)dbHz
字段8:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)
字段9:卫星仰角(00 - 90)度(前导位数不足则补0)
字段10:卫星方位角(00 - 359)度(前导位数不足则补0)
字段11:信噪比(00-99)dbHz
字段12:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)
字段13:卫星仰角(00 - 90)度(前导位数不足则补0)
字段14:卫星方位角(00 - 359)度(前导位数不足则补0)
字段15:信噪比(00-99)dbHz
字段16:校验值
$GPRMC
例:$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
字段0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息
字段1:UTC时间,hhmmss.sss格式
字段2:状态,A=定位,V=未定位
字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段4:纬度N(北纬)或S(南纬)
字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段6:经度E(东经)或W(西经)
字段7:速度,节,Knots
字段8:方位角,度
字段9:UTC日期,DDMMYY格式
字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
字段11:磁偏角方向,E=东W=西
字段16:校验值
$GPVTG
例:$GPVTG,89.68,T,,M,0.00,N,0.0,K*5F
字段0:$GPVTG,语句ID,表明该语句为Track Made Good and Ground Speed(VTG)地面速度信息
字段1:运动角度,000 - 359,(前导位数不足则补0)
字段2:T=真北参照系
字段3:运动角度,000 - 359,(前导位数不足则补0)
字段4:M=磁北参照系
字段5:水平运动速度(0.00)(前导位数不足则补0)
字段6:N=节,Knots
字段7:水平运动速度(0.00)(前导位数不足则补0)
字段8:K=公里/时,km/h
字段9:校验值
$GPGLL
例:$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D
字段0:$GPGLL,语句ID,表明该语句为Geographic Position(GLL)地理定位信息
字段1:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段2:纬度N(北纬)或S(南纬)
字段3:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段4:经度E(东经)或W(西经)
字段5:UTC时间,hhmmss.sss格式
字段6:状态,A=定位,V=未定位
字段7:校验值
文章评论(0条评论)
登录后参与讨论