手持GPS系统设计项目报告材料

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实用文案
实验报告
实验项目名称:手持GPS系统设计
指导老师:
项目成员:
结题时间:2010—12-15
手持GPS系统设计
——项目报告
一:实验名称
手持GPS系统设计
二:实验目的
掌握嵌入式系统开发的方法, 熟练掌握从总体方案设计、硬件电路的搭建调试、软件的编写测试到最终的软硬件联调、系统性能测试等各环节;掌握GPS模块的控制方法.
三:实验内容
利用51单片机开发板,GPS接收机,液晶显示屏等实现低成本,简单的局域GPS导航定位系统的设计。

四:相关知识
1 .NMEA-0183协议
目前,GPS采用NMEA-0183协议做为发送和接收数据的标准,NMEA-0183是美国国家海洋电子协会(NationalMarine Electronics Association)为统一海洋导航规范而制定的标准,该格式标准已成为国际通用的一种格式,协议内容在兼容NMEA-180和
NMEA-0182的基础上。

增加了GPS、测深仪、罗经方位系统等多种设备接口和通讯协议定义,同时还允许一些特定厂商对其设备通信自定协议。

NMEA-0183格式数据串的所有数据都采用ASCⅡ文本字符表示,数据传输以“$”开头,后面是语句头。

语句头由5个字母组成。

其前2个字母表示“系统ID”,即表示该语句是属于何种系统或设备,例如GP表示该语句属于GPS定位系统,HC表示该语句属于罗经方位系统;后3个字母表示“语句ID",表示该语句是关于何方面的数据。

语句头后是数据体,包含不同的数据体字段,语句末尾为校验码(可选),以回车换行符<CR><LF>结束,也就是ACSII 字符“回车”(十六进制的0D)和“换行”(十六进制的0A)。

数据字段以逗号分隔识别,空字段保留逗号。

在GPS系统中常用语句有GPGGA(GPS定位信息),GPGSA(当前卫星信息),GPGSV(可见卫星信息),GPRMC(推荐定位信息),GPGLL(定位地理信息),GPVTG(地面速度信息) 等。

GPS数据传输是以标准异步串行方式发送,其串行通信波特率为4 800 b/s、数据位8位、停止位1位、无奇偶校验位。

不同的语句中传送不同的信息,如GPGGA语句中传送的格式为:$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>, M,<11>,<12>*hh<CR><LF>
传送的信息说明如下:
$GPGGA:起始引导符及语句格式说明(本句为GPS定位数据)
<1> UTC时间,时时分分秒秒格式
<2> 纬度,度度分分.分分分分格式(第一位是零也将传送)
<3> 纬度半球,N或S(北纬或南纬)
<4> 经度,度度分分.分分分分格式(第一位零也将传送)
<5> 经度半球,E或W(东经或西经)
<6> GPS质量指示,0=方位无法使用,1=非差分GPS获得方位,2=差分方式获得方位(DGPS),6=估计获得
<7> 使用卫星数量,从00到12(第一个零也将传送)
<8> 水平精确度,0.5到99.9
<9> 天线离海平面的高度,-9999.9到9999.9米M 指单位米
<10> 大地水准面高度,-999.9到9999.9米M 指单位米
<11> 差分GPS数据期限(RTCM SC-104),最后设立RTCM 传送的秒数量(如无DGPS为0)
<12> 差分参考基站标号,从0000到1023(首位0也将传送。

如无DGPS为0)
* 语句结束标志符
hh 从$开始的所有ASCII码的校验和
<CR>
<LF>
2.EM411 GPS接收模块简介
GPS接收模块性能主要决定于其内部使用的GPS核心芯片组,GPS芯片组SiRF Star III通过采用20万次/频率的相关器(Correlators)提高了灵敏度并能在室内定位。

冷开机/暖开机/热开机的时间分别达到42 s/38 s/1 s,可同时追踪20个卫星信道。

