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

📄 main.txt

📁 基于c8051f系列的单片机
💻 TXT
字号:
/*************************************
	GPS解码程序
	作者:BG4UVR
最后更新:
2007.03.30
	1.5版
	1、改为使用12864点阵屏显示
***************************************/
//包含头文件
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "ks0108.h"

#define TIME_AREA 8

//GPS数据存储数组
unsigned char JD[10]={"00000.0000"};			//经度
unsigned char JD_a='*';			//经度方向
unsigned char WD[9]={"0000.0000"};			//纬度
unsigned char WD_a='*';			//纬度方向
unsigned char time[6]={"000000"};		//时间
unsigned char date[6]={"000000"};		//日期
unsigned char speed[5];		//速度
unsigned char high[6];		//高度
unsigned char angle[5];		//方位角
unsigned char use_sat[2]={"00"};		//使用的卫星数
unsigned char total_sat[2]={"00"};	//天空中总卫星数

//串口中断需要的变量
unsigned char seg_count;		//逗号计数器
unsigned char dot_count;		//小数点计数器
unsigned char byte_count;		//位数计数器
unsigned char cmd_number;		//命令类型
unsigned char mode;				//0:结束模式,1:命令模式,2:数据模式
volatile unsigned char buf_full;			//1:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5];			//命令类型存储数组

//显示需要的变量
unsigned char dsp_count;		//刷新次数计数器
unsigned char time_count;

volatile unsigned char high_num,a_num,s_num;

void init_set(void);
void sys_init(void);
unsigned char week(unsigned char year, unsigned char mon, unsigned char day);

