|
发表于 2010-11-29 11:13:09
|
显示全部楼层
索性再贴一段
//-------------- 串口1接收中断 我用的是C8051F020 ---------------//
void Uart1_Interrupt (void) interrupt 20
{
if ((SCON1 & 0x01) == 0x01) // RI1 = 1;
{
SCON1 &= 0xFE; // RI1 = 0;
TR0 = 0; // 关闭定时器
Uart1_RcvBuf[Uart1_SavePtr++] = SBUF1;
TH0 = 0x28; // 这里设置超时时间 视波特率及通信方式而定 别按我的这个设定。。。单片机也不一样。。。
TL0 = 0x00;
TR0 = 1; // 开启定时器
}
if((SCON1 & 0x02) == 0x02) // Check if transmit flag is set
SCON1 = (SCON1 & 0xFD);
}
//---------------------- 定时器中断 --------------------------//
void ISR_Timer0(void) interrupt 1
{
TR0 = 0; // 关闭计数
LED = !LED;
Rcvbit = 1; // 置接收标志位
//TH0 = 0x28; //
//TL0 = 0x00;
//TR0 = 1; // 这里不使能 装值可在这里重装 保证一次接收后才置一次接收位
}
把我写的GPS接收函数也一并贴出来.....用超时处理的方式处理GPS数据很好使,因为GPS数据每一秒发送一次,每次有大概400Byte的数据,开辟一个缓冲区后等待超时后再处理,9600bps下每秒
9600bit = 1200Byte(实际1000左右) 传送完需大概1/3秒的时间,剩下就是处理和调度的时间了,用51RAM大一些的话也能很好的处理完而不用在中断中处理那么一大堆处理。
typedef struct
{
INT8U Block;
INT8U BlockIndex;
INT8U UTCTime[10]; // hhmmss.mmm
INT8U Status; // A- 有效定位 V-无效定位
INT8U Latitude[9]; // ddmm.mmmm
INT8U NS; // N/S
INT8U Longitude[10]; // dddmm.mmmm
INT8U EW; // E/W
INT8U Speed[5]; // 速率000.0~999.9节
INT8U Course[5]; // 航向000.0~359.9度
INT8U UTCDate[6]; // ddmmyy
}stru_GPSRMC;
typedef struct
{
INT8U Block;
INT8U BlockIndex;
//INT8U UTCTime[10]; // hhmmss.mmm RMC中已有, 所以不解析
//INT8U Latitude[9]; // ddmm.mmmm
//INT8U NS; // N/S
//INT8U Longitude[10]; // dddmm.mmmm
//INT8U EW; // E/W
INT8U PositionFix; // 0,1,2,6
INT8U SateUsed[2]; // 00~12
//INT8U HDOP[4]; // 0.5~99.9
INT8U Altitude[7]; // -9999.9~99999.9
}stru_GPSGGA;
typedef struct
{
INT8U Block;
INT8U BlockIndex;
INT8U Mode; // A-自动 /M-手动
INT8U Mode2; // 0,1,2,3
INT8U SateUsed[12][2];
INT8U PDOP[4];
INT8U HDOP[4];
INT8U VDOP[4];
}stru_GPSGSA;
typedef struct
{
INT8U SatelliteID[2]; // 卫星编号
INT8U Elevation[2]; // 0-90 degree // 不显示GPS卫星的方位图, 所以不解析, 节省 5*12 RAM
INT8U Azimuth[3]; // 0-359 degree // 需要解析时去除注释'//'和解析前的'//'即可
INT8U SNR[2]; // 0-99 dbHz
}stru_SatelliteInfo;
typedef struct
{
INT8U Block;
INT8U BlockIndex;
INT8U SateInView[2];
INT8U GSVID; //当前 GSV语句编号
stru_SatelliteInfo SatelliteInfo[12];
}stru_GPSGSV;
INT8U GPRMC_Receive(void)
{
INT8U buf[13];
INT8U sbuf;
INT8U *ptr;
INT16U index;
memset(&GPS_RMC_Data, 0x00, sizeof(GPS_RMC_Data)); // 每次处理前将结构体清零
index = Find_Str(Uart1_RcvBuf, "$GPRMC,");
if(index)
{
ptr = Uart1_RcvBuf + index + 6;
do
{
sbuf = *ptr++;
switch(sbuf)
{
case ',': // 接收到数据段分隔符','
GPS_RMC_Data.Block++; // 数据段标志
GPS_RMC_Data.BlockIndex = 0; // 数据段数据计数指针
break;
default: // 接收到数据
switch(GPS_RMC_Data.Block)
{
case 0: GPS_RMC_Data.UTCTime[GPS_RMC_Data.BlockIndex] = sbuf; break;
case 1: GPS_RMC_Data.Status = sbuf; break;
case 2: GPS_RMC_Data.Latitude[GPS_RMC_Data.BlockIndex] = sbuf; break;
case 3: GPS_RMC_Data.NS = sbuf; break;
case 4: GPS_RMC_Data.Longitude[GPS_RMC_Data.BlockIndex] = sbuf;break;
case 5: GPS_RMC_Data.EW = sbuf; break;
case 6: GPS_RMC_Data.Speed[GPS_RMC_Data.BlockIndex] = sbuf; break;
case 7: GPS_RMC_Data.Course[GPS_RMC_Data.BlockIndex] = sbuf; break;
case 8: GPS_RMC_Data.UTCDate[GPS_RMC_Data.BlockIndex] = sbuf; break;
default: break;
}
GPS_RMC_Data.BlockIndex++;
break;
}
}while(sbuf != '*');
memset(buf, 0x00, sizeof(buf));
buf[0] = GPS_RMC_Data.NS;
buf[1] = ' ';
buf[2] = ' ';
memcpy(buf + 3, &GPS_RMC_Data.Latitude, 9);
LCD_ShowString(8, 20, buf, 0);
memset(buf, 0x00, sizeof(buf));
buf[0] = GPS_RMC_Data.EW;
buf[1] = ' ';
memcpy(buf + 2, &GPS_RMC_Data.Longitude, 10);
LCD_ShowString(120, 20, buf, 0);
memset(buf, 0x00, sizeof(buf));
buf[0] = 'T';
buf[1] = ' ';
memcpy(buf + 2, &GPS_RMC_Data.UTCTime, 10);
LCD_ShowString(8, 40, buf, 0);
/*
memset(buf, 0x00, sizeof(buf));
buf[0] = 'S';
buf[1] = ' ';
memcpy(buf + 2, &GPS_RMC_Data.Speed, 5);
LCD_ShowString(8,100, buf, 0);
memset(buf, 0x00, sizeof(buf));
buf[0] = 'C';
buf[1] = ' ';
memcpy(buf + 2, &GPS_RMC_Data.Course, 5);
LCD_ShowString(8,120, buf, 0);
*/
}
return 0;
}
INT8U GPGSV_Receive(void)
{
INT8U buf[8] = "Sat: 00";
INT8U i, sbuf;
INT8U *ptr;
INT16U index;
memset(&GPS_GSV_Data, 0x00, sizeof(GPS_GSV_Data)); // 每次处理前将结构体清零
index = Find_Str(Uart1_RcvBuf, "$GPGSV,");
if(index)
{
ptr = Uart1_RcvBuf + index + 6;
do
{
sbuf = *ptr++;
switch(sbuf)
{
case ',':
GPS_GSV_Data.Block++;
GPS_GSV_Data.BlockIndex=0;
break;
default:
switch(GPS_GSV_Data.Block)
{
case 1: //当前GPFSV语句的序号, 该序号计算出该组卫星数据应该存放于数组的哪个位置
GPS_GSV_Data.GSVID = sbuf - '1';
break;
case 2:
GPS_GSV_Data.SateInView[GPS_GSV_Data.BlockIndex] = sbuf;
break;
case 3:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4].SatelliteID[GPS_GSV_Data.BlockIndex] = sbuf;
break;
case 4:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4].Elevation[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 5:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4].Azimuth[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 6:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4].SNR[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 7:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+1].SatelliteID[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 8:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+1].Elevation[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 9:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+1].Azimuth[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 10:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+1].SNR[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 11:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+2].SatelliteID[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 12:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+2].Elevation[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 13:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+2].Azimuth[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 14:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+2].SNR[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 15:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].SatelliteID[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 16:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].Elevation[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 17:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].Azimuth[GPS_GSV_Data.BlockIndex]=sbuf;
break;
case 18:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].SNR[GPS_GSV_Data.BlockIndex]=sbuf;
break;
}
GPS_GSV_Data.BlockIndex++;
break;
}
}while(sbuf != '*');
for(i = 0; i < 4; i++)
{
}
//memcpy(buf + 5, &GPS_GSV_Data.SateInView, 2);
//LCD_ShowString(8, 60, buf, 0);
}
return 0;
}
INT8U GPGGA_Receive(void)
{
INT8U sbuf;
INT8U *ptr;
INT16U index;
memset(&GPS_GGA_Data, 0x00, sizeof(GPS_GGA_Data)); // 每次处理前将结构体清零
index = Find_Str(Uart1_RcvBuf, "$GPGGA,");
if(index)
{
ptr = Uart1_RcvBuf + index + 6;
do
{
sbuf = *ptr++;
switch(sbuf)
{
case ',': // 该字段结束, 下一个
GPS_GGA_Data.Block++;
GPS_GGA_Data.BlockIndex = 0; //字段索引置0:第一个字符
break;
default: // 字段字符
switch(GPS_GGA_Data.Block) //判断当前处于哪个字段
{
//case 0:
//GPS_GGA_Data.UTCTime[GPS_GGA_Data.BlockIndex]=sbuf;
//break;
//case 1:
//GPS_GGA_Data.Latitude[GPS_GGA_Data.BlockIndex]=sbuf;
//break;
//case 2:
//GPS_GGA_Data.NS=sbuf;
//break;
//case 3:
//GPS_GGA_Data.Longitude[GPS_GGA_Data.BlockIndex]=sbuf;
//break;
//case 4:
//GPS_GGA_Data.EW=sbuf;
//break;
case 5:
GPS_GGA_Data.PositionFix=sbuf;
break;
case 6:
GPS_GGA_Data.SateUsed[GPS_GGA_Data.BlockIndex]=sbuf;
break;
//case 7:
//GPS_GGA_Data.HDOP[GPS_GGA_Data.BlockIndex]=sbuf;
//break;
case 8:
GPS_GGA_Data.Altitude[GPS_GGA_Data.BlockIndex]=sbuf;
break;
}
GPS_GSV_Data.BlockIndex++; //字段索引++, 指向下一个字符
break;
}
}while(sbuf != '*');
}
return 0;
}
INT8U GPGSA_Receive(void)
{
INT8U sbuf;
INT8U *ptr;
INT16U index;
memset(&GPS_GSA_Data, 0x00, sizeof(GPS_GSA_Data)); // 每次处理前将结构体清零
index = Find_Str(Uart1_RcvBuf, "$GPGSA,");
if(index)
{
ptr = Uart1_RcvBuf + index + 6;
do
{
sbuf = *ptr++;
switch(sbuf)
{
case ',':
GPS_GSA_Data.Block++;
GPS_GSA_Data.BlockIndex=0;
break;
default:
switch(GPS_GSA_Data.Block)
{
case 0:
GPS_GSA_Data.Mode = sbuf;
break;
case 1:
GPS_GSA_Data.Mode2 = sbuf;
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13: //2-13 是已使用的卫星ID, 保存于数组中
GPS_GSA_Data.SateUsed[GPS_GSA_Data.Block-2][GPS_GSA_Data.BlockIndex]=sbuf;
break;
case 14:
GPS_GSA_Data.PDOP[GPS_GSA_Data.BlockIndex]=sbuf;
break;
case 15:
GPS_GSA_Data.HDOP[GPS_GSA_Data.BlockIndex]=sbuf;
break;
case 16:
GPS_GSA_Data.VDOP[GPS_GSA_Data.BlockIndex]=sbuf;
break;
}
GPS_GSV_Data.BlockIndex++; //字段索引++, 指向下一个字符
break;
}
}while(sbuf != '*');
}
return 0;
} |
|