⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basec8051f040easygpssrc.txt

📁 基于C8051F040简易GPS导航仪源代码,应用于嵌入系统中
💻 TXT
📖 第 1 页 / 共 2 页
字号:
/*-----------“基于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 <C8051F040.h>
#include <stdio.h>
#include <stdlib.h>
#include<absacc.h>
#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 uint  xx,yy;
uint  i,j;
uchar i1;
uchar  k,p,q;
uchar is_front,is_end,length;//判别参数
uchar color;
int xdata  data_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<y?x:y);}
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);
}

/*****************初始化LCD上的电子地图***********************/
void Draw_LCD()
{
    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}};
	
	Clearlcd(0x03,0x11);  //清屏
	Clearlcd(219,0x01);

	Fill_in(aera_point,6,107);//新食堂
	Draw_line2(40,107,195,107);
	Draw_rectangle(3,0,104,10,0xe3);//西南边
	Draw_rectangle(110,0,231,10,0xe3);//东南边
	Draw_rectangle(161,16,231,86,109);//新主楼
	Draw_rectangle(110,16,155,86,109);//体育馆
	Draw_rectangle(176,71,216,31,0xfe);//新主楼天井
	Draw_rectangle(68,86,104,16,111);//篮球场
	Draw_rectangle(65,86,20,16,111);//操场
	Draw_rectangle(15,317,3,16,0xe3);// 西边
	Draw_rectangle(55,76,30,26,12);//操场草坪
	Draw_rectangle(145,162,231,92,109);//东南门区域
	Draw_rectangle(110,162,141,92,109);//办公区
	Draw_rectangle(110,290,231,164,30);//教学区
	Draw_rectangle(50,210,104,92,244);//生活区
	Draw_rectangle(20,216,104,290,16);//绿园
	Draw_rectangle(20,296,104,317,0xe3);//西北边
	Draw_rectangle(110,296,231,317,0xe3);//东北边
	Fill_in(aera_pool,6,0x03);//荷花池
}

/********************单片机主程序********************/
void main(void)
{
	int xdata flag=0;
	
	point a,b;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -