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

📄 gps.c

📁 单片机上开发的微妙级GPS时钟
💻 C
字号:
//
//
//		get the data from gps and output the time nGpsSentenceIndex and bcd nGpsSentenceIndex
//

#include "gps.h"

uchar nBcdPos = 0;
uchar nBcdField = 0;
uchar nBcdCounter = 0;

uchar nHeadSign = 0;
uchar nHeadLength = 0;
uchar nFieldLength = 0;
uchar nGpsSentenceIndex = 0;
uchar nReadLength = 0;

//当前状态
uint nIntervalSecond = 0;				// 卫星丢失时间间隔
uint nUSCounter = 0;					// 时间间隔内钟差
uchar nGpsStatus = GPS_LOST; 

// 输出信号计数长度
uint nSignCounteNum = 0;

// 输出信号标志位
char bdata nSignStatus = 0;
sbit nSecondSign = nSignStatus^0;		// 下一个秒到时是否是整秒
sbit nMinuteSign = nSignStatus^1;		// 下一个秒到时是否是整分
sbit nHourSign = nSignStatus^2;			// 下一个秒到时是否是整时
sbit nCheckKey = nSignStatus^3;			// 检查键输入标志位

uchar nInputKey = 0;

bit nIsSend = 0;
uchar nSendPos = 0;

void serial() interrupt 4 using 2
{
	if(RI)
	{
		uchar nChar = SBUF;
		if(nChar == '$')
		{
			nHeadLength = 0;
			nFieldLength = 0;
			nHeadSign = 1;
			nGpsSentenceIndex = 0;
		}
		else if(nHeadSign)
		{
			Buff[nHeadLength++] = nChar;
			if(nHeadLength == HEAD_LENGTH-1)
			{
				uchar i;
				nGpsSentenceIndex = 1;
				for(i = 1;i<HEAD_LENGTH;i++)
				{
					if(Buff[i-1] != GPGGA_HEAD[i])
					{
						nGpsSentenceIndex = 0;
						break;
					}
				}
				
				if(!nGpsSentenceIndex)
				{
					nGpsSentenceIndex = 2;
					for(i = 1;i<HEAD_LENGTH;i++)
					{
						if(Buff[i-1] != GPRMC_HEAD[i])
						{
							nGpsSentenceIndex = 0;
							break;
						}
					}
				}
				nHeadSign = 0;
			}
		}
		else if(nGpsSentenceIndex == 1)
		{
			if(nChar == ',')
			{
				nFieldLength++;
				switch( nFieldLength )
				{
				case 7:
					nReadLength = 0;
					break;
				case 9: 
					SateliteNum = (Buff[0]-'0')*10+Buff[1]-'0';
					if(SateliteNum>= 3 && nGpsStatus != GPS_NORMAL)
					{
						EA = 0;
						ET2 = 0;
						EX0 = 1;
						nGpsStatus = GPS_NORMAL;
						EA = 1;
					}
					else if(SateliteNum < 3 && nGpsStatus == GPS_NORMAL)
					{
						EA = 0;
						EX0 = 0;
						ET2 = 1;
						EXEN2 = 1;
						nGpsStatus = GPS_NORMALLOST;
						EA = 1;
					}
					nReadLength = 0;
					{
						nIsSend = 1;
						nSendPos = 0;
					}
					break;
				case 10:
					{
					uchar i;
					for(i = 0;i<nReadLength;i++)
						SeaHeight[i] = Buff[i];
					SeaHeight[i] = 0;
					nReadLength = 0;
					}
					break;
				}
			}
			else
			{
				switch(nFieldLength)
				{
					case 7:
					case 9:
						Buff[nReadLength++] = nChar;
						break;
				}
			}
		}
		else if(nGpsSentenceIndex == 2 && nGpsStatus == GPS_NORMAL)
		{
			if(nChar == ',')
			{
				nFieldLength++;
				switch( nFieldLength )
				{
				case 1:
					nReadLength = 0;
					break;
				case 3:		
					{
						uchar i;
						for(i = 0;i<3;i++)
							Time[i] = (Buff[2*i]-'0')*10 + Buff[2*i+1] - '0';
						nReadLength = 0;
					}
					break;
				case 5:
					{
						uchar i;
						for(i = 0;i<7;i++)
							Latitude[i] = Buff[i];
						nReadLength = 0;
					}
					break;
				case 9:
					{
						uchar i;
						for(i = 0;i<8;i++)
							Longitude[i] = Buff[i];
						nReadLength = 0;
					}
					break;
				case 10:
					{
						uchar i;
						for(i = 0;i<3;i++)
							Date[2-i] = (Buff[2*i]-'0')*10 + Buff[2*i+1] - '0';
						nReadLength = 0;
					}
				case 11:
					NextSecond();
					break;
				}
			}
			else
			{
				switch(nFieldLength)
				{
				case 1:
				case 3:
				case 5:
				case 9:
					Buff[nReadLength++] = nChar;
					break;
				}
			}
		}
		RI = 0;
	}
	else if(TI)
	{
		if(nIsSend&&(nSendPos<3))
		{
			
			if(nSendPos == 1)
			{
			   SBUF = '\n';
			}
			else if(nSendPos == 2)
			{
				SBUF = '\r';
  			}
			else
				SBUF = SateliteNum + '0';
			TI = 0;	
		}
	}
}

