📄 gps_6610.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 + -