/***************************************************************************
** Project name:GPS_LCD Nvigation System Experiment
**
** Descriptions:Undergraduate Group Project of Navigation & Control
**
** Created by:GPS_LCD Nvigation System Design Group
**
** Major:Navigation & Control, Beihang University
**
** Supervisor:Professor Zhanghai, Zhang Liyong
**
** Created Date:11 Jan 2007
**
****************************************************************************/
#include
#include
#include
#include
#define baud rate 4800
#define N 100
#define HANG 20
#define LIE 12
#define dlcd XBYTE[0x8000]/*定义送数据的地址*/
#define clcd1 XBYTE[0xa000]/*定义送指令的地址,行地址*/
#define clcd2 XBYTE[0xc000]/*定义送指令的地址,列地址*/
#define clcd3 XBYTE[0xe000]/*定义送指令的地址,设置显示页和操作页*/
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
typedef struct {uint x; uint y;}point;
sfr16 RCAP2=0xca;
sfr16 RCAP3=0xca;
sfr16 RCAP4=0xca;
sfr16 TMR2=0xcc;
xdata uchar GPS_infor[N];//处理缓冲区
xdata uchar GPS_buff[N];//接收区
xdata uchar GPS_sec[HANG][LIE];//2维数组
xdata uchar GPS_sec_temp1[11];//中间变量1
xdata uchar GPS_sec_temp2[5];//中间变量2
xdata uchar mode[LIE];
xdata ulong longitude=0;//纬度
xdata ulong latitude=0;//经度
xdata ulong lol=0;//经度低位
xdata ulong loh=0;//经度高位
xdata ulong lal=0;//纬度低位
xdata ulong lah=0;//纬度高位
xdata uintxx,yy;
uinti,j;
uchar i1;
uchark,p,q;
uchar is_front,is_end,length;//判别参数
uchar color;
int xdatadata_col[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//区域填充交点存储数组
void Clearlcd(uchar color,uchar ppage);/*清屏*/
void Draw_point(uint x,uint y,uchar point_color);//画点子程序
void Draw_line(point point_a,point point_b,uchar line_color);//画线子程序
void Fill_in(point *peak,int mun,uchar fill_color);//区域填充子程序
void Draw_rectangle(int x1,int y1,int x2,int y2,uchar color);
void Draw_position(uint color);
void delay1ms(uint time);
void Get_color(uint x,uint y);
int node(point *peak,int row,int num,uchar color);//交点求取子程序
void sort_data(int *node_in,int num);//排序子程序
int drop_data(int *node_in,int num);//重点去除子程序
void Draw_line2(uint row,uint col_s,uint col_f,uchar color);//画水平线子程序
uint max(uint x,uint y){return (x>y?x:y);}
uint min(uint x,uint y){return (x void EMI_ini(); void uart0_ini(); void t2_ini(); void t2_baud(uint rate); void config (void); void para_clear(); void SendChar(uchar tt); void EMI_ini() { SFRPAGE= EMI0_PAGE; EMI0CF = 0x37; EMI0TC = 0xFF; } /************************串口初始化配制*****************************/ void uart0_ini() { SFRPAGE = UART0_PAGE; SADEN0 = 0x00;// SADEN0为UART0从机地址控制寄存器,0表示相应位地址不参加过滤,即该位地址值为0或1均为有效地址 SADDR0 = 0x00;// SADDR0为UART0从机地址设置寄存器 SSTA0 = 0x15;// SMOD0=1,UART0波特率2分频允许,此时在使用T1至T4为波特率发生定时器时,计算公式为BandRate=ft/16,ft为T1至T4的溢出率 //TX0时钟源为T2,RX0时钟源为T2 SCON0 = 0x50;//工作在模式1,为8bit可变波特率通讯 SCON0 &= 0xFC;//将TI0和RI0清零 t2_ini();//初始化UART0的波特率产生定时器T2 } /*************************定时器2初始化配制****************************/ void t2_ini() { SFRPAGE=TMR2_PAGE; TMR2CF = 0x10;// T2为外部时钟的8分频,计数方向为增值计数 TMR2CN = 0x04;// TR2置1,启动定时器 } /*************************定时器2产生波特率为4800bps*************************/ void t2_baud(uint rate) { uint count; SFRPAGE = TMR2_PAGE; count=22118400/8/16/rate; RCAP2=~count+1;//RCAP2用于存放定时器重载值,TMR2是计数寄存器 TMR2=RCAP2; } void config() { uchar n; WDTCN = 0xDE;//禁止看门狗 WDTCN = 0xAD; SFRPAGE = CONFIG_PAGE; XBR0 = 0x34;//将PCA0至PCA5和UART0配置到端口 XBR1 = 0x00; XBR2 = 0x44;//全局弱上拉开启,将XBAR打开;TX1,RX1配置到端口 XBR3 = 0x00; P0MDOUT = 0xFF; P1MDOUT = 0xFF; P1MDIN = 0xFF; P4MDOUT = 0xff; P5MDOUT = 0xff; P7MDOUT = 0xff; SFRPAGE = CONFIG_PAGE; //晶振配置,系统时钟采用采用内部晶振微调后8分频 CLKSEL= 0x00;//系统时钟采用内部晶振 OSCXCN= 0x67;//外部晶振配置:外部石英晶振模式,不分频,并配置合适的驱动电流 for(;n<255;n++) while((OSCXCN&0x80)==0);//查询XTLVLD是否为1,等待外部晶振稳定振荡 CLKSEL= 0x00;//选择内部晶振 OSCICN= 0x83; SFRPAGE=0x0F; SFRPGCN=0x01; IE=0x90;//若UART0使用中断方式则应该开全局中断 }//端口与时钟配置函数 /*********************采用查询方式串口输出**************************/ void SendChar(uchar tt) { SBUF0=tt; while(TI0==0); TI0=0; } /*****************************参数清零*****************************/ void para_clear() { i=0; j=0; p=0; q=0; k=0; } /*****************************GPS码分割函数*****************************/ void GPS_div() { para_clear(); for(k=0;k<=length;k++)//利用',',将数组进行分割,存到二维数组div中 { if(GPS_infor[k]!=','){GPS_sec[p][q]=GPS_infor[k];q++;} else {p++;q=0;} } } /**********************通过串口输出接收进来的GPS数据*******************/ void GPS_out() { p=2;//纬度部分 for(q=0;GPS_sec[p][q]!='\0';q++) { SFRPAGE=0; SendChar(GPS_sec[p][q]); } SendChar('*'); p=4;//经度部分 for(q=0;GPS_sec[p][q]!='\0';q++) { SFRPAGE=0; SendChar(GPS_sec[p][q]); } SendChar('*'); } /*************GGA码解码函数,得到latitude和longitude用整数类型存储***********/ void GGA_deal() { para_clear();//整数小数同存,按单位统一到角度 for (i=0;GPS_sec[2][i]!='.';i++) GPS_sec_temp1[i]=GPS_sec[2][i];//按.分割 移位 for (j=i;j<=i+3;j++) GPS_sec_temp1[j]=GPS_sec[2][j+1]; for (j=j;j<11;j++) GPS_sec_temp1[j]='\0'; latitude=atol(GPS_sec_temp1); for (i=0;GPS_sec[4][i]!='.';i++) GPS_sec_temp1[i]=GPS_sec[4][i]; for (j=i;j<=i+3;j++) GPS_sec_temp1[j]=GPS_sec[4][j+1]; for (j=j;j<11;j++) GPS_sec_temp1[j]='\0'; longitude=atol(GPS_sec_temp1); lal=latitude%1000000;//取出角分 lol=longitude%1000000; lah=latitude-lal;//取出角度 loh=longitude-lol; lal=lal*100/60;//化角分为度 lol=lol*100/60; latitude=lah+lal;//整合 longitude=loh+lol; para_clear(); } /************GPS信息解算,并在LCD屏幕上标出用户所在位置************/ void GPS_cau() { point xdata aera_point[6]={{22,195},{40,195},{48,175},{48,127},{40,107},{22,107}}; point xdata aera_pool[6]={{84,275},{94,245},{94,226},{60,232},{54,240},{70,250}}; xx=(longitude-116334919)/53;//按经纬度边界计算LCD上画点位置 yy=(latitude-39975169)/31; Get_color(xx,yy); //Draw_position(0xe3); //delay1ms(2000); //Draw_position(color); /*xx=xx+5; yy=yy+5; Get_color(xx,yy); Draw_position(0xfc); delay1ms(2000); Draw_position(color);*/ for(i1=0;i1<10;i1++) { xx=xx+1; Get_color(xx,yy); Draw_position(0xfc); delay1ms(1000); Draw_position(color); } for(i1=0;i1<10;i1++) { yy=yy+1; Get_color(xx,yy); Draw_position(0xfc); delay1ms(1000); Draw_position(color); } for(i1=9;i1>0;i1--) { xx=xx-1; Get_color(xx,yy); Draw_position(0xfc); delay1ms(1000); Draw_position(color); } for(i1=9;i1>0;i1--) { yy=yy-1; Get_color(xx,yy); Draw_position(0xfc); delay1ms(1000); Draw_position(color); } } /************得到原来点的颜色值,以便进行覆盖************/ void Get_color(uint x,uint y) { uchar high,low; high = (y&0xff00)>>8; low = y&0xff; clcd3=0x00;//设定操作页和显示页 clcd1=x;//设定行地址 clcd2=high;//设定列地址 clcd2=low; color=dlcd; } /************画出用户位置,在LCD屏幕上用十字显示************/ void Draw_position(uint color)//画出所在点的位置 { Draw_point(xx,yy,color); Draw_point(xx-1,yy,color); Draw_point(xx+1,yy,color); Draw_point(xx,yy,color); Draw_point(xx,yy-1,color); Draw_point(xx,yy+1,color); }