void time0(void) interrupt 1 using 1
{
	TH0 = TH0CONST;	        	//		500us
	TL0 = TL0CONST;    
	
	nSignCounteNum ++;

	OUT1KHZ = !OUT1KHZ;
 	if(nSignCounteNum == PPS_LENGTH)
		OUTPPS = 0;
	else if(nSignCounteNum == BCD_LENGTH*nBcdCounter)
		OUTBCD = 0;
	else if(nSignCounteNum == PPMS_LENGTH)
		OUTPPMS = 0;
	else if(nSignCounteNum == PPHS_LENGTH)
		OUTPPHS = 0;
	else if(nSignCounteNum == PPML_LENGTH)
		OUTPPML = 0;
	else if(nSignCounteNum & KEYBOADMASK )
		nCheckKey = 1;
}

void externint0(void) interrupt 0 using 0
{
	OUTPPS = 1;
	OutSign();
}

void timer2(void) interrupt 5 using 3
{
	OUTPPS = 1;
	OutSign();	
	TF2 = 0;
	if(EXF2)
	{
		EXF2 = 0;
		EXEN2 = 0;
		nGpsStatus = GPS_LOST;
	}
}

void main(void)
{
	Init();
	while(1)
	{
		if(nSecondSign)
		{
			ShowLED();

			// start the serial sending
			nIsSend = 1;
			nSendPos = 0;

			// computer the bcd field length
			if(++nBcdPos == 10)
			{
				nBcdPos = 0;
				nBcdField++;
			}

			if(!nBcdPos)
				nBcdCounter = 8;
			else if(nBcdPos == 1)
			{
				if(!nBcdField)
					nBcdCounter = 8;
				else 
					nBcdCounter = 1;
			}
			else 
			{
				uchar nData;
				switch(nBcdField)
				{
					case 0:
						nData = 20;
						break;
					case 1:
						nData = Date[0];
						break;
					case 2:
						nData = Date[1];
						break;
					case 3:
						nData = Date[2];
						break;
					case 4:
						nData = Date[0];
						break;
					case 5:
						nData = Date[1];
						break;
				}
				if( nBcdPos < 6 )
					nBcdCounter = ((nData/10) & (0x01 << (5 - nBcdPos)))?8:1;
				else 
					nBcdCounter = ((nData%10) & (0x01 << (9 - nBcdPos)))?8:1;
			}
			nSecondSign = 0;
		}
		
		if(nCheckKey)
		{
			Scankeyboad();
			nCheckKey = 0;
		}
	}
}


void Init(void)
{
	CORRECTSIGN = 0;
	LOSTSIGN = 1;
	nGpsStatus = GPS_LOST; 

	Init8279();
	InitSerial();

	while(nGpsStatus ==GPS_LOST);

	InitTime0();
	InitTimer2();

	// Initlize the extern interrupt source 0
	IT0 = 1;		// 设置负跳变引起中断
	PX0 = 1;
}

void Init8279(void)
{
	COM = 0XD1;
	COM = 0x08;
	COM = 0X32;
}

void InitSerial(void)
{
	SCON  = 0x50;	// SCON: mode 1, 8-bit UART, enable rcvr 
  	TMOD |= 0x20;	// TMOD: timer 1, mode 2, 8-bit reload 
  	TH1   = 0xFA;	// TH1:  reload value for 9600 baud 
  	TR1   = 1;		// TR1:  timer 1 run 
  	PCON |= 0X80;	// SET THE SMOD 1
  	TI    = 1;		// TI:   set TI to send first char of UART
  	EA = 1;
	ES = 1;
}

void InitTime0(void)
{
	TMOD |= 0X01;
	TH0 = -(46080/256);		//	500us
	TL0 = -(46080%256);     //
	ET0 = 1;
	TR0 = 1;
}

