基於C8051F040簡易GPS導航儀的實現源程序

admin @ 2014-03-25 , reply:0

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



[admin via 研發互助社區 ] 基於C8051F040簡易GPS導航儀的實現源程序已經有1237次圍觀

http://cocdig.com/docs/show-post-42091.html