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

📄 gps_6610.c

📁 GPS DEMO CODE FOR NOKIA6610 LCD,下载于OURAVR.COM.
💻 C
字号:
#include "My_NOKIA6610/LCD_6610_Config.h"
#include "UART/UART.h"
#include "LCD_Graphic.h"
#include "GPS_Config.h"

uint8 SatNum[2+1];       //位星数目
uint8 SatDetail[12*2+1]; //定位卫星详细信息,编号
uint8 GPSMode = 0;       //GPS是否有效定位模式
uint8 GPS_Status = 0;    //定位状态
uint8 GPS_Height[10];    //海拔高度

uint8 Mapx = 0;//地图上点的坐标
uint8 Mapy = 0;

uint8 MapWidth  = 130; //地图宽象素
uint8 MapHeight = 83;  //地图高象素

struct GPS_Time
{
	uint8 t_year[2+1];
	uint8 t_mon[2+1];
	uint8 t_day[2+1];
	uint8 t_hour[2+1];
	uint8 t_min[2+1];
	uint8 t_sec[2+1];
}CurTime;//时间

struct GPS_LL
{
	uint8 ll_line;
	uint8 ll_degree[3+1];
	uint8 ll_cent[2+1];
	uint8 ll_secb[2+1];
	uint8 ll_secs[2+1];
} CurLong, CurLat;//经纬度

struct GPS_LL MapLatUp, MapLatDown, MapLongLeft, MapLongRight;//地图坐标

void Load_Dat(struct GPS_LL *mapll, uint8 *dat)//装入数据
{
	uint8 i;
	uint16 secb = 0; //秒高位
	uint8 secbh = 0;//秒高十位
	uint8 secbl = 0;//秒高个位

	(*mapll).ll_line = *(dat++);
	for(i=0; i<3; i++)
	{
		(*mapll).ll_degree[i] = *(dat++);
	}
	(*mapll).ll_degree[3] = '\0';
	for(i=0; i<2; i++)
	{
		(*mapll).ll_cent[i] = *(dat++);
	}
	(*mapll).ll_cent[2] = '\0';
	secbh = *(dat++);
	secbl = *(dat++);
	secb = (secbh-'0')*10 + (secbl-'0');//秒高位
	secb = secb * 5 / 3;//由六十进制转为一百进制
	(*mapll).ll_secb[0] = (secb/10) + '0';
	(*mapll).ll_secb[1] = (secb%10) + '0';
	(*mapll).ll_secb[2] = '\0';
	for(i=0; i<2; i++)
	{
		(*mapll).ll_secs[i] = *(dat++);//秒低位
	}
	(*mapll).ll_secs[2] = '\0';
}

void Init_Map()//初始化地图
{
	Load_Dat(&MapLongLeft,  LONG_LEFT);//装入数据
	Load_Dat(&MapLongRight, LONG_RIGHT);//装入数据
	Load_Dat(&MapLatUp,     LAT_UP);//装入数据
	Load_Dat(&MapLatDown,   LAT_DOWN);//装入数据
}

void ClearBuffer(uint8 *str, uint16 n)
{
	uint16 i;
	for(i=0; i<n; i++)
	{	
		*(str++) = 0;
	}
}

uint8 GPS_XORCheck(uint8 *str)//校验和
{
	uint8 xorDat = 0x00;
	while(*str == '$')
	{
		str++;
	}

	for(; *str!='*';)
	{
		xorDat ^= (*(str++));
	}
	return xorDat;
}

