📄 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 + -