EM411型GPS接收模块采用SiRF Star III高效能GPS芯片组,其具有特点:极佳的灵敏度(追踪感度:-159 dBm);讯号微弱时,TTFF(Time to First Fix)定位仍十分迅速;支持NMEA 0183语言格式:GGA,GSA,GSV,RMC,GLL,VTG;内建超大电容,可储存快速获取的卫星讯号数据;内建陶瓷天线;LED指示灯显示卫星定位状况:LED不亮时接收器关闭,LED恒亮时未定位或搜寻讯号,LED 闪烁时已定位。

此外,EM411体积小巧,外形尺寸为30 mm×30 mm ×10.5 mm,工作时供电电压为4.5~6.5 V,消耗电流为60 mA。

对外提供6个引脚,使用时引脚1、5接地,引脚2接电源,引脚3为串口输出数据线,引脚4为串口输入数据线,引脚6悬空。

五:实验步骤
1.总体方案设计
通过GPS接收机接收信号,提取此信号中相关信息对移动的物体进行定位并在液晶显示屏上以及上位机上显示相关位置信息。

通过软硬件分别对接收的信号进行分析,通过一定的准换渠道得到我们所需要的实时位置进行定位。

总体方案设计图
2.软件设计
单片机部分
主程序流程首先是初始化,主要包括通用I/O端口,UART,SPI,以及LCD初始化,并在LCD 上显示开机初始信息。

接着单片机开始接收从EM411传送的GPS定位信息,该系统设计的只接收GPSGGA语句信息并将保存接收到的信息。

然后从中提取要显示在LCD上的信息,并然后键盘扫描,如果有键按下则进行键盘中断程序的处理。

当SW1键按下时,软件通过延时子程序设定一个固定的保存时间间隔。

当SW2键按下时,软件执行SD卡驱动子程序,可以方便地将GPS定位信息以FAT文件格式保存到SD卡中,并可在Windows操作系统下打开这些文件。

SD卡驱动子程序主要完成SD 卡初始化、卡插入检测、写保护检测、SD卡读/写命令的发送/接收、文件的更名、文件数据的传送等任务。