void GPS_Write(uint8 *str, uint8 mode)//写GPS(目标语句名,状态参数)
{
	uint8 i;
	uint8 *pstr;
	uint8 xorDat = 0;
	uint8 Buffer[25]={
					'$', 'P', 'G', 'R', 'M', 'O', ',',   0,
					  0,   0,   0,   0,   0,   0,   0,   0,
					  0,   0,   0,   0,   0,   0,   0,   0,
					  0,   
				};
	if(mode < '4')
	{
		pstr = &Buffer[7];
		for(;*str!='\0';)
		{
			*(pstr++) = *(str++);
		}
		*(pstr++) = ',';
		*(pstr++) = mode;
		*(pstr++) = '*';
		xorDat = GPS_XORCheck(Buffer);//计算异或和
		*(pstr++) = Hex4ToChar(xorDat>>4);//高位
		*(pstr++) = Hex4ToChar(xorDat & 0x0f);//低位
		*(pstr++) = 13;   //CR
		*(pstr++) = 10;   //LF
		*(pstr++) = '\0'; //0
	}
	if(mode == '4')
	{
		pstr = PRWIZCHOFF;
		for(i=0;(*pstr)!='\0';i++)
		{
			Buffer[i] = *(pstr++);
		}
	}
	if(mode == '5')
	{
		pstr = PRWIZCHON;
		for(i=0;(*pstr)!='\0';i++)
		{
			Buffer[i] = *(pstr++);
		}
		
	}
	for(i=0; Buffer[i]!='\0'; i++)
	{
		USART_putchar(Buffer[i]);//写目标语句名
	}
//	LCD_ShowStr(0, 80, Buffer);               //显示字符串
}

void CGPSStartDat(prog_char *str)//比较到字符串相等
{
	uint8 i;
x:
	while(USART_getchar() != '$');
	for(i=0; pgm_read_byte(&str[i])!='\0'; i++)
	{
		if(USART_getchar() != pgm_read_byte(&str[i]))
			goto x;
	}
}

void WaitnDat(uint8 n)//等到第n个数据
{
	uint8 i;
	for(i=0; i<n; i++)
	{
		while(USART_getchar() != ',');
	}
}

void Get1GPSDat(uint8 *str)//收1个数据,即在','与','或'*'之间的数据
{
	uint8 dat;
	for(;;)
	{
		dat=USART_getchar();
		if((dat != ',') && (dat != '*'))
		{
			*(str++) = dat;
		}
		else
		{
			*str = '\0';
			break;
		}
	}
}

void CopyDat(uint8 *des, uint8 *sour, uint8 n)//复制数据
{
	uint8 i;
	for(i=0; i<n; i++)
	{
		*(des++)=*(sour++);
	}
	*des = '\0';
}

void GetGPSDat()//得到GPS数据
{
	uint8 i;
	uint8 dat[10];
	CGPSStartDat(PSTR("GPGGA\0"));//比较到字符串相等,GPGGA
	WaitnDat(7);//等到第n个数据,n=7,定位卫星数
	Get1GPSDat(SatNum);//卫星数
	WaitnDat(1);//等到1个数据,
	Get1GPSDat(GPS_Height);//高度

	CGPSStartDat(PSTR("GPGSA\0"));//比较到字符串相等,GPGSA
	WaitnDat(2);//等到第n个数据,n=2,定位模式
	GPSMode = USART_getchar();
	WaitnDat(1);//等到第n个数据,n=1
	for(i=0; i<12; i++)//12颗卫星定位情况
	{
		Get1GPSDat(SatDetail);//收1个数据
	}

	CGPSStartDat(PSTR("GPRMC\0"));//比较到字符串相等,GPRMC
	WaitnDat(1);//等到1个数据,n=1,时间
	Get1GPSDat(dat);//时间
	CurTime.t_hour[0] = dat[0];
	CurTime.t_hour[1] = dat[1];
	CurTime.t_hour[2] = '\0';
	CurTime.t_min[0]  = dat[2];
	CurTime.t_min[1]  = dat[3];
	CurTime.t_min[2]  = '\0';
	CurTime.t_sec[0]  = dat[4];
	CurTime.t_sec[1]  = dat[5];
	CurTime.t_sec[2]  = '\0';
	GPS_Status = USART_getchar();//定位状态
	WaitnDat(1);//等到1个数据,n=1,纬度
	Get1GPSDat(dat);//纬度
	CopyDat(CurLat.ll_degree, &dat[0], 2);  //复制数据
	CopyDat(CurLat.ll_cent,   &dat[2], 2);  //复制数据
	CopyDat(CurLat.ll_secb,   &dat[5], 2);  //复制数据,去掉小数点
	CopyDat(CurLat.ll_secs,   &dat[7], 2);  //复制数据,去掉小数点
	CurLat.ll_line = USART_getchar();       //南北纬
	WaitnDat(1);//等到1个数据,n=1,
	Get1GPSDat(dat);//经度
	CopyDat(CurLong.ll_degree, &dat[0], 3); //复制数据
	CopyDat(CurLong.ll_cent,   &dat[3], 2); //复制数据
	CopyDat(CurLong.ll_secb,   &dat[6], 2); //复制数据,去掉小数点
	CopyDat(CurLong.ll_secs,   &dat[8], 2); //复制数据,去掉小数点
	CurLong.ll_line = USART_getchar();      //东西经
	WaitnDat(3);//等到3个数据, 日期
	Get1GPSDat(dat);//日期
	CurTime.t_day[0]  = dat[0];
	CurTime.t_day[1]  = dat[1];
	CurTime.t_day[2]  = '\0';
	CurTime.t_mon[0]  = dat[2];
	CurTime.t_mon[1]  = dat[3];
	CurTime.t_mon[2]  = '\0';
	CurTime.t_year[0] = dat[4];
	CurTime.t_year[1] = dat[5];
	CurTime.t_year[2] = '\0';

}

