系統硬件電路主要有GPS、液晶顯示器、STC12C5A60S2、LED狀態指示單片機上電復位和電源等部分組成。GPS發送的串行數據送至單片機串行口經處理后通過鍵盤選擇要顯示的信息,送至LCD液晶顯示器。LCD液晶顯示器會定時更新,更新周期約為1 s。上電復位電路為單片機上電提供上電復位。電源電路為各個電路提供穩定的電源。
電路圖用AD畫的
QQ圖片20171024195317.png (157.66 KB, 下載次數: 97)
下載附件
原理圖截圖
2017-10-24 19:53 上傳
0.png (5.96 KB, 下載次數: 61)
下載附件
2017-10-25 01:56 上傳
QQ圖片20171024195502.png (28.18 KB, 下載次數: 74)
下載附件
程序截圖
2017-10-24 19:55 上傳
STC12C5A60S2單片機源程序如下:
- #include "STC12C5A.H"
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- #include "uart.h"
- #include "timer0.h"
- #include "key.h"
- #include "lcd12864.h"
- #include "GPS.h"
- #include "GPS_PacketQueue.h"
- extern unsigned long Timer0_Count; // 系統時基
- unsigned char Display_Flag = 0; // 顯示界面(0 - 時間經緯度,1 - 速度等)
- unsigned char xdata DateTime[7] = {0}; // 時間和日期緩沖:秒,時,分,日,月,星期,年
- /*-------------GPS相關變量-------- --------------------*/
- GPS_INFO xdata GPS;
- unsigned char GPS_Flag = 0; // GPS數據有效標志
- // 函數聲明
- void LCD_Display_DateTime(unsigned char *pDataTime); // LCD顯示時間,日期
- void LCD_Display_Longitude_Latitude(GPS_INFO *GPS); // LCD顯示經緯度
- void LCD_Display_Speed(GPS_INFO *GPS); // LCD顯示速度,航向等
- /****************************************
- 主函數
- /****************************************/
- void main(void)
- {
- char key_value = 0;
- struct timer Display_Time;
- struct timer Flag_Time;
- struct timer Error_Time;
- GPS_PACKET *Packet = NULL;
- memset(&GPS,0,sizeof(GPS)); // 一定要清0
-
- timer_set(&Display_Time, CLOCK_SECOND/5); // 200ms
- timer_set(&Error_Time, CLOCK_SECOND*2); // 2S
- timer_set(&Flag_Time, CLOCK_SECOND*5); // 3S
- LCD_Init();
- GPS_PacketInit(); // 接收緩沖區初始化
-
- UART_Init(); // 初始化UART
- Timer0_Init(); // 啟動定時器
- while(1)
- {
- /* 處理GPS信號 */
- Packet = NULL;
- Packet = (GPS_PACKET *)GPS_GetPacket();
- if( Packet ){
- timer_restart(&Error_Time); // 接收正確更新時間
- if(Packet->DataType == 1){
- if(GPS_RMC_Parse(Packet->DataBuffer, &GPS)) // 解析GPRMC
- {
- memset(Packet,0,sizeof(GPS_PACKET));
- DateTime[6] = GPS.D.year;
- DateTime[4] = GPS.D.month;
- DateTime[3] = GPS.D.day;
- DateTime[2] = GPS.D.hour;
- DateTime[1] = GPS.D.minute;
- DateTime[0] = GPS.D.second;
- GPS_Flag = 1;
- }
- else{ // 解析錯誤要清空緩沖區
- memset(Packet,0,sizeof(GPS_PACKET));
- }
- }
- else if(Packet->DataType == 2){
- if(GPS_GGA_Parse(Packet->DataBuffer, &GPS)){
- memset(Packet,0,sizeof(GPS_PACKET));
- GPS_Flag = 1;
- }
- else{ // 解析錯誤要清空緩沖區
- memset(Packet,0,sizeof(GPS_PACKET));
- }
- }
- }
- else{
- // 接收錯誤,且時長超過100*20ms = 2S,復位硬件
- if( timer_expired(&Error_Time) )
- {
- UART_Init();
- GPS_PacketInit();
- timer_restart(&Error_Time);
- GPS_Flag = 0;
- }
- }
-
-
- if( timer_expired(&Flag_Time) ) // 切換畫面
- {
- Display_Flag = ++Display_Flag % 2;
- LCD_Clear();
- timer_reset(&Flag_Time);
- }
-
- if( timer_expired(&Display_Time) )
- {
- timer_reset(&Display_Time);
-
- if(GPS_Flag == 0)
- {
- memset(DateTime,0,sizeof(DateTime));
- memset(&GPS,0,sizeof(GPS));
- }
- if(Display_Flag == 0)
- {
- LCD_Display_DateTime(DateTime); // 時間顯示
- LCD_Display_Longitude_Latitude(&GPS);
- }
- else
- {
- LCD_Display_Speed(&GPS);
- }
- }
- }
- }
- /*
- 日期和時間顯示
- */
- void LCD_Display_DateTime(unsigned char *pDataTime)
- {
- unsigned char temp_buffer[9] = {0};
-
- // 顯示年,月,日
- temp_buffer[0] = pDataTime[6]/10+0x30;
- temp_buffer[1] = pDataTime[6]%10+0x30;
- Display_String(1,1,"20");
- Display_String(2,1,temp_buffer);
- Display_String(3,1,"年");
- temp_buffer[0] = pDataTime[4]/10+0x30;
- temp_buffer[1] = pDataTime[4]%10+0x30;
- Display_String(4,1,temp_buffer);
- Display_String(5,1,"月");
- temp_buffer[0] = pDataTime[3]/10+0x30;
- temp_buffer[1] = pDataTime[3]%10+0x30;
- Display_String(6,1,temp_buffer);
- temp_buffer[8] = '\0';
- Display_String(7,1,"日");
-
- // 顯示時,分,秒
- temp_buffer[0] = pDataTime[2]/10+0x30;
- temp_buffer[1] = pDataTime[2]%10+0x30;
- temp_buffer[2] = ':';
- temp_buffer[3] = pDataTime[1]/10+0x30;
- temp_buffer[4] = pDataTime[1]%10+0x30;
- temp_buffer[5] = ':';
- temp_buffer[6] = pDataTime[0]/10+0x30;
- temp_buffer[7] = pDataTime[0]%10+0x30;
- temp_buffer[8] = '\0';
- Display_String(1,2,temp_buffer);
-
- // 顯示星期
- switch(DateTime[5]%10 -1)
- {
- case 0: Display_String(6,2,"星期日\0");break;
- case 1: Display_String(6,2,"星期一\0");break;
- case 2: Display_String(6,2,"星期二\0");break;
- case 3: Display_String(6,2,"星期三\0");break;
- case 4: Display_String(6,2,"星期四\0");break;
- case 5: Display_String(6,2,"星期五\0");break;
- case 6: Display_String(6,2,"星期六\0");break;
- default: break;
- }
- }
- /*
- 顯示緯度和經度
- */
- void LCD_Display_Longitude_Latitude(GPS_INFO *GPS)
- {
- unsigned char ch, i;
- char info[20];
-
- if (GPS->NS == 'N') //判斷是北緯還是南緯
- {
- Display_String(1,3,"北緯");
- }
- else if (GPS->NS == 'S')
- {
- Display_String(1,3,"南緯");
- }
- if (GPS->EW == 'E') //判斷是東經還是西經
- {
- Display_String(1,4,"東經");
- }
- else if (GPS->EW == 'W')
- {
- Display_String(1,4,"西經");
- }
- sprintf(info,":%3d\0",GPS->latitude_Degree);
- LCD_XY(3, 3);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- LCD_Write_Data(0xA1);
- LCD_Write_Data(0xE3);
- Int_To_Str(GPS->latitude_Cent, info);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- LCD_Write_Data(0xA1);
- LCD_Write_Data(0xE4);
- Int_To_Str(GPS->latitude_Second, info);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- sprintf(info,":%3d\0",GPS->longitude_Degree);
- LCD_XY(3, 4);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- LCD_Write_Data(0xA1);
- LCD_Write_Data(0xE3);
- Int_To_Str(GPS->longitude_Cent, info);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- LCD_Write_Data(0xA1);
- LCD_Write_Data(0xE4);
- Int_To_Str(GPS->longitude_Second, info);
- i = 0;
- while(info[i] != '\0')
- {
- ch = info[i++];
- LCD_Write_Data(ch);
- }
- }
- /*
- 把浮點數fla顯示在LCD的坐標(x,y)位置
- */
- void Show_Float(float fla, unsigned char x, unsigned char y)
- {
- int integar;
- char Info[10],ch;
- unsigned char i;
-
- LCD_XY(x, y);
- integar = (int)fla; // 得到浮點數的整數部分
- Int_To_Str(fla, Info);
- i = 0;
- while(Info[i] !='\0')
- {
- ch=Info[i++];
- LCD_Write_Data(ch);
- }
- LCD_Write_Data('.');
- fla = fla - integar; // 得到浮點數的小數部分
-
- fla = fla * 10; // 小數位第一位
- integar = (int)fla;
- fla = fla - integar;
- ch = integar + 0x30;
- LCD_Write_Data(ch);
-
- fla = fla*10; // 小數位第二位
- integar = (int)fla;
- fla = fla - integar;
- ch = integar + 0x30 ;
- LCD_Write_Data(ch);
- }
- /*
- 顯示速度,航向,海拔
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
1. DXP版本原理圖 & PCB.rar
(478.27 KB, 下載次數: 291)
2017-10-24 19:57 上傳
點擊文件名下載附件
原理圖 下載積分: 黑幣 -5
3. 程序.rar
(172.8 KB, 下載次數: 310)
2017-10-24 19:57 上傳
點擊文件名下載附件
程序 下載積分: 黑幣 -5
|