部分代码
/*配置GPS模块初始化函数*/
/*void Init_GPS( ){
uchar i;
uchar in[]="$PGRMO,,4*"; //发送数据数组
for(i=0;i<10;i++){
TI = 0;
SBUF = in[i];
while(!TI);
}
}
/*配置GPS模块使能特定几个输出语句子函数*/
/*void Enable_GPS( ){
uchar i;
uchar en[]="$PGRMO,GPRMC,1*"; //发送数据数组
for(i=0;i<15;i++){
TI = 0;
SBUF = en[i];
while(!TI);
}
}
/*配置GPS模块禁用所有输出语句子函数*/
/*void Disable_GPS( ){
uchar i;
uchar diData_BUF[]="$PGRMO,,2*"; //发送数据数组
for(i=0;i<10;i++){
TI = 0;
SBUF = diData_BUF[i];
while(!TI);
}
}
/*串口接收函数*/
uchar serial_recieve(void)
{ uint i=0;
RI=0; serial_ERROR=0;
while(!RI){
if(i++>30000){serial_ERROR=1;return SBUF; } };
RI=0;
return SBUF;
}
/*道路定位函数*/
void LocateRoads(struct Location *L,struct Road R[]) {
int i,j;
double k,b;
strcpy(L->name,"0");
for(j=0;j<RoadNum;j++)
{
for(i=0;i<6;i++)
{
if((R[j].point[i+1].y-R[j].point[i].y)<(R[j].point[i+1].x-R[j].po int[i].x)){//路是东西走向时
k=(R[j].point[i+1].y-R[j].point[i].y)/(R[j].point[i+1].x-R[j].po int[i].x);
b=R[j].point[i].y-k*R[j].point[i].x;
if((L->point.x-R[j].point[i].x)*(L->point.x-R[j].point[i+1].x)< 0)
if(fabs(L->point.x*k+b-L->point.y)*fabs(L->point.x*k+b-L->point.y)/(1+k*k)<RoadWide*RoadWide)
{
strcpy(L->name,R[j].name);return;
}
}
else{
//南北走向时
k=(R[j].point[i+1].x-R[j].point[i].x)/(R[j].point[i+1].y-R[j].po
int[i].y);
b=R[j].point[i].x-R[j].point[i].y*k;
if((L->point.y-R[j].point[i].y)*(L->point.y-R[j].point[i+1].y)< 0)
if(fabs(L->point.y*k+b-L->point.x)*fabs(L->point.y*k+b-L->point.x)/(1+k*k)<RoadWide*RoadWide)
{
strcpy(L->name,R[j].name);return;
}
}
}
}
}
/*高校定位函数*/
void LocateBuildings(struct Location *L,struct Building B[]) {
double k,b;
unsigned char i;
strcpy(L->name,"0");
for(i=0;i<BuildNum;i++)
{
k=(B[i].point[1].y-B[i].point[0].y)/(B[i].point[1].x-B[i].point[0 ].x);
b=B[i].point[1].y-k*B[i].point[1].x;
if(L->point.y>=L->point.x*k+b){
k=(B[i].point[3].y-B[i].point[2].y)/(B[i].point[3].x-B[i].point[2 ].x);
b=B[i].point[2].y-k*B[i].point[2].x;
if(L->point.y<=L->point.x*k+b){
k=(B[i].point[2].x-B[i].point[0].x)/(B[i].point[2].y-B[i].point[0 ].y);
b=B[i].point[2].x-B[i].point[2].y*k;
if(L->point.x>=L->point.y*k+b){
k=(B[i].point[3].x-B[i].point[1].x)/(B[i].point[3].y-B[i].point[1 ].y);
b=B[i].point[3].x-B[i].point[3].y*k;
if(L->point.x<=L->point.y*k+b)
{
strcpy(L->name,B[i].name);return;
}
}
}
}
}
}
/*液晶显示与清屏函数*/
void Init_LCD(void)
{
LCD_Data=0xff;
E=0;
Delay(100);
LCD_SET;//功能设定
Delay(10);
LCD_OFF;//关显示指令
Delay(10);
Write_com(0x06);//地址归位
Delay(10);
LCD_CLR;//清屏
Delay(10);
LCD_ON;//开显示
Delay(10);
}
上位机部分
通过使用上位机软件C#中相关控件将串口与GPS模块建
立连接通信。

每次触冲区接收完固定字节的数据,触发一个事件,自动从SBUF中接受所有数据存入str_org为原始数据,所接收到的数据中,我们只需要其中部分,所以使用字符串处理函数对字符进行剪切提取,提取出经度,纬度,海拔和时间四个量。

再将这四个参数与图像上已标定的参考点进行比较,运算,计算出本点在地图上的位置并用标记标注。

为了保证显示数据稳定,我们将单位时间内的一组数据平均化,再进行比较运算,减小了计算机的负荷,提高系统的响应速度。

附上位机程序界面:
在上位机的程序设计中,我们对于在应用中可能出现的异常处理进行了处理,防止程序的错误运行。

具体程序如下所示:
private void button1_Click(object sender, EventArgs e)
{
if ((Convert.ToString(comboBox2.SelectedItem)) == "")
{
MessageBox.Show("请先选择COM端口!", "系统提示");
return;
}
else if (serialPort1.IsOpen == false)
{
serialPort1.PortName = Convert.ToString(comboBox2.SelectedItem);
try
{
serialPort1.Open();
serialPort1.DiscardInBuffer(); } catch (Exception ex)
{
MessageBox.Show("端口不存在,请检查端口。

", "系统提示");
return;
}
Thread.Sleep(1100);
string qqqq;
qqqq = serialPort1.ReadExisting();
if (qqqq.Length < 7)
{
MessageBox.Show("不能读取数据,请检查连接", "系统提示");
serialPort1.Close();
{
if (qqqq.Length < 7)
return;
else
break;
}
}
}
if (serialPort1.IsOpen == false )
{
serialPort1.Open();
Thread.Sleep(2000);
string qqqq;
qqqq = serialPort1.ReadExisting();
if (qqqq.Length < 7)
{
MessageBox.Show("不能读取数据,请检查连接", "系统提示");
while (true)
{
if (qqqq.Length < 7)
else
break;
}
}
}
3.硬件设计
①主要芯片
a)STC89C52单片机
b)EM-411GPS接收模块②电路实现
a)部分电路
GPS电路图:
基于MCS-51系列单片机的GPS独立定位设备:
六:实验数据
道路经纬度转换数据:
建筑物经纬度转换数据:
七:实验心得
全球定位系统(Global Positioning System 简称GPS)
是美国第二代卫星导航系统。