int main(void)
{
	unsigned char i;
	unsigned char Bhour=0,Bday=0,Bmonth=0;
	unsigned int Byear=0;
	sys_init();

	while(1){
		if(buf_full==0)				//无GPS信号时
		{
			dsp_count++;
			_delay_ms(10);
			if(dsp_count>=200){
				CLEAN_SCREEN();			//清屏
				STR_58_DISP(0,0,PSTR("No GPS CONNECT.."),0);
				while(buf_full==0);
				CLEAN_SCREEN();	
				dsp_count=0;
			}
		}
		else{						//有GPS信号时
			if(buf_full|0x01){				//GGA语句
				ASCII_58_DISP(0,0,JD_a,0);			//显示经度
				for(i=0;i<3;i++){
					ASCII_58_DISP(0,(i+1)*6,JD[i],0);
				}
				ASCII_58_DISP(0,24,'.',0);
				for(i=3;i<10;i++){
					ASCII_58_DISP(0,(i+2)*6,JD[i],0);
				}
				ASCII_58_DISP(1,0,WD_a,0);			//显示纬度
				for(i=0;i<2;i++){
					ASCII_58_DISP(1,(i+2)*6,WD[i],0);
				}			
				ASCII_58_DISP(1,24,'.',0);
				for(i=2;i<9;i++){
					ASCII_58_DISP(1,(i+3)*6,WD[i],0);
				}
				ASCII_58_DISP(2,96,use_sat[0],0);		//显示接收卫星数
				ASCII_58_DISP(2,102,use_sat[1],0);
				ASCII_58_DISP(2,108,'/',0);
				STR_58_DISP(2,0,PSTR("HI:"),0);	
				if(high_num<6)							//高度显示
				{
					for(i=0;i<(6-high_num);i++)
					{
						ASCII_58_DISP(2,(3+i)*6,0x20,0);
					}
				}
				for(i=0;i<high_num;i++)
				{						
					ASCII_58_DISP(2,(9-high_num+i)*6,high[i],0);
				}				
				STR_58_DISP(2,54,PSTR("m  U/T:"),0);
				buf_full&=~0x01;
				dsp_count=0;
			}
			if(buf_full|0x02){				//GSV语句
				ASCII_58_DISP(2,114,total_sat[0],0);
				ASCII_58_DISP(2,120,total_sat[1],0);
				buf_full&=~0x02;
				dsp_count=0;
			}
			if(buf_full|0x04)
			{
				STR_58_DISP(0,78,PSTR("AG:"),0);//方位角显示
				if(a_num<5)
				{
					for(i=0;i<(5-a_num);i++)
					{
						ASCII_58_DISP(0,(16+i)*6,0x20,0);
					}
				}
				for(i=0;i<a_num;i++)
				{						
					ASCII_58_DISP(0,(21-a_num+i)*6,angle[i],0);
				}	
				STR_58_DISP(1,78,PSTR("SP:"),0);	//速度显示
				if(s_num<5)	
				{
					for(i=0;i<(5-s_num);i++)
					{
						ASCII_58_DISP(1,(16+i)*6,0x20,0);
					}
				}
				for(i=0;i<s_num;i++)
				{						
					ASCII_58_DISP(1,(21-s_num+i)*6,speed[i],0);
				}	
				buf_full&=~0x04;
				dsp_count=0;
			}
			if(buf_full|0x08){
				if(Bhour!=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA){
					Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;			//北京时间转换
					Bday=(date[0]-0x30)*10+date[1]-0x30;
					Bmonth=(date[2]-0x30)*10+date[3]-0x30;
					Byear=(date[4]-0x30)*10+date[5]-0x30+2000;
					if(Bhour>=24){					//如果小时数大于24
						Bhour-=24;						//小时数减24
						Bday++;							//日期数加1
						switch(Bday){						//判断日期
							case 29:							//普通年的2月份
								if((!((Byear%400==0)||((Byear%4==0)&&(Byear%100!=0)))&&(Bmonth==2))){
									Bday=1;
									Bmonth++;
								}
								break;
							case 30:							//如果是闰年的2月
								if(((Byear%400==0)||((Byear%4==0)&&(Byear%100!=0)))&&(Bmonth==2)){
									Bday=1;
									Bmonth++;
								}
								break;
							case 31:
								if((Bmonth==4)||(Bmonth==6)||(Bmonth==9)||(Bmonth==11)){
									Bday=1;
									Bmonth++;
								}
								break;
							case 32:
								Bday=1;
								Bmonth++;
								if(Bmonth>=13){
									Byear++;
									Bmonth=1;
								}
								break;
						}
					}
				}
				ASCII_58_DISP(3,0,'2',0);
				ASCII_58_DISP(3,6,'0',0);
				ASCII_58_DISP(3,12,(Byear%100)/10+0x30,0);
				ASCII_58_DISP(3,18,Byear%10+0x30,0);
				ASCII_58_DISP(3,24,'/',0);
				ASCII_58_DISP(3,30,Bmonth/10+0x30,0);
				ASCII_58_DISP(3,36,Bmonth%10+0x30,0);
				ASCII_58_DISP(3,42,'/',0);
				ASCII_58_DISP(3,48,Bday/10+0x30,0);
				ASCII_58_DISP(3,54,Bday%10+0x30,0);
				
				switch(week(Byear%100,Bmonth,Bday)){
					case 0:
						STR_58_DISP(3,120,PSTR("7"),0);
						break;
					case 1:
						STR_58_DISP(3,120,PSTR("1"),0);
						break;
					case 2:
						STR_58_DISP(3,120,PSTR("2"),0);
						break;						
					case 3:
						STR_58_DISP(3,120,PSTR("3"),0);
						break;						
					case 4:
						STR_58_DISP(3,120,PSTR("4"),0);
						break;						
					case 5:
						STR_58_DISP(3,120,PSTR("5"),0);
						break;						
					case 6:
						STR_58_DISP(3,120,PSTR("6"),0);
						break;						
				}
				if(Bhour/10!=0)
				{
					ASCII_58_DISP(3,66,Bhour/10+0x30,0);
					NUM1632_DISP(4,0,Bhour/10,0);
				}
				else
				{
					ASCII_58_DISP(3,66,0x20,0);
					NUM1632_DISP(4,0,11,0);
				}
				ASCII_58_DISP(3,72,Bhour%10+0x30,0);
				ASCII_58_DISP(3,78,':',0);
				ASCII_58_DISP(3,84,time[2],0);
				ASCII_58_DISP(3,90,time[3],0);
				ASCII_58_DISP(3,96,':',0);
				ASCII_58_DISP(3,102,time[4],0);
				ASCII_58_DISP(3,108,time[5],0);
				
				NUM1632_DISP(4,1,Bhour%10,0);
				NUM1632_DISP(4,2,10,0);
				NUM1632_DISP(4,3,time[2]-0x30,0);
				NUM1632_DISP(4,4,time[3]-0x30,0);
				NUM1632_DISP(4,5,10,0);
				NUM1632_DISP(4,6,time[4]-0x30,0);
				NUM1632_DISP(4,7,time[5]-0x30,0);
				
				buf_full&=~0x08;
				dsp_count=0;
			}
		}
	}
}


