|
楼主 |
发表于 2011-6-28 08:31:18
|
显示全部楼层
上一个采集卫星定位信息,并把采集到的原始字符数据转换成压缩BCD格式,由于程序结构不好,是从整个项目程序中复制过来的一小段,可能会有个别全局变量在该段程序中未注明:
/*
采集到的原始定位数据:$GPRMC,170034.00,A,3928.04929,N,11800.89192,E,0.023,,300411,,,A*72end
*/
uchar *GpsC[7]={GPS.HMS,GPS.State,GPS.N,GPS.E,GPS.Speed,GPS.Course,GPS.YMD};
extern struct GPSDATAC{
uchar *HMS; //定位模块中采集到的时间时分秒
uchar *State; //定位状态 A V X
uchar *N; //纬度
uchar *E; //经度
uchar *Speed; //速度
uchar *Course; //航向
uchar *YMD; //日期年月日
}GpsPointer;
extern struct GPSDATA{
uchar HMS[6];
uchar State[4];
uchar N[6];
uchar E[7];
uchar Speed[6];
uchar Course[6];
uchar YMD[7];
}GPS;
/*
***********************************************************************
函数名称: 航向处理
函数功能: 将从GPS模块采集到的航向字符串转换成BCD码
入口参数: 要转换的字符串 ,转换结果存放的地址
出口参数: 转换后的BCD字节数
***********************************************************************
*/
uchar GpsCourseProcess(uchar *courseAscii,uchar *courseBCD)
{
uchar i,j;
uint ZsBin=0,ZsBcd=0;
uchar XsBin=0,XsBcd=0;
uchar BiytNumber=0;
for(i=0;i<5;i++){
if(courseAscii[0]==',') { return 0; } ///////courseBCD[0]=0x00; return 0;
if(courseAscii=='.'){
for(j=0;j<i;j++){
ZsBin=ZsBin*10;
ZsBin+=(courseAscii[j]-'0');
}
if(courseAscii[i+1]!=','&&courseAscii[i+2]!=','){
XsBcd=((courseAscii[i+1]-'0')<<4)|(courseAscii[i+2]-'0');
}else{
XsBcd=0x00;
}
if(ZsBin>99){
BinToBcd(ZsBin,&ZsBcd);
courseBCD[0]=0x06; //航向字段字节数
courseBCD[1]=0x02; //0x02表示BCD数据格式,数据为正数,小数点后有两位有效数字
courseBCD[2]=0x04; //航向的寄存器号
courseBCD[3]=ZsBcd>>8;
courseBCD[4]=ZsBcd&0xff;
courseBCD[5]=XsBcd;
BiytNumber=6;
break;
}else{
BinToBcd(ZsBin,&ZsBcd);
courseBCD[0]=0x05; //航向字段字节数
courseBCD[1]=0x02; //0x02表示BCD数据格式,数据为正数,小数点后有两位有效数字
courseBCD[2]=0x04; //航向的寄存器号
courseBCD[3]=ZsBcd&0xff;
courseBCD[4]=XsBcd;
BiytNumber=5;
break;
}
}
}
return BiytNumber;
}
/*
***********************************************************************
函数名称: 速度处理
函数功能: 将GPS模块采集到的速度字符串转换为BCD码格式,并且原来的单位是
海里/小时,转换为千米/小时,
入口参数: 要转换的字符串
出口参数: 无
***********************************************************************
*/
uchar GpsSpeedProcess(uchar *speedAscii,uchar *speedBCD)
{
uchar i,j;
uchar BiytNumber=0; //转换后的BCD码位数
uint speedZsBin=0,speedZsBcd=0,speedXsBcd=0;
uchar speedXsBin=0;
for(i=0;i<4;i++)
{
if(speedAscii[0]==',') { return 0;} /// speedBCD[0]=0x00; return 0;
if(speedAscii=='.'){
for(j=0;j<i;j++){
speedZsBin=speedZsBin*10;
speedZsBin+=(speedAscii[j]-'0');
}
speedZsBin=speedZsBin*1.852; //海里转换为公里 整数部分
if(speedAscii[i+1]!=','&&speedAscii[i+2]!=','){
speedXsBin=(speedAscii[i+1]-'0')*10+(speedAscii[i+2]-'0');
}else{
speedXsBin=0x00;
}
speedXsBin=speedXsBin*1.852;
if(speedXsBin>99){
speedZsBin+=1;
}
BinToBcd(speedXsBin,&speedXsBcd);
if(speedZsBin>99){
BinToBcd(speedZsBin,&speedZsBcd);
speedBCD[0]=0x06; //速度字段的字节数
speedBCD[1]=0x02; //0x02表示BCD数据格式,数据为正数,小数点后有两位有效数字
speedBCD[2]=0x03; //速度的寄存器号0x03
speedBCD[3]=speedZsBcd>>8;
speedBCD[4]=speedZsBcd&0xff;
speedBCD[5]=speedXsBcd&0xff;
BiytNumber=6;
break;
}else{
BinToBcd(speedZsBin,&speedZsBcd);
speedBCD[0]=0x05; //速度字段的字节数
speedBCD[1]=0x02; //0x02表示BCD数据格式,数据为正数,小数点后有两位有效数字
speedBCD[2]=0x03; //速度的寄存器号0x03
speedBCD[3]=speedZsBcd&0xff;
speedBCD[4]=speedXsBcd&0xff;
BiytNumber=5;
break;
}
}
}
return BiytNumber;
}
/*
***********************************************************************
函数名称: 日期、时间处理函数
函数功能: 处理采集到的GPS模块的时间和日期,处理后的日期时间以
年高位、年低位、月、日、时、分、秒顺序排列,格式为压缩
BCD格式;
入口参数: 要处理的时间,要处理的日期,时间处理结果存放地址,
日期处理结果存放地址 ,uchar *ResultBcdHMS,uchar *ResultBcdYMD
出口参数:
************************************************************************
*/
void GpsDataTimeProcess(uchar *timeHMS,uchar *dayYMD,uchar *ResultBcdHMS,uchar *ResultBcdYMD)
{
uchar TimeBinHMS[3]; //TimeBinHMS[0]---时;TimeBinHMS[1]---分;TimeBinHMS[2]---秒
uint DayBinYMD[3]; //DayBinYMD[0]---年; DayBinYMD[1]---月; DayBinYMD[2]--日
uint Year=0;
receive_count_com1=0;
if(timeHMS[0]==','||dayYMD[0]==',')
{
//ResultBcdHMS[0]=0x00;
//ResultBcdYMD[0]=0x00;
return;
}
else
{
/*--------------------------日期、时间字符串转BIN--------------*/
TimeBinHMS[0]=(timeHMS[0]-'0')*10+(timeHMS[1]-'0');
TimeBinHMS[1]=(timeHMS[2]-'0')*10+(timeHMS[3]-'0');
TimeBinHMS[2]=(timeHMS[4]-'0')*10+(timeHMS[5]-'0');
DayBinYMD[0]=(dayYMD[4]-'0')*10+(dayYMD[5]-'0')+2000;
DayBinYMD[1]=(dayYMD[2]-'0')*10+(dayYMD[3]-'0');
DayBinYMD[2]=(dayYMD[0]-'0')*10+(dayYMD[1]-'0');
/*-------------------------------------END--------------------*/
TimeBinHMS[0]+=8;
/*----------------------------------------调整日期---------------------------------------------*/
if(TimeBinHMS[0]>=24){ //如果大于等于24小时,侧需要调整日期
TimeBinHMS[0]-=24;
DayBinYMD[2]++;
switch(DayBinYMD[1])
{
case 1: case 3:
case 5: case 7:
case 8: case 10:
if(DayBinYMD[2]>31)
{
DayBinYMD[2]=1;
DayBinYMD[1]++;
}
break;
case 4: case 6:
case 9: case 11:
if(DayBinYMD[2]>30)
{
DayBinYMD[2]=1;
DayBinYMD[1]++;
}
break;
case 12: if(DayBinYMD[2]>31)
{
DayBinYMD[2]=1;
DayBinYMD[1]=1;
DayBinYMD[0]++;
}
break;
case 2: if((DayBinYMD[0]%400==0)||((DayBinYMD[0]%4==0)&&(DayBinYMD[0]%100!=0))){ //闰年
if(DayBinYMD[2]>29){
DayBinYMD[2]=1;
DayBinYMD[1]=3;
}
}else{ //平年
if(DayBinYMD[2]>28){
DayBinYMD[2]=1;
DayBinYMD[1]=3;
}
}
break;
default: break;
}
}
/*---------------------------------------------------END----------------------------------------*/
/*-------------------------------时间转换--------------------------------*/
ResultBcdHMS[0]=0x06;
ResultBcdHMS[1]=0x00;
ResultBcdHMS[2]=0x06; //时间的寄存器号
ResultBcdHMS[3]=((TimeBinHMS[0]/10)<<4)|(TimeBinHMS[0]%10);
ResultBcdHMS[4]=((TimeBinHMS[1]/10)<<4)|(TimeBinHMS[1]%10);
ResultBcdHMS[5]=((TimeBinHMS[2]/10)<<4)|(TimeBinHMS[2]%10);
/*----------------------------------END----------------------------------*/
/*--------------------------------日期转换-------------------------------*/
ResultBcdYMD[0]=0x07;
ResultBcdYMD[1]=0x00;
ResultBcdYMD[2]=0x07; //日期的寄存器号
BinToBcd(DayBinYMD[0],&Year);
ResultBcdYMD[3]=Year>>8;
ResultBcdYMD[4]=Year&0xff;
ResultBcdYMD[5]=(((uchar)DayBinYMD[1]/10)<<4)|(DayBinYMD[1]%10);
ResultBcdYMD[6]=(((uchar)DayBinYMD[2]/10)<<4)|(DayBinYMD[2]%10);
/*----------------------------------END----------------------------------*/
}
}
/*
*****************************************************************
函数名称: GPS数据分拣
函数功能: 分拣采集到的GPS数据,把不同段数据首地址送给各自的指针
入口参数: 要分拣的GPS原始数据
出口参数: 无
*****************************************************************
*/
void GpsDataFenjian(uchar *GpsD)
{
uchar i,Dhao=0;
for(i=0;i<150;i++){
if(GpsD==','){
Dhao++;
switch(Dhao)
{
case 1: GpsPointer.HMS=&GpsD[i+1];
break;
case 2: GpsPointer.State=&GpsD[i+1];
break;
case 3: GpsPointer.N=&GpsD[i+1];
break;
case 5: GpsPointer.E=&GpsD[i+1];
break;
case 7: GpsPointer.Speed=&GpsD[i+1];
break;
case 8: GpsPointer.Course=&GpsD[i+1];
break;
case 9: GpsPointer.YMD=&GpsD[i+1];
break;
default: break;
}
}
if(Dhao==10) break;
}
GPS.State[0]=0x04;
GPS.State[1]=0x00;
GPS.State[2]=0x05;
switch(GpsPointer.State[0])
{
case 65: GPS.State[3]=0x65;
//此处添加点亮GPS定位状态指示灯语句,定位有效
break;
case 86: GPS.State[3]=0x86;
//此处添加熄灭GPS定位状态指示灯语句,定位无效
break;
default: GPS.State[3]=0x88;
break;
}
//return GPS.State[3];
}
/*
**************************************************************************
函数名称: 经纬度字符转BCD
函数功能: 将从GPS模块中提取的字符串形式的经纬度信息转换成BCD码格式
入口参数: 要转换的经纬度字符串,转换结果存放地址(存放形式: 度 分 格式),寄存器号
出口参数: 转换后的BCD码的字节数
**************************************************************************
*/
uchar GpsNE_AscToBcd(uchar *p,uchar *q,uchar re)
{
uchar i,j,n;
uchar BiytNumb=0; //返回转换后的BCD码字节个数
uint NEH=0; //存放整数部分
uint NEL=0; //存放小数部分
uint XsBcd16=0;
uint ZsBcd16=0;
/*-------------将字符串转换为BIN----------*/
if(p[0]==',')
{
// q[0]=0;
return 0;
}
for(i=0;i<15;i++)
if(p=='.'){ //寻找小数点
for(j=i-2;j<i+4;j++){
if(p[j]=='.') continue;
NEL=NEL*10; ///分的转换
NEL+=(p[j]-'0');
}
NEL=NEL/6;
for(j=0;j<i-2;j++){
NEH=NEH*10;
NEH+=(p[j]-'0');
}
break;
}
/*------------------END-------------------*/
n=NEH;
/*-----------------------转换分----------*/
BinToBcd(NEL,&XsBcd16); //转换分
/*------------------------END------------*/
/*-------------------转换度---------------*/
BinToBcd(NEH,&ZsBcd16); //转换度
if(n>99){
q[0]=0x07;
q[1]=0x04;
q[2]=re;
q[3]=ZsBcd16>>8; //保存度的高字节
q[4]=ZsBcd16&0xff; //保存度的低字节
q[5]=XsBcd16>>8; //保存分的高字节
q[6]=XsBcd16&0xff; //保存分的低字节
BiytNumb=7;
}else{
q[0]=0x06;
q[1]=0x04;
q[2]=re;
q[3]=ZsBcd16&0xff; //保存度,单字节
q[4]=XsBcd16>>8; //保存分的高字节
q[5]=XsBcd16&0xff; //保存分的低字节
BiytNumb=6;
}
/*---------------------END---------------*/
return BiytNumb;
}
/*
************************************************************************
函数名称: 二进制转BCD码函数
函数功能: 将16位二进制数据转换为压缩BCD码格式
入口参数: 要转换的16位的二进制数据和转换结果的地址
出口参数: 转换后的两字节压缩BCD码
说 明: 本函数专门为GPS的经纬度设计,故要转换的二进制数据有
范围大小的限制,因为转换结果为两字节BCD码,故转换结
果最大为9999,所以要转换的二进制数据不大于0x270F
************************************************************************
*/
uchar BinToBcd(uint Bin16,uint *Bcd16)
{
uchar BcdNumb=0;
uchar i;
for(i=0;i<16;i++){
if((*Bcd16&0X0F)>=5) //大于等于5加3
{
*Bcd16=(((*Bcd16&0x0F)+3)&0x0f)|(*Bcd16&0xfff0);
}
if(((*Bcd16&0Xf0)>>4)>=5) //大于等于5加3
{
*Bcd16=(((((*Bcd16&0Xf0)>>4)+3)&0x0f)<<4)|(*Bcd16&0xff0f);
}
if(((*Bcd16&0X0F00)>>8)>=5) //大于等于5加3
{
*Bcd16=(((((*Bcd16&0x0F00)>>8)+3)&0x0f)<<8)|(*Bcd16&0xf0ff);
}
if(((*Bcd16&0Xf000)>>12)>=5) //大于等于5加3
{
*Bcd16=(((((*Bcd16&0Xf000)>>12)+3)&0x0f)<<12)|(*Bcd16&0x0fff);
}
*Bcd16=(*Bcd16<<1)|(bit)(Bin16&0x8000);
Bin16=Bin16<<1;
}
return BcdNumb;
} |
|