void ChangeParameter()//转换数据格式
{
	uint8 time;
	time = (CurTime.t_hour[0] - '0')*10 + (CurTime.t_hour[1] - '0') + 8;//转换北京时间
	if (time > 23)
	{
		time -= 24;
	}
	CurTime.t_hour[0] = (time / 10) + '0';
	CurTime.t_hour[1] = (time % 10) + '0';

	//,,
}

uint16 SubLL(struct GPS_LL  Subtrahend, struct GPS_LL Minuend)//GPS经纬度相减
{
	uint16 dat;
	uint8  CentDatH;
	uint16 SecDatH;
	uint8  CentDatL;
	uint16 SecDatL;
	CentDatH = ((Subtrahend.ll_cent[0]-'0')*10 + (Subtrahend.ll_cent[1]-'0'));
	CentDatL = ((Minuend.ll_cent[0]-'0')*10 + (Minuend.ll_cent[1]-'0'));
	if(CentDatH < CentDatL)
	{
		return -1;
	}
	dat = (CentDatH - CentDatL)*10000;
	SecDatH = ((Subtrahend.ll_secb[0]-'0')*1000 + (Subtrahend.ll_secb[1]-'0')*100
		+ (Subtrahend.ll_secs[0]-'0')*10 + (Subtrahend.ll_secs[1]-'0'));
	SecDatL = ((Minuend.ll_secb[0]-'0')*1000 + (Minuend.ll_secb[1]-'0')*100
		+ (Minuend.ll_secs[0]-'0')*10 + (Minuend.ll_secs[1]-'0'));
	if((CentDatH == CentDatL) && (SecDatH < SecDatL))
	{
		return -1;
	}
	dat = (dat + SecDatH - SecDatL);
	return dat;
}

void ProcessCoo()//处理数据,把接收到的数据转为坐点
{
	uint16 x;
	uint16 y;
	uint16 Sx;
	uint16 Sy;
	if(SubLL(CurLong, MapLongLeft) != -1 
		&& SubLL(CurLat, MapLatDown) != -1
		&& SubLL(MapLongRight, CurLong) != -1
		&& SubLL(MapLatUp, CurLat) != -1
		)
	{
		Sx = SubLL(MapLongRight, MapLongLeft) / MapWidth;//5296/130=40
		Sy = SubLL(MapLatUp, MapLatDown) / MapHeight;//2955/85=34
		x =  (SubLL(CurLong, MapLongLeft) - ModifyLong) / Sx;//4168/40=104,0x68
		y =  (SubLL(CurLat, MapLatDown) - ModifyLat) / Sy;//1758/34=51,0x33
		//在这里写数据点
		if(Mapx == 0 && Mapy == 0)//第一个点
		{
			LCD_6610_ShowGraphic(0, CurY_MAX-MapHeight, MapWidth, MapHeight, graph);//写入位图(xs,ys,x_dot,y_dot,pG)
		}
		else
		{
			nRGB(255, 0, 0);//画红线
			LCD_6610_DrawLine(x, CurY_MAX - y, Mapx, Mapy);//画线函数
		}
		Mapx = x;
		Mapy = CurY_MAX - y;		
		if(GPSMode == Loc_3D)//三维定位显示红色
		{
			nRGB(255, 0, 0);
		}
		else if(GPSMode == Loc_2D)
		{
			nRGB(0, 0, 255);//二维定位显示红色
		}
		else
		{
			nRGB(0, 0, 0);//无效定位显黑色
		}
	}
	else
	{
		nRGB(255, 0, 255); //超出范围显紫色
	}
//	else//超出地图范围
//	{
//		x = 0;
//		y = 0;
//	}
//	LCD_ShowHex(0, 0, x);//显示HEX
//	LCD_ShowHex(24, 0, y);//显示HEX
}

