久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
51單片機GPS經緯度信息發送與顯示的實物制作與源程序
[打印本頁]
作者:
君子慎獨
時間:
2017-11-1 21:49
標題:
51單片機GPS經緯度信息發送與顯示的實物制作與源程序
利用GPS北斗ATGM336H-5N模塊輸出的原始定位信息,發到單片機后進行處理,提取有用的信息如經緯度、速度、海拔、日期等,通過串口發到電腦的串口調試助手進行顯示,并顯示到LCD屏幕。
12.jpg
(274.91 KB, 下載次數: 1077)
下載附件
2017-11-2 01:10 上傳
程序的功能有GPS信息顯示與發送(LCD顯示經緯度、海拔、速度,電腦串口接收時間、日期、經緯度、海拔、速度數據)
GPS原始數據捕獲(從一開始通電時不完整到過一會后完整)見附件
GPS原始數據捕獲與簡單分析:
$GNGGA,120726.000,3208.0858,N,11841.7828,E,1,05,4.3,12.7,M,0.0,M,,*40
$GNGLL,3208.0858,N,11841.7828,E,120726.000,A,A*43
$GPGSA,A,3,12,25,,,,,,,,,,,6.9,4.3,5.4*3F
$BDGSA,A,3,10,04,07,,,,,,,,,,6.9,4.3,5.4*28
$GPGSV,3,1,12,04,,,21,10,66,313,,12,42,100,34,14,21,289,*49
$GPGSV,3,2,12,15,18,086,,18,79,174,27,20,13,143,24,21,18,203,*73
$GPGSV,3,3,12,24,40,042,,25,37,150,31,31,10,230,,32,33,301,*7A
$BDGSV,1,1,04,03,,,35,04,32,122,34,07,54,184,34,10,33,200,36*50
$GNRMC,120726.000,A,3208.0858,N,11841.7828,E,0.11,303.11,031017,,,A*70
$GNVTG,303.11,T,,M,0.11,N,0.20,K,A*21
$GNZDA,120726.000,03,10,2017,00,00*4E
$GPTXT,01,01,01,ANTENNA OK*35
原始數據中逗號數量和順序的統計:
--------------------------
1 2 3 4 5 6 7 8 9 a b c d
$GNGGA,034214.000,3208.1201,N,11841.7167,E,1,07,1.7,7.7,M,0.0,M,,*7 OK*
1 2 3 4 5 6 7 8 9 abc
$GNRMC,034214.000,A,3208.1201,N,11841.7167,E,2.71,336.76,041017,,,A*700
--------------------------
GPS原始數據及處理后的數據
(見附件)
單片機源程序如下:
/*******************************************************************************
單片機的RXD端口接收來自GPS模塊的數據,把數據進行處理,并顯示到Lcd上,同時
通過TXD端口經過USB-TTL模塊發送到電腦的串口調試軟件上顯示。
注意事項:
1、串口調試軟件的波特率要設為9600;
2、單片機與USB-TTL模塊兩者要共地!!!(我也不知為什么,攤手.jpg)
*******************************************************************************/
#include "reg52.h"
#include "main.h"
#include "LCD1602.h"
#include "GPS.h"
unsigned char xdata Display_GPGGA_Buffer[68]={0}; //用于儲存GPGGA的數據
unsigned char xdata Display_GPRMC_Buffer[68]={0}; //用于儲存GPRMC的數據
unsigned int k=0,qian_a=0,hou_a=0,qian_b=0,hou_b=0,qian_c=0,hou_c=0; //存儲前后逗號的位置序號的變量
bit qian_OK=0; //已找出前面的逗號的標志變量
bit First_Share_OK=0; //已開始LCD顯示的標志變量
bit jiajian=1; //進行加或減的標志變量
//bit Page = 0;
bit Flag_OV = 0; //日期需進位的標志變量
bit Flag_Calc_GPGGA_OK = 0; //GPGGA完整有效的數據已收到的標志變量
bit Flag_Calc_GPRMC_OK = 0; //GPRMC完整有效的數據已收到的標志變量
//****************************************************
//主函數
//****************************************************
void main()
{
unsigned int i = 0;
unsigned int j=0;
Init_LCD1602(); //LCD初始化
LCD1602_write_com(0x80); //LCD指針設置到第一行第一列
LCD1602_write_word("Searching data. "); //顯示正在搜索數據
Uart_Init(); //串口初始化
while(1)
{
// Scan_Key();
qian_OK=0; //標志變量歸零
k=0; //累計量歸零
if (First_Share_OK==0) //讓變量j在0~10000之間來回增減,增加到10000時顯示". ",減到0時顯示" .",實現兩點來回閃動
{
if (jiajian==1)
{
j++;
if (j==10000)
{
jiajian=0;
LCD1602_write_com(0x8e);
LCD1602_write_data('.');
LCD1602_write_com(0x8f);
LCD1602_write_data(' ');
}
}
else
{
j--;
if (j==0)
{
jiajian=1;
LCD1602_write_com(0x8e);
LCD1602_write_data(' ');
LCD1602_write_com(0x8f);
LCD1602_write_data('.');
}
}
}
//代碼詳見附件
// {
// UartPrintf("----------------------------------------------\r\n");
// UartPrintf(RX_Buffer);
// UartPrintf("\r\n");
// }
if ( Flag_GPS_OK == 1
&& RX_Buffer[1] == 'G'
&& RX_Buffer[3] == 'G'
&& RX_Buffer[4] == 'G'
&& RX_Buffer[5] == 'A'
&& (RX_Buffer[28] == 'N'|| RX_Buffer[28] == 'S')
&& (RX_Buffer[41] == 'E'|| RX_Buffer[41] == 'W') ) //確認是否收到"GPGGA"這一幀完整有效的數據
{
for( i = 0; i < 67 ; i++) //必須為i<67,因為要確保Display_GPGGA_Buffer[67]為'\0',便于串口發送
{
Display_GPGGA_Buffer[i] = RX_Buffer[i]; //儲存到數組中
}
Flag_Calc_GPGGA_OK = 1; //收到完整有效數據后,置為1
}
if(Flag_Calc_GPGGA_OK == 1) //已收到完整有效的數據,可以進行顯示,
{
Flag_Calc_GPGGA_OK = 0; //標志位歸零
if (First_Share_OK == 0)
{
First_Share_OK=1; //"Searching data. "不需再顯示,標志變量置為1
LCD1602_write_com(0x01); //先清屏
}
LCD1602_write_com(0x80);
LCD1602_write_data(Display_GPGGA_Buffer[28]); //顯示 N 或者 S
LCD1602_write_word(": ");
LCD1602_write_data(Display_GPGGA_Buffer[18]); //緯度
LCD1602_write_data(Display_GPGGA_Buffer[19]);
LCD1602_write_data(0xdf); //度符號的ASCII碼,16進制
LCD1602_write_data(Display_GPGGA_Buffer[20]); //緯度
LCD1602_write_data(Display_GPGGA_Buffer[21]);
LCD1602_write_word("'"); //秒
for (i=0;i<68;i++) //由于海拔有時是1位數有時是2位數有時是3位數,不定
{ //而確定的是其數值在第9與第10個逗號之間,所以用此算法輸出海拔
if ( Display_GPGGA_Buffer[i]==',' ) //逐個檢索
k++; //k計算逗號數量
if (k==9&&qian_OK==0)
qian_a=i,qian_OK=1; //找到第9個,則記錄其序號,同時標志變量置為1
if (k==10) //海拔數據位于第9~10個逗號之間
{
hou_a=i; //記錄第10個的序號
k=0; //歸零
qian_OK=0; //重置為0
break; //找到后直接跳出循環
}
}
LCD1602_write_com(0x89); //準備在第一行第9列輸出海拔數據
switch(hou_a-qian_a-1) //計算海拔數據的長度
{
case 3:LCD1602_write_word(" ");break; //根據海拔數據長度輸出對應所需的空格數,使其顯示方式為右對齊
case 4:LCD1602_write_word(" ");break;
case 5:LCD1602_write_word(" ");break;
case 6:break;
case 7:break;
}
for (i=qian_a+1; i<=hou_a-1; i++)
LCD1602_write_data(Display_GPGGA_Buffer[i]); //輸出海拔
LCD1602_write_data('m'); //顯示單位
LCD1602_write_com(0xc0); //在第2行第1列開始輸出經度
LCD1602_write_data(Display_GPGGA_Buffer[41]); //輸出E 或者 W
LCD1602_write_data(':');
LCD1602_write_data(Display_GPGGA_Buffer[30]); //經度
LCD1602_write_data(Display_GPGGA_Buffer[31]);
LCD1602_write_data(Display_GPGGA_Buffer[32]);
LCD1602_write_data(0xdf);
LCD1602_write_data(Display_GPGGA_Buffer[33]);
LCD1602_write_data(Display_GPGGA_Buffer[34]);
LCD1602_write_word("'");
UartPrintf("----------------------------------------------\r\n"); //串口發送數據到電腦
UartPrintf("Original data(1):\r\n");
UartPrintf(Display_GPGGA_Buffer); //直接把首地址作為實參
UartPrintf("......\r\n");
UartPrintf("Processed data(1): \r\n");
UartPrintData(Display_GPGGA_Buffer[28]); //N 或者 S
UartPrintf(": ");
UartPrintData(Display_GPGGA_Buffer[18]); //發送緯度
UartPrintData(Display_GPGGA_Buffer[19]);
UartPrintData('*'); //串口無法發送擴展的ASCII碼(大于127),所以用*代替度數符號
UartPrintData(Display_GPGGA_Buffer[20]);
UartPrintData(Display_GPGGA_Buffer[21]);
UartPrintData('\'');
UartPrintf("\r\n"); //發送回車換行
UartPrintData(Display_GPGGA_Buffer[41]); //E 或者 W
UartPrintf(": ");
UartPrintData(Display_GPGGA_Buffer[30]);
UartPrintData(Display_GPGGA_Buffer[31]);
UartPrintData(Display_GPGGA_Buffer[32]);
UartPrintData('*');
UartPrintData(Display_GPGGA_Buffer[33]); //發送經度
UartPrintData(Display_GPGGA_Buffer[34]);
UartPrintData('\'');
UartPrintf("\r\n");
UartPrintf("Altitude: ");
for (i=qian_a+1; i<=hou_a-1; i++) //發送海拔
UartPrintData(Display_GPGGA_Buffer[i]);
UartPrintf(" m");
UartPrintf("\r\n");
}
// 這部分代碼詳見附件
&& RX_Buffer[1] == 'G'&& RX_Buffer[3] == 'R'&& RX_Buffer[4] == 'M'&& RX_Buffer[5] == 'C')
// {
// UartPrintf(RX_Buffer);
// UartPrintf("\r\n");
// }
if( Flag_GPS_OK == 1
&& RX_Buffer[1] == 'G'
&& RX_Buffer[3] == 'R'
&& RX_Buffer[4] == 'M'
&& RX_Buffer[5] == 'C'
&& RX_Buffer[18]== 'A') //確認是否收到"GPRMC"這一幀完整有效的數據
{
for( i = 0; i < 67 ; i++)
{
Display_GPRMC_Buffer[i] = RX_Buffer[i];
}
Flag_Calc_GPRMC_OK = 1;
Hour = (Display_GPRMC_Buffer[7]-0x30)*10+(Display_GPRMC_Buffer[8]-0x30)+8; //UTC時間轉換到北京時間(東八區),0x30即48
if( Hour >= 24) //如果溢出
{
Hour %= 24; //獲取實際Hour
Flag_OV = 1; //日期進位的標志變量置為1
}
else
{
Flag_OV = 0;
}
Min_High = Display_GPRMC_Buffer[9];
Min_Low = Display_GPRMC_Buffer[10]; //獲取時間數據
Sec_High = Display_GPRMC_Buffer[11];
Sec_Low = Display_GPRMC_Buffer[12];
for (i=0;i<68;i++) //由于日期數據前面的速度數據也是位數不定,所以速度數據位數也不定,故亦用此算法精確地確定日期數據位置
{
if ( Display_GPRMC_Buffer[i]==',' )
k++;
if (k==9&&qian_OK==0) //日期數據位于第9~10個逗號之間
qian_b=i,qian_OK=1;
if (k==10)
{
hou_b=i;
k=0;
qian_OK=0;
break;
}
}
Year_High = Display_GPRMC_Buffer[qian_b+5]; //獲取日期
Year_Low = Display_GPRMC_Buffer[qian_b+6];
Month_High = Display_GPRMC_Buffer[qian_b+3];
Month_Low = Display_GPRMC_Buffer[qian_b+4];
Day_High = Display_GPRMC_Buffer[qian_b+1];
Day_Low = Display_GPRMC_Buffer[qian_b+2];
if(Flag_OV == 1) //如果日期須進位
{
UTCDate2LocalDate(); //UTC日期進位并轉換為北京時間
}
}
if(Flag_Calc_GPRMC_OK == 1) //GPRMC數據完整有效則顯示
{
Flag_Calc_GPRMC_OK = 0;
if (First_Share_OK == 0)
{
First_Share_OK=1;
LCD1602_write_com(0x01);
}
for (i=0;i<68;i++) //由于速度數據也是位數不定,故亦用此算法精確地確定速度數據位置
{
if ( Display_GPRMC_Buffer[i]==',' )
k++;
if (k==7&&qian_OK==0) //速度數據位于第7~8個逗號之間
qian_c=i,qian_OK=1;
if (k==8)
{
hou_c=i;
k=0;
qian_OK=0;
break;
}
}
LCD1602_write_com(0xc9); //準備在第2行第9列顯示
switch(hou_c-qian_c-2) //原式為(hou_c-1)-qian_c-1。由于速度不太準還浮動,故只讓它顯示一位小數
{
case 3:LCD1602_write_word(" ");break; //使右對齊
case 4:break;
case 5:break;
}
for (i=qian_c+1; i<=hou_c-2; i++) //(原式為hou_c-1-1)
LCD1602_write_data(Display_GPRMC_Buffer[i]); //顯示速度
LCD1602_write_word("m/s"); //顯示單位
UartPrintf("\r\n");
UartPrintf("Original data(2):\r\n");
UartPrintf(Display_GPRMC_Buffer);
UartPrintf("......\r\n");
UartPrintf("Processed data(2): \r\n");
UartPrintf("Time: ");
UartPrintData(Hour/10+0x30); //串口發送時間
UartPrintData(Hour%10+0x30);
UartPrintData(':');
UartPrintData(Min_High);
UartPrintData(Min_Low);
UartPrintData(':');
UartPrintData(Sec_High);
UartPrintData(Sec_Low);
UartPrintf("\r\n");
UartPrintf("Date: "); //發送日期
UartPrintf("20");
UartPrintData(Display_GPRMC_Buffer[qian_b+5]);
UartPrintData(Display_GPRMC_Buffer[qian_b+6]);
UartPrintData('-');
UartPrintData(Display_GPRMC_Buffer[qian_b+3]);
UartPrintData(Display_GPRMC_Buffer[qian_b+4]);
UartPrintData('-');
UartPrintData(Display_GPRMC_Buffer[qian_b+1]);
UartPrintData(Display_GPRMC_Buffer[qian_b+2]);
UartPrintf("\r\n");
UartPrintf("Speed: ");
for (i=qian_c+1; i<=hou_c-1; i++)
UartPrintData(Display_GPRMC_Buffer[i]);
UartPrintf(" m/s\r\n"); //發送速度,2位小數都發
UartPrintf("----------------------------------------------\r\n");//分隔符
}
}
}
//****************************************************
//UTC日期與當地日期轉換
//****************************************************
void UTCDate2LocalDate(void)
{
Day = (Day_High - 0x30) * 10 + (Day_Low-0x30) + 1; //日期進一
Month = (Month_High - 0x30) * 10 + (Month_Low - 0x30);
Year = 2000 + (Year_High - 0x30) * 10 + (Year_Low - 0x30);
MaxDay = GetMaxDay(Month,Year); //獲取當月天數最大值
if(Day > MaxDay) //如果溢出
{
Day = 1;
Month += 1;
if(Month > 12)
{
Year+=1;
}
}
Day_High = Day/10 + 0x30; //轉換日期值為ASCII
Day_Low = Day%10 + 0x30;
Month_High = Month/10 + 0x30;
Month_Low = Month%10 + 0x30;
Year_High = Year%100/10 + 0x30;
Year_Low = Year%10 + 0x30;
}
//****************************************************
//獲取當月日期最大值
//****************************************************
unsigned char GetMaxDay(unsigned char Month_Value,unsigned int Year_Value)
{
unsigned char iDays;
switch(Month_Value)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
{
iDays = 31;
}
break;
case 2:
{
//2月份比較特殊,需要根據是不是閏年來判斷當月是28天還29天
iDays = IsLeapYear(Year_Value) ? 29 : 28 ;
}
break;
case 4:
case 6:
case 9:
case 11:
{
iDays = 30;
}
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
GPS(LCD,USart).zip
(101.7 KB, 下載次數: 363)
2017-11-1 21:40 上傳
點擊文件名下載附件
GPS信息發到單片機,經過處理,發到串口,并顯示到LCD
下載積分: 黑幣 -5
作者:
xwnc
時間:
2017-11-8 18:34
樓主太強了,學習學習
作者:
marklee
時間:
2018-1-8 09:17
好東西 學習學習
作者:
114892148
時間:
2018-1-17 12:38
太贊了樓主
作者:
jack2694514902
時間:
2018-4-12 20:36
樓主,有急用,能分享下嗎
作者:
aking991
時間:
2018-9-27 17:00
曾經也作了一個,還是匯編版的,本想改成C版的,可是一直沒時間處理
作者:
andyliang
時間:
2018-9-28 11:58
什么時候能跟上樓主
作者:
index.jsp
時間:
2018-11-17 23:20
很棒。學習一下
作者:
1589959571
時間:
2018-11-24 16:09
樓主有沒有仿真
作者:
君子慎獨
時間:
2018-12-27 02:34
1589959571 發表于 2018-11-24 16:09
樓主有沒有仿真
GPS哪能仿真鴨
作者:
阿維拉
時間:
2019-2-22 10:56
怎么能讓其顯示在彩屏上
作者:
tyj123456
時間:
2019-2-27 22:38
樓主太強了,學習學習
作者:
Jeff_BlindCat
時間:
2019-3-25 08:30
謝謝樓主分享,還沒法下載。
作者:
小姜戈
時間:
2019-5-5 14:45
樓主的分享非常有用,可是我按這個程序做出來,串口接收到的還是這種$GNGGA,034214.000,3208.1201,N,11841.7167,E,1,07,1.7,7.7,M,0.0,M,,*7 OK*形式的數據,這是什么原因呢
麻煩樓主指點一下下
作者:
hyz5122
時間:
2019-7-6 12:08
文章不錯,就是要的積分有點高!!!
作者:
hyz5122
時間:
2019-7-6 12:24
看了一下發表的部分,非常不錯,學習了!
作者:
快樂眼淚
時間:
2019-7-7 20:44
這個真不錯!
作者:
aaaaaa。
時間:
2019-10-16 20:58
請問樓主能發一下原理圖嗎
作者:
liuhua1111
時間:
2019-10-29 14:30
這代碼強強強,學習
作者:
153905507
時間:
2019-11-4 15:37
原理圖可以發下嗎
作者:
吾乃長山霸王龍
時間:
2019-12-6 14:44
可以請作者發下原理圖嗎
作者:
吾乃長山霸王龍
時間:
2019-12-6 14:51
樓主求原理圖
作者:
ynzsc001
時間:
2019-12-30 17:42
提示...........\main.m51 contains an incorrect path.
導致文件編譯不了
作者:
scyqwer
時間:
2019-12-31 14:54
gps調試
作者:
123456qwj
時間:
2020-4-14 22:09
為啥我的液晶屏上沒有顯示數據
作者:
zxopenljx
時間:
2020-6-7 15:39
感謝樓主分享
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
亚洲网站在线播放
|
亚洲国产精选
|
精品亚洲一区二区三区四区五区高
|
久久久激情视频
|
中文字幕福利
|
亚洲a网
|
91视频在线观看免费
|
免费观看黄色一级片
|
视频精品一区二区三区
|
av黄色在线
|
国产精品99久久久久久宅男
|
狠狠干网
|
日韩一区和二区
|
久久久精品一区二区
|
国产成人免费一区二区60岁
|
精品一二区
|
一区二区三区免费
|
欧美精品1区
|
国产美女精品
|
久久久黄色
|
亚州激情
|
国产在线激情视频
|
中文字幕在线一区二区三区
|
日韩中文字幕视频在线
|
欧美日韩精品一区二区三区视频
|
婷婷五月色综合香五月
|
天天干b
|
作爱视频免费看
|
91视频在线看
|
91看片在线观看
|
欧美黑人国产人伦爽爽爽
|
欧美亚洲视频
|
中文字幕免费在线
|
日韩无
|
日韩精品一区二区三区
|
99re视频这里只有精品
|
欧洲免费毛片
|
超级乱淫av片免费播放
|
一区二区在线免费播放
|
男女搞网站
|
99久久国产综合精品麻豆
|