它是在子午仪卫星导航系统的基础上发展起来的,GPS能提供全天候、连续、实时高精度导航参数,实现三维定位,并可提供精确的时间信息。

我们所设计的系统具有目前GPS的部分功能,能在南京仙林地区内应用,可以实现GPS导航定位以及轨迹显示等功能。

该系统具有结构简单,可移植性强,成本低,灵敏度高等特点,可以实现局域GPS导航系统,选用不同的的电子地图及应用场合,实现各种局域车载导航,智能交通及野外探测,也可以很方便的应用到其他导航定位场合(如校园,旅游景点等)。

八:附录
单片机部分程序
/*定位*/
#include<stdio.h>
#include <string.h>
#define RoadWide 0.0002 double fabs(double x) {
if(x<0) x=-x;
return x;
}
struct point
{
double x,y;
};
struct Building
{
char name[16];
struct point point[4];
struct Building *Next; };
struct Road
{
char name[16];
struct point point[6];
struct Road *Next;
};
struct Location
{
struct point point;
char name[16];
};
struct Building *BuildingPointer;
struct Building *Btail;
struct Road *RoadPointer;
struct Road *Rtail;
struct Location *LocationPointer;
#define BuildNum 1
#define RoadNum 1
struct Location Location={ {118.9118056 , 32.10356667 },"0"}
;
struct Building Building[10]={
{" 南邮",{{ 118.9227583 , 32.10653056 },{ 118.9307389 , 32.10913333 },{ 118.9201806 , 32.12024444 },{ 118.9281861 , 32.12385556 }}},
{" 南财",{{ 118.9121028 , 32.10325556 },{ 118.9224111 , 32.10665556 },{ 118.9105333 , 32.11351389 },{ 118.9189639 , 32.11989167 }}},
{" 南师",{{ 118.9001556 , 32.10044444 },{ 118.9115194 , 32.10355000 },{ 118.8906667 , 32.10600833 },{ 118.9085222 , 32.11263889 }}},
};
struct Road Road[10]={
{" 文苑路",{{ 118.8986528 , 32.09898333 },{ 118.9053472 , 32.10115833 },{ 118.912125 , 32.10324722 },{ 118.9195417 , 32.10551667 },{ 118.9252111 , 32.10724444 },{ 118.9309222 , 32.10886667 }}},
{" 学海路",{{ 118.9151528 , 32.12653611
},{ 118.9222528 , 32.11440833 },{ 118.9230889 , 32.11277778 },{ 118.9225639 , 32.10336389 },{ 118.923175 , 32.10150000 },{ 118.9277917 , 32.09604722 }}},
};
void LocateBuildings(struct Location *L,struct Building *B);
void LocateRoads(struct Location *L,struct Road *R);
void LocateBuildings(struct Location *L,struct Building *B)
{
double k,b;
strcpy(L->name,"0");
while(B){
k=(B->point[1].y-B->point[0].y)/(B->point[1].x-B-> point[0].x);
b=B->point[1].y-k*B->point[1].x;
if(L->point.y>=L->point.x*k+b){
k=(B->point[3].y-B->point[2].y)/(B->point[3].x-B->
point[2].x);
b=B->point[2].y-k*B->point[2].x;
if(L->point.y<=L->point.x*k+b){
k=(B->point[2].x-B->point[0].x)/(B->point[2].y-B-> point[0].y);
b=B->point[2].x-B->point[2].y*k;
if(L->point.x>=L->point.y*k+b){
k=(B->point[3].x-B->point[1].x)/(B->point[3].y-B-> point[1].y);
b=B->point[3].x-B->point[3].y*k;
if(L->point.x<=L->point.y*k+b)
{
strcpy(L->name,B->name);return;
}
}
}
}
B=B->Next;
}
}
void LocateRoads(struct Location *L,struct Road *R)
{
int i;
double k,b;
strcpy(L->name,"0");
while(R){
for(i=0;i<6;i++)
{
if((R->point[i+1].y-R->point[i].y)<(R->point[i+1].x-R->point[i].x)){//路是东西走向时
k=(R->point[i+1].y-R->point[i].y)/(R->point[i+1].x-R->point[i].x);
b=R->point[i].y-k*R->point[i].x;
if((L->point.x-R->point[i].x)*(L->point.x-R->point[i +1].x)<0)
if(fabs(L->point.x*k+b-L->point.y)*fabs(L->point.x* k+b-L->point.y)/(1+k*k)<RoadWide*RoadWide)
{
strcpy(L->name,R->name);return;
}
}
else{
//南北走向时
k=(R->point[i+1].x-R->point[i].x)/(R->point[i+1].y-R->point[i].y);
b=R->point[i].x-R->point[i].y*k;
if((L->point.y-R->point[i].y)*(L->point.y-R->point[i +1].y)<0)
if(fabs(L->point.y*k+b-L->point.x)*fabs(L->point.y* k+b-L->point.x)/(1+k*k)<RoadWide*RoadWide)
{
strcpy(L->name,R->name);return;
}
}
}
R=R->Next;
}
}
void InitMap()
{ int i;
BuildingPointer=Building;
RoadPointer=Road;
LocationPointer=&Location;
if(BuildNum>=2){
for(i=0;i<BuildNum-1;i++){
Btail=&Building[i];
Btail->Next=&Building[i+1];
}
}
if(RoadNum>=2){
for(i=0;i<RoadNum-1;i++){
Rtail=&Road[i];
Rtail->Next=&Road[i+1];
}
}
}
void Locate()
{
LocateBuildings(LocationPointer,BuildingPoint
er);
if(!strcmp(LocationPointer->name,"0"))
LocateRoads(LocationPointer,RoadPointer);
}
void main()
{
InitMap();
Locate();
printf("%s",LocationPointer->name);
}
/*GPS*/
//$GPRMC,010101.130, A, 3606.6834, N, 12021.7778, E, 0.0, 238.3, 010807,,,A*6C //$GPRMC, <1>, <2>, <3>, <4>,
<5>, <6>, <7>, <8>, <9>,
#include <reg51.h> // 引用标准库的头文件
#include<string.h>
#include"Locate.c"
#include"LCD_TCM12864N.H"
#define uchar unsigned char //宏定义无符号字符型
#define uint unsigned int //宏定义无符号整数型
enum status{init=0,show,search}
status; //led显示状态标志
//0:初始
//1:显示经纬度
//2:信号搜寻中;
uchar serial_ERROR;
uchar Data_BUF[42]; // 存放数据缓存数组
uchar time[16];
uchar datacount; //接收数据长度
uchar Recive_Complete; //GPS数据接收完
void ConvertTime();
void ConvertData();
void display(); //液晶显示
/*液晶显示*/
void Init_display(){
LCD_CLR;
LCD_LINE1;
Display_sentence("GPS 卫星定位系统");
}
void display(){
LCD_LINE1_3;
Display_sentence(time);
LCD_LINE2;
if(strcmp(,"0")!=0)
{ uint i;
Display_sentence();
for(i=0;i<16-strlen();i++) Display_sentence(" ");
}
else
Display_sentence(" ");
LCD_LINE3_3;
Display_double(Location.point.x);
LCD_LINE4_3;
Display_double(Location.point.y);
// Delay(20);
// EA=1;
}
/*配置GPS模块初始化函数*/
/*void Init_GPS( ){
uchar i;
uchar in[]="$PGRMO,,4*"; //发送数据数组
for(i=0;i<10;i++){
TI = 0;
SBUF = in[i];
while(!TI);
}
}
/*配置GPS模块使能特定几个输出语句子函数*/
/*void Enable_GPS( ){
uchar i;
uchar en[]="$PGRMO,GPRMC,1*"; //发送数据数组
for(i=0;i<15;i++){
TI = 0;
SBUF = en[i];
while(!TI);
}
}
/*配置GPS模块禁用所有输出语句子函数*/
/*void Disable_GPS( ){
uchar i;
uchar diData_BUF[]="$PGRMO,,2*"; //发送数据数组
for(i=0;i<10;i++){
TI = 0;
SBUF = diData_BUF[i];
while(!TI);
}
}
/*串口接收函数*/
uchar serial_recieve(void)
{ uint i=0;
RI=0; serial_ERROR=0;
while(!RI){
if(i++>30000){serial_ERROR=1;return SBUF; }
};
RI=0;
return SBUF;
}
code unsigned char GPS_ASC[]="$GPRMC";//定义特征字符串
/* 串口接收中断*/
void GetRs232_Data() interrupt 4{ //由于GPS发数据频率较快,所以中断程序必须短
uchar i;
RI = 0; // 清除中断标志位
Data_BUF[0] = SBUF;
if(Data_BUF[0]=='$'){
for(i=1;i<sizeof(GPS_ASC)-1;i++)
{
Data_BUF[i]=serial_recieve();
if(Data_BUF[i]!=GPS_ASC[i]) return;//是否为"$GPRMC"
}
for(;i<sizeof(Data_BUF);i++){
Data_BUF[i]=serial_recieve();
if(serial_ERROR){ //接收中断.串口被拔出
Recive_Complete=0;
return; }
if(i==18&&Data_BUF[i]=='V'){//GPS未定位
Recive_Complete=2;ES=0;
return;
}
}
Recive_Complete=1;
ES=0; //接收完数据禁止再次接收以免数据混叠}
}
//串口初始化函数
void Init_serial(void)
{
SCON = 0x40;//UART为模式1,8位数据
TMOD |= 0x20;//定时器1为模式2,8位自动重装
PCON &= 0x7f; //SMOD=0;
TH1 = 0xfa; //当SMOD=0时,fosc=11059200
时,baud=4800
TL1 = 0xfa;
TR1 = 1; // timer 1 run
EA = 1; //中断允许总控位
ES = 1; //串行口中断允许位
TR1 = 1; //启动定时器1
TI = 1;
REN = 1; //允许串行接收控制位
}
void ConvertTime()
{uint timex;
timex=((Data_BUF[7]-'0')*10+Data_BUF[8]-'0'+8) %24;
time[0]=timex/10+'0';
time[1]=timex%10+'0';
time[2]=':';
time[3]=Data_BUF[9];
time[4]=Data_BUF[10];
time[5]=':';
time[6]=Data_BUF[11];
time[7]=Data_BUF[12];
}
void ConvertData()
{
strcpy(,"0");
Location.point.x=(Data_BUF[32]-'0')*100+(Dat a_BUF[33]-'0')*10+(Data_BUF[34]-'0')+ //经度
((Data_BUF[35]-'0')*10+(Data_BUF[36]-'0')+
(Data_BUF[38]-'0')*1.0/10+(Data_BUF[39]-'0')*1.0/1 00+(Data_BUF[40]-'0')*1.0/1000+(Data_BUF[41]-'0')* 1.0/10000)/60;
Location.point.y=(Data_BUF[20]-'0')*10+(Data _BUF[21]-'0')+ //纬度
((Data_BUF[22]-'0')*10+(Data_BUF[23]-'0')+
(Data_BUF[25]-'0')*1.0/10+(Data_BUF[26]-'0')*1.0/1 00+(Data_BUF[27]-'0')*1.0/1000+(Data_BUF[28]-'0')* 1.0/10000)/60;
}
/*主函数*/
void main( ){
datacount=0;
Init_LCD();
Init_display(); //欢迎界面
/* 初始化串口*/
Init_serial();
while(1){
if(Recive_Complete==1){
Recive_Complete=0;
if(status!=show){
status=show;
LCD_CLR;
LCD_LINE1;
Display_sentence("时间: ");
LCD_LINE3;
Display_sentence("东经: ");
LCD_LINE4;
Display_sentence("北纬: ");
if(Data_BUF[18]=='A')
{
ConvertTime();
ConvertData();
Locate();
display();
}
ES=1; //处理完数据允许接收新数据}
else if(Recive_Complete==2){
if(status!=search)
{
status=search;
Recive_Complete=0;
LCD_CLR;
LCD_LINE1;
Display_sentence("时间: ");
LCD_LINE2;
Display_sentence("GPS 未定位");
LCD_LINE3;
Display_sentence("搜寻信号中...");
ConvertTime();
LCD_LINE1_3;
Display_sentence(time);
ES=1;
}
}; //等待接收GPS数据
}
/*LCD_TCM12864N*/
#ifndef LCD_TCM12864N_H__
#define LCD_TCM12864N_H__
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_Data P1 //定义P1口为液晶数据口
uchar Busy; //液晶忙标志
sbit RS=P3^6; //液晶指令/数据选择信号
sbit RW=P3^7; //液晶读写选择信号sbit E=P3^5; //液晶使能信号
#define LCD_CLR Write_com(0x01)
#define LCD_ON Write_com(0x0c)
#define LCD_OFF Write_com(0x08)
#define LCD_SET Write_com(0x30)
#define LCD_LINE1 Write_com(0x80)
#define LCD_LINE1_1 Write_com(0x81)
#define LCD_LINE1_2 Write_com(0x82)
#define LCD_LINE1_3 Write_com(0x83)
#define LCD_LINE1_4 Write_com(0x84)
#define LCD_LINE1_5 Write_com(0x85)
#define LCD_LINE1_6 Write_com(0x86)
#define LCD_LINE1_7 Write_com(0x87)
#define LCD_LINE2 Write_com(0x90)
#define LCD_LINE2_1 Write_com(0x91)
#define LCD_LINE2_2 Write_com(0x92)
#define LCD_LINE2_3 Write_com(0x93)
#define LCD_LINE2_4 Write_com(0x94)
#define LCD_LINE2_5 Write_com(0x95)
#define LCD_LINE2_6 Write_com(0x96)
#define LCD_LINE2_7 Write_com(0x97)
#define LCD_LINE3 Write_com(0x88) #define LCD_LINE3_1 Write_com(0x89) #define LCD_LINE3_2 Write_com(0x8A) #define LCD_LINE3_3 Write_com(0x8B) #define LCD_LINE3_4 Write_com(0x8C) #define LCD_LINE3_5 Write_com(0x8D) #define LCD_LINE3_6 Write_com(0x8E) #define LCD_LINE3_7 Write_com(0x8F) #define LCD_LINE4 Write_com(0x98) #define LCD_LINE4_1 Write_com(0x99) #define LCD_LINE4_2 Write_com(0x9A) #define LCD_LINE4_3 Write_com(0x9B) #define LCD_LINE4_4 Write_com(0x9C) #define LCD_LINE4_5 Write_com(0x9D) #define LCD_LINE4_6 Write_com(0x9E) #define LCD_LINE4_7 Write_com(0x9F)
/* 延时t毫秒*/
void Delay(uint t){
uint x,z;
for(x=t;x>0;x--)
for(z=110;z>0;z--);
}
void Check_busy()
{
RW=1;
RS=0;
do
{
LCD_Data=0xff;
E=1;
Delay(5);
Busy=P1;
E=0;
}while(Busy&0x80);
}
void Write_com(uchar com) //写指令{
Check_busy();
RW=0;
RS=0;
E=1;
Delay(5);
LCD_Data=com;
E=0;
}
void Write_dat(uchar dat) //写数据{
Check_busy();
RW=0;
RS=1;
LCD_Data=dat;
E=1;
Delay(5);
E=0;
}
void Display_sentence(uchar *p) {
while(*p)
{
Write_dat(*p++);
}
}
int exp(int x)
{int i,s;
s=1;
for(i=0;i<x;i++)
s=s*10;
return s;
}
void Display_int(uint x)
{
unsigned char weishu;
int i;
int temp;
temp=x;
weishu=0;
while(temp)
{ temp=temp/10;weishu++; } temp=x;
for(i=weishu-1;i>=0;i--)
{
Write_dat(temp/exp(i)+'0');
temp=temp%exp(i);
}
}
void Display_double(double x) {
uint temp;
temp=x;
Display_int(temp);
Display_sentence(".");
temp=(x-temp)*100000;
Display_int(temp);
}
void Init_LCD(void)
{
LCD_Data=0xff;
E=0;
Delay(100);
LCD_SET;//功能设定
Delay(10);
LCD_OFF;//关显示指令
Delay(10);
Write_com(0x06);//地址归位
Delay(10);
LCD_CLR;//清屏
Delay(10);
LCD_ON;//开显示
Delay(10);
}
#endif
上位机部分
#include<stdio.h>
#include<string.h>
#define RoadWide 0.0002
double fabs(double x)
{
if(x<0) x=-x;
return x;
}
struct point
{
double x,y;
};
struct Building
{
char name[16];
struct point point[4];
struct Building *Next;
};
struct Road
{
char name[16];
struct point point[6];
struct Road *Next;
};
struct Location
{
struct point point;
char name[16];
};
struct Building *BuildingPointer; struct Building *Btail;
struct Road *RoadPointer; struct Road *Rtail;
struct Location *LocationPointer;
#define BuildNum 1
#define RoadNum 1
struct Location Location={ {118.9118056 , 32.10356667 },"0"}
;
struct Building Building[10]={
{" 南?邮?",{{ 118.9227583 , 32.10653056 },{ 118.9307389 , 32.10913333 },{ 118.9201806 , 32.12024444 },{ 118.9281861 , 32.12385556 }}},
{" 南?财? ",{{ 118.9121028 , 32.10325556 },{ 118.9224111 , 32.10665556 },{ 118.9105333 , 32.11351389 },{ 118.9189639 , 32.11989167 }}},
{" 南?师簗",{{ 118.9001556 , 32.10044444 },{ 118.9115194 , 32.10355000 },{ 118.8906667 , 32.10600833 },{ 118.9085222 , 32.11263889 }}},
};
struct Road Road[10]={
{" 文?苑·路·",{{ 118.8986528 , 32.09898333 },{ 118.9053472 , 32.10115833 },{ 118.912125 , 32.10324722 },{ 118.9195417 , 32.10551667 },{ 118.9252111 , 32.10724444 },{ 118.9309222 , 32.10886667 }}},
{" 学§海£路·",{{ 118.9151528 , 32.12653611 },{ 118.9222528 , 32.11440833
},{ 118.9230889 , 32.11277778 },{ 118.9225639 , 32.10336389 },{ 118.923175 , 32.10150000 },{ 118.9277917 , 32.09604722 }}},
};
void LocateBuildings(struct Location *L,struct Building *B);
void LocateRoads(struct Location *L,struct Road *R);
void LocateBuildings(struct Location *L,struct Building *B)
{
double k,b;
strcpy(L->name,"0");
while(B){
k=(B->point[1].y-B->point[0].y)/(B->point[1].x-B->point[0].x);
b=B->point[1].y-k*B->point[1].x;
if(L->point.y>=L->point.x*k+b){
k=(B->point[3].y-B->point[2].y)/(B->point[3].x-B->point[2].x);
b=B->point[2].y-k*B->point[2].x;
if(L->point.y<=L->point.x*k+b){
k=(B->point[2].x-B->point[0].x)/(B->point[2].y-B->point[0].y);
b=B->point[2].x-B->point[2].y*k;
if(L->point.x>=L->point.y*k+b){
k=(B->point[3].x-B->point[1].x)/(B->point[3].y-B->point[1].y);
b=B->point[3].x-B->point[3].y*k;
if(L->point.x<=L->point.y*k+b)
{
strcpy(L->name,B->name);return;
}
}
}
}
B=B->Next;
}
}
void LocateRoads(struct Location *L,struct Road *R)
{
int i;
double k,b;
strcpy(L->name,"0");
while(R){。

相关文档
最新文档