void DisLL(uint8 xs, uint8 ys, struct GPS_LL dsp_ll)//显示经纬度
{
	LCD_ShowChar(     xs, ys, dsp_ll.ll_line); //东西经	
	LCD_ShowChar(xs +  8, ys, ':');	
	LCD_ShowStr( xs + 16, ys, dsp_ll.ll_degree);//度	
	LCD_ShowChar(xs + 40, ys, 0x80);            //显示字符,度	
	LCD_ShowStr( xs + 48, ys, dsp_ll.ll_cent); //分
	LCD_ShowChar(xs + 64, ys, '\'');
	LCD_ShowStr( xs + 72, ys, dsp_ll.ll_secb); //秒,整数	
	LCD_ShowChar(xs + 88, ys, '.');
	LCD_ShowStr( xs + 96, ys, dsp_ll.ll_secs); //秒,小数位	
	LCD_ShowChar(xs +112, ys, '"');
}

void Display()//显示
{
	uint8 TimeL = 0;       //时间, 行
	uint8 TimeC = 0;       //时间, 列
	uint8 LongitudeL = 16; //经度,行
	uint8 LongitudeC = 2;  //经度,列
	uint8 LatitudeL  = 32; //纬度,行
	uint8 LatitudeC  = 2;  //纬度,列
//	uint8 HeightL    = 48; //高度, 行
//	uint8 HeightC    = 0;  //高度, 列
//	uint8 SatStatusL = 64; //卫星定位状况, 行
//	uint8 SatStatusC = 0;  //卫星定位状况, 列
//	uint8 SatDetailL = 120;//卫星编号, 行
//	uint8 SatDetailC = 0;  //卫星编号, 列
//	uint8 i;
//	uint8 dat;


	if(GPS_Status == 'A')//有效定位
	{
		ProcessCoo();//处理数据,把接收到的数据转为坐点
	}
	else if(GPS_Status == 'V')
	{
		nRGB(0, 0, 0);
	}
	else
	{
		nRGB(0, 255, 0);
	}

	ChangeParameter();                      //转换数据格式
	//时间,日期
	LCD_ShowStr( TimeC +  0, TimeL, CurTime.t_mon);  //月
	LCD_ShowChar(TimeC + 16, TimeL, '/');
	LCD_ShowStr( TimeC + 24, TimeL, CurTime.t_day);  //日
	LCD_ShowChar(TimeC + 40, TimeL, '/');
	LCD_ShowStr( TimeC + 48, TimeL, CurTime.t_hour); //时
	LCD_ShowChar(TimeC + 64, TimeL, ':');
	LCD_ShowStr( TimeC + 72, TimeL, CurTime.t_min);  //分	
	LCD_ShowChar(TimeC + 88, TimeL, ':');
	LCD_ShowStr( TimeC + 96, TimeL, CurTime.t_sec);  //秒	

	LCD_ShowStr( TimeC + 112,  TimeL, SatNum); //卫星数

	//经度
	DisLL(LongitudeC, LongitudeL, CurLong);//显示经纬度

	//纬度
	DisLL(LatitudeC, LatitudeL, CurLat);//显示经纬度

//	DisLL(0, 5*16, MapLatUp);//显示经纬度
//	DisLL(0, 6*16, MapLatDown);//显示经纬度
/*	//高度
	LCD_ShowStr( HeightC,  HeightL, ("Height:"));   //显示字符串
	if(GPS_Height[0] == '\0')
	{
		LCD_ShowStr( HeightC + 7*8,  HeightL, "UnKnow"); //卫星数		
	}
	else
	{		
		LCD_ShowStr( HeightC + 7*8,  HeightL, GPS_Height); //
	}		

	//卫星相关信息
	LCD_ShowStr( SatStatusC,  SatStatusL, ("Total:"));   //显示字符串		
	LCD_ShowStr( SatStatusC + 6*8,  SatStatusL, SatNum); //卫星数		

	//卫星定位信息
	if(GPSMode == Loc_1D)
	{
		LCD_ShowStr( SatStatusC + 10*8,  SatStatusL, ("No"));    //无定位
	}
	else if(GPSMode == Loc_2D)
	{
		LCD_ShowStr( SatStatusC + 10*8,  SatStatusL, ("2 Dim ")); //二维定位	
	}
	else if(GPSMode == Loc_3D)
	{
		LCD_ShowStr( SatStatusC + 10*8,  SatStatusL, ("3 Dim ")); //三维定位		
	}
	else
	{
	}

	//显示卫星编号信息
	LCD_ShowStr( SatDetailC,  SatDetailL-16, SatDetail);
	for(i=0; i<12; i++)
	{
		if(SatDetail[2*i] != '\0')
		{
			dat = (SatDetail[2*i]-'0')*10 + (SatDetail[2*i+1]-'0');
		}
		else
		{
			dat = 0;
		}
//		dat=20;
		if(dat<1)
		{
			nRGB(255, 255, 255);
		}
		else if(dat<11)
		{
			nRGB(23*dat, 0, 0);
		}
		else if(dat<22)
		{
			nRGB(0, 23*(dat-11), 0);
		}
		else if(dat<33)
		{
			nRGB(0, 0, 23*(dat-22));
		}
		else
		{
			nRGB(0, 0, 0);
		}
		LCD_ShowChar(SatDetailC + 8*i ,  SatDetailL, 0x81);
	}
*/

}