void InitTimer2(void)
{
	T2CON &= 0xf0;
	T2CON |= 0x80;					// Set T2Ex valid
	TH2 = -(TIMER2COUNTER/256);		//	50ms
	TL2 = -(TIMER2COUNTER%256);    	//
	RCAP2H = TH2;
	RCAP2L = TL2;
	PT2 = 1;
	//ET2 = 1;						// open the T						
}

void Scankeyboad()
{
	if(COM&0X0F)
	{
		COM = 0X40;
		nInputKey = DAT;
		nInputKey = nInputKey&0x3f;
	}
}

void OutSign(void)
{
	OUTBCD = 1;
	if(nMinuteSign)
	{
		OUTPPMS	= OUTPPML = 1;
		nMinuteSign = 0;
		if(nHourSign)
		{
			OUTPPHS = OUTPPHL = 1;
			nMinuteSign = 0;
		}
		nBcdPos = -1;
		nBcdField = 0;
	}	

	nSecondSign = 1;
	nSignCounteNum = 0;
}

void ShowLED(void)
{
	uchar i;
	COM = 0x90;
	//if(!nInputKey)
	{
		for(i = 0; i<16; i++)
		{
			COM = i+0x80;
			switch(i)
			{
				case 0:
					DAT = table[2];
					break;
				case 1:
					DAT = table[0];
					break;
				case 2:
					DAT = table[Date[0]/10];
					break;
				case 3:
					DAT = table[Date[0]%10];
					break;
				case 4:
					DAT = table[Date[1]/10];
					break;
				case 5:
					DAT = table[Date[1]%10];
					break;
				case 6:
					DAT = table[Date[2]/10];
					break;
				case 7:
					DAT = table[Date[2]%10+10];
					break;
				case 8:
					DAT = table[Time[0]/10];
					break;
				case 9:
					DAT = table[Time[0]%10];
					break;
				case 10:
					DAT = 0x40;
					break;
				case 11:
					DAT = table[Time[1]/10];
					break;
				case 12:
					DAT = table[Time[1]%10];
					break;
				case 13:
					DAT = 0x40;
					break;
				case 14:
					DAT = table[Time[2]/10];
					break;
				case 15:
					DAT = table[Time[2]%10];
					break;
			}
	   	}
	}
/*	else if(!(nInputKey&0x10))
	{
		for(i = 0; i<7; i++)
		{
			COM = i+0x80;
			DAT = table[led[i]];
		}
		COM = 7+0x80;
		DAT = table[20];
		for(i = 8;i<16;i++)
		{
			COM = i+0x80;
			DAT = table[led[i-1]];
		}
	}
	else
	{
		for(i = 0;i<2;i++)
		{
			COM = i + 0x80;
			DAT = table[Satelite[i]];
		}
	 	COM = 2 + 0x80;
		DAT = table[20];
		for(i =3;i<8;i++)
		{
			COM = i + 0x80;
			DAT = table[Satelite[i-1]];
		}
		for(i = 8;i<16;i++)
		{
			COM = i + 0x80;
			DAT = table[20];
		}
	}*/
}

//	为了与GPS输出同步输出时间信号,必须计算出下一秒时间和日期
//
void NextSecond(void)
{
	if(++Time[2] == 60)
	{
		Time[2] = 0;
		nMinuteSign = 1;
		if(++Time[1] == 60)
		{
			Time[1] = 0;
			nHourSign = 1;
			if(++Time[0] == 24)
			{
				Time[0] = 0;
				if(++Date[2] == 29 && Date[1] == 2 && (Date[0]%4) ) 
				{						
					Date[2] = 1;	// 3月1号
					Date[1] = 3;
				}
				else if(Date[2] == 30 && Date[1] == 2 && !(Date[0]%4))
				{
					Date[2] = 1;
					Date[1] = 3;
				}
				else if(Date[2] == 31)
				{
					if(Date[1] == 9 || Date[1] == 11 || Date[1] == 2 || 
						Date[1] == 4 || Date[1] == 6)
					{
						Date[2] = 1;
						Date[1] ++;
					}
				}
				else if(Date[2] == 32)
				{
					if( (Date[1] >= 8 && !(Date[1]%2)) ||
							(Date[1] <8 && (Date[1]%2)))
					{
						Date[2] = 1;
						if(++Date[1] == 13)
						{
							Date[1] = 1;
							Date[0] ++;
						}
					}
				}
			}
		}
	}
}		



⌨️ 快捷键说明

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