基于51单片机的GPS定位系统,利用虚拟串口结合 VirtualGPS(虚拟GPS软件) ,得到GPS数据,实现在仿真上实现GPS定位信息,同时系统支持温湿度测量、超声波距离测量,led和蜂鸣器报警等功能。
一、系统设计
1、串口解析GPS代码
虚拟GPS发送过来的GPS数据以其固定格式存储,我们通过对这个字符串数据的解析得到经纬度的各个信息,通过如下函数可以解析出。
cpp
// GPS纬度提取函数
void removeLatitude(unsigned char temp)
{
uchar i,k=0;
for(i=temp+2;i<temp+13;i++)
uLatitude[k++]=uartBuffer[i];
}
// GPS经度提取函数
void removeLongitude(unsigned char temp)
{
uchar i,k=0;
for(i=temp+2;i<temp+14;i++)
uLongitude[k++]=uartBuffer[i];
}
// GPS速度提取函数
void removeSpeed(unsigned char temp)
{
uchar i,k=0;
for(i=temp+2;i<temp+9;i++)
{
if(uartBuffer[i]==',') break;
uSpeed[k++]=uartBuffer[i];
}
}
// GPS日期提取函数
void removeDate(unsigned char temp)
{
uchar i,k=0;
for(i=temp+2;i<temp+11;i++)
uDate[k++]=uartBuffer[i];
}
// GPS数据处理函数
void uartBufferDeal()
{
uchar i,j;
uchar comma_n=0;
for(i=0;i<100;i++)
{
if(uartBuffer[i]=='R')
{
comma_n=0;//逗号的个数归零
for(j=i;j<100;j++)
{
if(uartBuffer[j]==',')
comma_n+=1;
if(comma_n==2)
removeLatitude(j);
if(comma_n==4)
removeLongitude(j);
if(comma_n==6)
removeSpeed(j);
if(comma_n==8)
removeDate(j);
}
}
}
}
// 经纬度数据格式转换函数
void formatControl()
{
uchar w[13],j[13],D[6],V[10];
uchar i;
for(i=0;i<13;i++)
{
w[i]=uLatitude[i];
j[i]=uLongitude[i];
}
for(i=0;i<6;i++)
{
D[i]=uDate[i];
V[i]=uSpeed[i];
}
uLatitude[0]='W';
uLatitude[1]=w[0];
uLatitude[2]=w[1];
uLatitude[3]=0x20;//空格
uLatitude[4]=w[2];
uLatitude[5]=w[3];
uLatitude[6]=0x27;//单引号
uLatitude[7]=w[5];
uLatitude[8]=w[6];
uLatitude[9]=w[4];//小数点
uLatitude[10]=w[7];
uLatitude[11]=w[8];
uLatitude[12]=0x22;//双引号
uLongitude[0]='J';
uLongitude[1]=j[0];
uLongitude[2]=j[1];
uLongitude[3]=j[2];
uLongitude[4]=0x20;//空格
uLongitude[5]=j[3];
uLongitude[6]=j[4];
uLongitude[7]=0x27;//单引号
uLongitude[8]=j[6];
uLongitude[9]=j[7];
uLongitude[10]=j[5];//小数点
uLongitude[11]=j[8];
uLongitude[12]=j[9];
uLongitude[13]=0x22;//双引号
uDate[0]='D';
uDate[1]=D[0];
uDate[2]=D[1];
uDate[3]='/';
uDate[4]=D[2];
uDate[5]=D[3];
uDate[6]='/';
uDate[7]=D[4];
uDate[8]=D[5];
for(i=0;i<10;i++)
{
if(i==0)
uSpeed[i]='V';
else
uSpeed[i]=V[i-1];
}
}
//==============串口初始化函数==========================
void uartInit()
{
SCON = 0x50; //REN=1允许串行接收状态,串口工作模式1
TMOD|= 0x20; //定时器工作方式2
PCON|= 0; //SMOD设置为0
TH1 = 0xFA; // 波特率4800、数据位8、停止位1。效验位无 (11.0592M)
TL1 = 0xFA;
TR1 = 1; //定时器T1启动
ES = 1; //开串口中断
}
2、超声波测量距离
超声波模块使用定时器测量声音发送遇到物体,到回弹到超声波除所花费的时间,再根据声音在空气中中的传播速度,综合测量出物体距离。
cpp
//初始化定时器
void init_time()
{
TMOD = 0x01; //选择定时器0工作 工作方式为方式1
TH0 = 0; //装初值0
TL0 = 0;
TF0 = 0; //中断溢出标志位
ET0 = 1; //开定时器中断
EA = 1; // 开总中断
}
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
//超声波1
sbit TRIG2 = P3^2; //超声波的 TRIG端 插在了P3.2口
sbit ECHO2 = P3^3; //超声波的 ECHO端 插在了P3.3口
//超声波2获取距离
int GetDistance2(void)
{
u16 distance,out_TH0,out_TL0;
/*超声波传感器的使用方法:
控制口发一个10US 以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的,此时就为此次测距的时间,方可算出距离。如此不断的周期测, 就可以达到移动测量的值了*/
init_time(); //初始化定时器
flag = 0; //置溢出标志位为0
//控制口发一个10US 以上的高电平
TRIG2 = 1;
delay(2);
TRIG2 = 0;
//等待接收端出现高电平
while(!ECHO2);
TR0 = 1; //启动计时器 开始计时
while(ECHO2); //等待高电平结束
TR0 = 0; //关闭低电平
out_TH0 = TH0; //取定时器的值
out_TL0 = TL0;
out_TH0 <<= 8; //右移8位
distance = out_TH0 | out_TL0; //合并为16位的值
distance /= 58;
}
三、项目演示
仿真运,并将虚拟GPS打开,可以看到如下:
按下模式切换,进入距离测量模式,当距离低于阈值的时候,蜂鸣器会进行鸣叫,如下:
再次按下模式切换,进入温度测量模式,可以看到如下:
四、项目总结
本次设计利用虚拟串口,结合虚拟GPS软件在仿真上拓展了GPS功能,同时系统还有距离测算报警,温度测量等功能,使用虚拟串口扩展仿真的功能,使得Proteus向更为方便的方向上发展。