int main(void)
{
	COM_Initial(MYUBRR);	                    //串口初始化
	Init_LCD_PORT();                            //配置引脚最初状态
//	LCD_6610_WriteCmd(0x11);//写指令
	Init_LCD_Dev();                             //初始化LCD
	MapHeight = 85;
	MapWidth  = 130;
	LCD_6610_ShowGraphic(0, CurY_MAX-MapHeight, MapWidth, MapHeight, graph);//写入位图(xs,ys,x_dot,y_dot,pG)
	Init_Map();//初始化地图,坐标信息
	nRGB(255, 0, 0);
	LCD_6610_DrawLine(0, 0, 100, 3);//画线函数
	LCD_ShowStr(10, 0, ("NOKIA 6610 LCD"));     //显示字符串
	nRGB(0, 255, 0);
	LCD_ShowStr(20, 16, ("Our AVR.com"));       //显示字符串
	nRGB(0, 0, 255);
	LCD_ShowStr(16, 32, ("JUPITER21 GPS"));     //显示字符串
	nRGB(0, 0, 0);
	_delay_ms(3000);
	ClearRAM();
	Mapx = 0;
	Mapy = 0;
//	DisLL(0, 130-48, MapLongLeft);//显示经纬度
//	DisLL(0, 130-64, MapLongRight);//显示经纬度
//	GPS_Write("GPGSV\0", '4');//写GPS(目标语句名,状态参数)
//	LCD_ShowDen(0, 130-32, 1030);//显示十进制数据
//	LCD_ShowDen(48, 130-32, SubLL(MapLongRight, MapLongLeft));//显示十进制数据
	while(1)
	{
		GetGPSDat(); //得到GPS数据
		Display();   //显示
//		LCD_6610_DspMode(LCD_SEP, 0, 68, 64, i);   //显示模式,滚动显示模式	
	}
	while(1);
	(*(void(*)())0)();                          //软件复位!!
	return 0;
}

⌨️ 快捷键说明

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