基于C8051F040简易GPS导航仪的实现源程序
2012-06-02
标签: C8051F040 GPS

/***************************************************************************

** 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);

}

共 2 页   12下一页
可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号