//计算星期 
unsigned char week(unsigned char year, unsigned char mon, unsigned char day) 
{ 
    const prog_uchar Weekdays[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; 
                                         // 31 28 31 30 31 30 31 31 30 31 30 
    return (6-1 + (year>>2) + year + Weekdays[mon-1] + day + (((year & 3) || mon > 2)? 1 : 0)) % 7; 
    //完整的计算星期的公式: 
    //(year>>2) - (year / 100) + (year/400) + year + 
    //    Weekdays[mon-1] + day + ((!isLeap(year) || mon > 2)? 1 : 0)) % 7; 
}

//USART 初始化
void init_USART(void)	
{
    UCSRC = (1<<URSEL) | 0x06;    			//异步,8位数据,无奇偶校验,一个停止位,无倍速
    UBRRL= (F_CPU/9600/16-1)%256;    		//UBRR= (F_CPU/(BAUDRATE*16))-1;
    UBRRH= (F_CPU/9600/16-1)/256;
    UCSRA = 0x00;    						//使能接收中断,使能接收,使能发送
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
	sei();									//总中断允许	
}

//系统初始化
void sys_init() 
{
	LCD_RESET();				//初始化LCD
	CLEAN_SCREEN();
	init_USART();			//初始化串口
}


//串口接收中断
SIGNAL(SIG_UART_RECV) //串口接收中断服务程序
{
	unsigned char tmp;
	tmp=UDR;
	switch(tmp){
		case '$':
			cmd_number=0;		//命令类型清空
			mode=1;				//接收命令模式
			byte_count=0;		//接收位数清空
			break;
		case ',':
			seg_count++;		//逗号计数加1
			byte_count=0;
			break;
		case '*':
			switch(cmd_number){
				case 1:
					buf_full|=0x01;
					break;
				case 2:
					buf_full|=0x02;
					break;
				case 3:
					buf_full|=0x04;
					break;
				case 4:
					buf_full|=0x08;
					break;
			}
			mode=0;
			break;
		default:
			if(mode==1){
				//命令种类判断
				cmd[byte_count]=tmp;			//接收字符放入类型缓存
				if(byte_count>=4){				//如果类型数据接收完毕,判断类型
					if(cmd[0]=='G'){
						if(cmd[1]=='P'){
							if(cmd[2]=='G'){
								if(cmd[3]=='G'){
									if(cmd[4]=='A'){
										cmd_number=1;
										mode=2;
										seg_count=0;
										byte_count=0;
										high_num=0;
									}
								}
								else if(cmd[3]=='S'){
									if(cmd[4]=='V'){
										cmd_number=2;
										mode=2;
										seg_count=0;
										byte_count=0;
									}
								}
							}
							else if(cmd[2]=='R'){
								if(cmd[3]=='M'){
									if(cmd[4]=='C'){
										cmd_number=3;
										mode=2;
										seg_count=0;
										byte_count=0;
										a_num=0;
										s_num=0;
									}
								}
							}
							else if(cmd[2]=='Z'){
								if(cmd[3]=='D'){
									if(cmd[4]=='A'){
										cmd_number=4;
										mode=2;
										seg_count=0;
										byte_count=0;
									}
								}
							}
						}
					}
				}
			}
			else if(mode==2){
				//接收数据处理
				switch (cmd_number){
					case 1:				//类型1数据接收。GPGGA
						switch(seg_count){
							case 2:								//纬度处理
								if(byte_count<9){
									WD[byte_count]=tmp;
								}
								break;
							case 3:								//纬度方向处理
								if(byte_count<1){
									WD_a=tmp;
								}
								break;
							case 4:								//经度处理
								if(byte_count<10){
									JD[byte_count]=tmp;
								}
								break;
							case 5:								//经度方向处理
								if(byte_count<1){
									JD_a=tmp;
								}
								break;
							case 7:								//定位使用的卫星数
								if(byte_count<2){
									use_sat[byte_count]=tmp;
								}
								break;
							case 9:								//高度处理
								if(byte_count<6){
									high[byte_count]=tmp;
									high_num++;
								}
								break;
						}
						break;
					case 2:				//类型2数据接收。GPGSV
						switch(seg_count){
							case 3:								//天空中的卫星总数
								if(byte_count<2){
									total_sat[byte_count]=tmp;
								}
								break;
						}
						break;
					case 3:				//类型3数据接收。GPRMC
						switch(seg_count){
							case 7:								//速度处理
								if(byte_count<5){
									speed[byte_count]=tmp;
									s_num++;
								}
								break;
							case 8:								//方位角处理
								if(byte_count<5){
									angle[byte_count]=tmp;
									a_num++;
								}
								break;
						}
						break;
					case 4:				//类型4数据接收。GPZDA
						switch(seg_count){
							case 1:
								if(byte_count<6){				//时间处理
									time[byte_count]=tmp;	
								}
								break;
							case 2:
								if(byte_count<2){
									date[byte_count]=tmp;
								}
								break;
							case 3:
								if(byte_count<2){
									date[byte_count+2]=tmp;
								}
								break;
							case 4:
								if((byte_count<4)&&(byte_count>1)){
									date[byte_count+2]=tmp;
								}
								break;							
						}
						break;
				}
			}
			byte_count++;		//接收数位加1
			break;
	}
}

/*
$GPGGA,024518.00,3153.7225,N,12111.9951,E,1,04,1.48,-00009,M,007,M,,*4C
$GPGLL,3153.7225,N,12111.9951,E,024518.00,A,A*63
$GPVTG,000.0,T,004.7,M,000.0,N,000.0,K,A*20
$GPGSA,A,2,04,08,17,20,,,,,,,,,1.48,1.48,0.03*08
$GPGSV,2,1,08,04,15,231,38,08,29,218,42,11,49,043,,19,09,082,*76
$GPGSV,2,2,08,27,14,198,29,28,71,316,,17,32,300,36,20,45,124,43*70
$GPRMC,024518.00,A,3153.7225,N,12111.9951,E,000.0,000.0,280107,04.7,W,A*12
$GPZDA,024519.45,28,01,2007,,*62
*/

/*
012345678901234567890

E121.22.2231 AG:112.1
N 23.23.2341 SP:234.1
HI:12345.5m U/T:03/12
2007/12/13 23:23:53 7

*/

⌨️ 快捷键说明

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