以51單片機為主控制器,LCD1602顯示,通過GPS定位模塊收發(fā)信息,在LCD上顯示經緯度。
還加了溫濕度DHT11模塊,可以在經緯度旁邊顯示溫濕度。
實物圖:
IMG_20171221_112137.jpg (2.06 MB, 下載次數: 83)
下載附件
2017-12-21 12:18 上傳
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include <stdio.h>
- #include "delay.h"
- #include "1602.h"
- /**The UART1 stage1**/
- #define STAGE_SOHE 0x01
- #define STAGE_TYPE 0x02
- #define STAGE_NONE 0x03
- #define STAGE_DATA 0x04
- unsigned char Lin0_No[16]="N:000.000000 ";//顯示北緯
- unsigned char Lin1_Ea[16]="E:000.000000 ";//顯示東經
- unsigned long xdata time_20ms=0;
- unsigned char xdata devide_flag; //GPS數據逗號分隔符
- unsigned char xdata speed_end; //收速度數據結束標志
- unsigned char xdata dir_end; //收方向角數據結束標志
- unsigned char xdata sysmode_GPS=0; //gps有效無效標志
- unsigned char xdata ew_flag; //東西標志
- unsigned char xdata ns_flag; //南北標志
- unsigned char xdata gps_infor_weijing[17]; //暫存經緯度 格式是以度分秒的是形式
- unsigned char xdata gps_infor_speed[4]; //暫存速率
- unsigned char xdata gps_infor_time[6]; //時間暫存
- unsigned char xdata gps_infor_date[6]; //日期暫存
- unsigned char xdata gps_infor_dir[3]; //方向暫存
- unsigned char xdata recv1_step=STAGE_SOHE; //串口1接收指令步驟
- unsigned char xdata uart1_r_buf; //串口的緩存
- unsigned char xdata rev1_buf_busy; //串口接收忙碌標志
- unsigned char xdata temp1_buf[85]; //串口接收數組
- unsigned int xdata record1=0;
- unsigned char times = 0; //延時計數
- void Init_Timer0(void);//定時器初始化
- void UART_Init(void);
- void main (void)
- {
- unsigned char num=0;
- unsigned long Mid_Du; //中間變量 暫存經緯度的整數部分 即度
- unsigned long Mid_Fen; //中間變量 暫存經緯度的小數部分 即分 gps原始數據是度分秒格式
- unsigned long Mid_Vale; ////中間變量 暫存經緯度 并將其擴大了10000000倍
- unsigned char i ;
- Init_Timer0(); //定時器0初始化
-
- UART_Init();
-
- LCD_Init(); //初始化液晶
- DelayMs(20); //延時有助于穩(wěn)定
- LCD_Clear(); //清屏
- DelayMs(120);
- while(1) //主循環(huán)
- {
- if(sysmode_GPS==1) //檢測gps是否有效數據
- {
- sysmode_GPS=0; //清除有效位
- times = 0; //防止gps數據未更新就誤判斷數據無效
- Mid_Du=(gps_infor_weijing[0]-0x30)*10000000+(gps_infor_weijing[1]-0x30)*1000000; //處理緯度 暫存整數部分擴大10000000
-
- Mid_Fen=(gps_infor_weijing[2]-0x30)*10000000+(gps_infor_weijing[3]-0x30)*1000000+
- (gps_infor_weijing[4]-0x30)*100000+(gps_infor_weijing[5]-0x30)*10000+
- (gps_infor_weijing[6]-0x30)*1000+(gps_infor_weijing[7]-0x30)*100; //處理緯度 暫存小數部分擴大10000000
- Mid_Fen=Mid_Fen/60; //分秒換算為小數位
- Mid_Vale=Mid_Du+Mid_Fen; //最終緯度 格式為000.00000000 非度分秒格式
- Lin0_No[0]='N';
- Lin0_No[1]=':';
- Lin0_No[2]='0';
- Lin0_No[3]=Mid_Vale/10000000+0x30; //將處理后的緯度填入字符串 并打印顯示
- Lin0_No[4]=(Mid_Vale/1000000)%10+0x30;
- Lin0_No[5]='.';
- Lin0_No[6]=(Mid_Vale/100000)%10+0x30;
- Lin0_No[7]=(Mid_Vale/10000)%10+0x30;
- Lin0_No[8]=(Mid_Vale/1000)%10+0x30;
- Lin0_No[9]=(Mid_Vale/100)%10+0x30;
- Lin0_No[10]=(Mid_Vale/10)%10+0x30;
- Lin0_No[11]=Mid_Vale%10+0x30;
-
- Mid_Du=(gps_infor_weijing[8]-0x30)*100000000+(gps_infor_weijing[9]-0x30)*10000000+(gps_infor_weijing[10]-0x30)*1000000; //處理經度 暫存整數部分擴大10000000
-
- Mid_Fen=(gps_infor_weijing[11]-0x30)*10000000+(gps_infor_weijing[12]-0x30)*1000000+
- (gps_infor_weijing[13]-0x30)*100000+(gps_infor_weijing[14]-0x30)*10000+
- (gps_infor_weijing[15]-0x30)*1000+(gps_infor_weijing[16]-0x30)*100; //處理經度 暫存小數部分擴大10000000
- Mid_Fen=Mid_Fen/60; //分秒換算為小數位
- Mid_Vale=Mid_Du+Mid_Fen; //最終經度 格式為000.00000000 非度分秒格式
- Lin1_Ea[0]='E';
- Lin1_Ea[1]=':';
- Lin1_Ea[2]=Mid_Vale/100000000+0x30; //將處理后的經度填入字符串 并打印顯示
- Lin1_Ea[3]=(Mid_Vale/10000000)%10+0x30;
- Lin1_Ea[4]=(Mid_Vale/1000000)%10+0x30;
- Lin1_Ea[5]='.';
- Lin1_Ea[6]=(Mid_Vale/100000)%10+0x30;
- Lin1_Ea[7]=(Mid_Vale/10000)%10+0x30;
- Lin1_Ea[8]=(Mid_Vale/1000)%10+0x30;
- Lin1_Ea[9]=(Mid_Vale/100)%10+0x30;
- Lin1_Ea[10]=(Mid_Vale/10)%10+0x30;
- Lin1_Ea[11]=Mid_Vale%10+0x30;
-
- }
- else
- {
- times++;
- if(times>4) //防止gps數據未更新就誤判斷數據無效
- {
- times = 0; //清零計數
- Lin1_Ea[0]='G'; //無gps信號情況下 打印正在連接
- Lin1_Ea[1]='P';
- Lin1_Ea[2]='S';
- Lin1_Ea[3]=' '; //將處理后的緯度填入字符串 并打印顯示
- Lin1_Ea[4]='L';
- Lin1_Ea[5]='I';
- Lin1_Ea[6]='N';
- Lin1_Ea[7]='K';
- Lin1_Ea[8]='I';
- Lin1_Ea[9]='N';
- Lin1_Ea[10]='G';
- Lin1_Ea[11]='.';
- for(i=0;i<12;i++) //數組重新填充
- {
- Lin0_No[i]=Lin1_Ea[i];
- }
- }
- }
- LCD_Write_String(0,0,Lin0_No);//顯示第一行
- LCD_Write_String(0,1,Lin1_Ea);//顯示第二行
- }
- }
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
- TH0=(65536-20000)/256; //重新賦值 20ms
- TL0=(65536-20000)%256;
- EA=1; //總中斷打開
- ET0=1; //定時器中斷打開
- TR0=1; //定時器開關打開
- }
- void Timer0_isr(void) interrupt 1
- {
- TH0=(65536-20000)/256; //重新賦值 20ms
- TL0=(65536-20000)%256;
- time_20ms++;
- }
- void UART_Init(void)
- {
- SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
- TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重裝
- TH1 = 0xFD; // TH1: 重裝值 9600 波特率 晶振 11.0592MHz
- TR1 = 1; // TR1: timer 1 打開
- EA = 1; //打開總中斷
- ES = 1; //打開串口中斷
- }
- void UART_SER (void) interrupt 4 //串行中斷服務程序
- {
- if(RI) //判斷是接收中斷產生
- {
- RI=0; //標志位清零
- uart1_r_buf=SBUF; //提取buf中的值
- rev1_buf_busy=0x00; //判別 放置break問題
- switch(recv1_step)
- {
- case STAGE_SOHE: if(uart1_r_buf == '') //判斷接收到了 具體原因參考GPS標準協議NMEA0183
- {
- rev1_buf_busy=0x01;
- if(uart1_r_buf == '') //再次查看接收的是否是
- {
- recv1_step=STAGE_TYPE; //跳轉到下一步
- record1=0; //計數清零
- }
- else
- {
- recv1_step=STAGE_SOHE; //恢復初始化
- record1=0;
- }
- }
- break;
- case STAGE_TYPE: if(rev1_buf_busy == 0x00)
- {
- rev1_buf_busy=0x01;
- temp1_buf[record1]=uart1_r_buf;
- record1++;
- if(record1 == 0x05)
- { //查看$GPRMC開頭的命令行
- if((temp1_buf[0] == 'G') && (temp1_buf[1] == 'P') && (temp1_buf[2] == 'R') && (temp1_buf[3] == 'M') && (temp1_buf[4] == 'C'))
- {
- recv1_step=STAGE_NONE; //跳轉到下一步
- record1=0;
- }
- else
- {
- recv1_step=STAGE_SOHE;//恢復初始化
- record1=0;
- }
- }
- }
- break;
- case STAGE_NONE: if(rev1_buf_busy == 0x00)//接收命令格式:$GPRMC,054347.00,A,3202.04770,N,11846.23632,E,0.000,0.00,221013,,,A*67
- {
- rev1_buf_busy=0x01;
- record1++;
- if((record1 > 0x01) && (record1 < 0x08))
- {
- gps_infor_time[record1-2]=uart1_r_buf; //時間存儲
- }
- if((uart1_r_buf == ',') && (record1 > 0x07) && (record1 < 0x010)) //||((uart1_r_buf == ',') && (record1==0x02))
- {
- record1=0xcc;
- }
- if(record1 == 0xcd)
- {
- record1=0;
- devide_flag=2;
- speed_end=0x00;
- dir_end=0x00;
- if(uart1_r_buf == 'A') //gps收到數據 且有效
- {
- recv1_step=STAGE_DATA; //跳轉到下一步
- }
- else
- {
- sysmode_GPS=0;
- recv1_step=STAGE_SOHE; //無效恢復初始化
- record1=0;
- }
- }
- }
- break;
- case STAGE_DATA: if(rev1_buf_busy == 0x00)
- {
- rev1_buf_busy=0x01;
- record1++;
- if(uart1_r_buf == ',') //判斷逗號
- {
- devide_flag++; //逗號次數記錄
- record1=0;
- }
- if(devide_flag == 3)
- {
- if((record1 > 0) && (record1 < 5))
- {
- gps_infor_weijing[record1-1]=uart1_r_buf; //存儲經緯度 此處為緯度
- }
- if((record1 > 5) && (record1 < 10)) //跳過小數點的存儲
- {
- gps_infor_weijing[record1-2]=uart1_r_buf; //存儲經緯度 此處為緯度
- }
- }
- if(devide_flag == 4)
- {
- if(record1 > 0)
- {
- ns_flag=uart1_r_buf; //接收緯度NS標志
- }
- }
- if(devide_flag == 5)
- {
- if((record1 > 0) && (record1 < 6))
- {
- gps_infor_weijing[record1+7]=uart1_r_buf; //存儲經緯度 此處為緯度
- }
- if((record1 > 6) && (record1 < 11)) //跳過小數點的存儲
- {
- gps_infor_weijing[record1+6]=uart1_r_buf; //存儲經緯度 此處為經度
- }
- }
- if(devide_flag == 6)
- {
- if(record1 > 0)
- {
- ew_flag=uart1_r_buf; //經度度 EW標志
- }
- }
- if(devide_flag == 7)
- {
- if(speed_end == 0x00)
- {
- if((record1 > 0) && (uart1_r_buf != '.'))
- {
- gps_infor_speed[record1-1]=uart1_r_buf; //接收速率
- }
- else if(uart1_r_buf == '.')
- {
- record1--;
- speed_end=0xff;
- }
- }
- else if(speed_end == 0xff)
- {
- speed_end=0xfe;
- gps_infor_speed[record1-1]=uart1_r_buf;
- gps_infor_speed[3]=gps_infor_speed[record1-1];
- gps_infor_speed[2]=gps_infor_speed[record1-2];
- if(record1 > 2)
- {
- gps_infor_speed[1]=gps_infor_speed[record1-3];
- }
- else
- {
- gps_infor_speed[1]=0x30;
- }
- if(record1 > 3)
- {
- gps_infor_speed[0]=gps_infor_speed[record1-4];
- }
- else
- {
- gps_infor_speed[0]=0x30;
- }
- }
- }
- if(devide_flag == 8)
- {
- if(dir_end == 0x00)
- {
- if((record1 > 0) && (uart1_r_buf != '.'))
- {
- gps_infor_dir[record1-1]=uart1_r_buf; //存儲方向
- }
- else if(uart1_r_buf == '.')
- {
- record1--;
- dir_end=0xff;
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (10.87 KB, 下載次數: 84)
下載附件
2017-12-21 16:21 上傳
所有資料51hei提供下載:
程序.rar
(71.15 KB, 下載次數: 122)
2017-12-21 12:14 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|