#include <string.h>
void UartInit4800(void) //4800bps@30.000MHz
{
SCON = 0x50; //8位數據,可變波特率
AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
TMOD &= 0x0F; //設定定時器1為16位自動重裝方式
TL1 = 0xE5; //設定定時初值
TH1 = 0xF9; //設定定時初值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
ES = 1; //使能串口1中斷
EA = 1;
}
void UartInit9600(void) //9600bps@30MHz
{
SCON = 0x50; //8位數據,可變波特率
AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
TMOD &= 0x0F; //設定定時器1為16位自動重裝方式
TL1 = 0xF3; //設定定時初值
TH1 = 0xFC; //設定定時初值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
ES = 1; //使能串口1中斷
EA = 1;
}
void UartInit1152(void) //115200bps@30.000MHz
{
SCON = 0x50; //8位數據,可變波特率
AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
TMOD &= 0x0F; //設定定時器1為16位自動重裝方式
TL1 = 0xBF; //設定定時初值
TH1 = 0xFF; //設定定時初值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
ES = 1; //使能串口1中斷
EA = 1;
}
void UartInit(){
switch(bps) {
case 0://
UartInit1152();
break;
case 1://
UartInit9600();
break;
case 2://
UartInit4800();
break;
default:
UartInit1152();
break;
}
}
void Uart() interrupt 4 using 1
{
uchar data Rx_temp ;
static uchar fg_count=0; //數據間隔,計數
static uchar Rx_count=0;
static uchar n=0; //握手信號計數
static uchar da_count=0; //數據計數
uchar idata GPRMC[6]={0x24,0x47,0x50,0x52,0x4D,0x43}; //GPS選擇接收字符$GPRMC,
uchar idata GPVTG[6]={0x24,0x47,0x50,0x56,0x54,0x47}; //GPS選擇接收字符$GPVTG,
if(RI)
{
RI=0;
Rx_temp=SBUF;
/******* 監控握手信號進行軟件復位自動下載 ******/
if(Rx_temp==0x7f)
{ //STC下載指令是0x7f
n++;
if(n>20) //如果連續收到20次0x7f
{
IAP_CONTR=0x60; //復位至ISP區
n=0;
}
}
else
n=0;
/********* GPS數據處理 **************/
if(Rx_count<6)
{
if(Rx_temp==GPRMC[Rx_count]) //比較開始$GPRMC字符,
Rx_count++;
else
Rx_count=0;
}
else //找到GPRMC開始保存數據
{
if(Rx_temp==',') //如果收到逗號,
{
fg_count++; //計數增加
da_count=0;
}
else
{
if(fg_count==1) //保存時間數據
{
if(da_count<6) //只保存前6位時間數據
SJ[da_count++]=Rx_temp;
}
else
if(fg_count==2) //保存定位信息
{
if(Rx_temp=='A') //如果收到A
DW_OK=1; //則定位成功
else
DW_OK=0;
}
/*****************************************************/
else //緯度
if(fg_count==3) //保存定位信息
{
if(da_count<10) //只保存前10位時間數據
weidu[da_count++]=Rx_temp;
}
else //緯度半球N(北半球)或S(南半球)
if(fg_count==4) //保存定位信息
{
NS=Rx_temp;
}
else//經度
if(fg_count==5) //保存定位信息
{
if(da_count<10) //只保存前10位時間數據
jindu[da_count++]=Rx_temp;
}
else //經度半球E(東經)或W(西經)
if(fg_count==6) //保存定位信息
{
EW=Rx_temp;
}
else //地面速率(000.0~999.9節,前面的0也將被傳輸)
if(fg_count==7) //保存定位信息
{
if(da_count<5) //只保存前10位時間數據
shudu[da_count++]=Rx_temp;
}
/*****************************************************/
else
if(fg_count==9) //保存日期數據
RQ[da_count++]=Rx_temp;
else
if(fg_count>9) //接收完畢
{
RX_over=1;
fg_count=0;
da_count=0;
Rx_count=0;
}
}
}
/************************************************
if (Rx_temp == '$') //如果收到字符'$',便開始接收
{
rev_start = 1;
rev_stop = 0;
}
if (rev_start == 1) //標志位為1,開始接收
{
rev_buf[num++] = Rx_temp; //字符存到數組中
if (Rx_temp == '\n') //如果接收到換行
{
rev_buf[num] = '\0';
rev_start = 0;
rev_stop = 1;
//gps_flag = 1;
num = 0;
}
}
*************************************************/
}
}
double Str_To_Double(char *buf)
{
xdata double rev_d = 0;
xdata uchar dat;
xdata uchar integer = 1;
xdata char *str = buf;
xdata int i;
while(*str != '\0')
{
switch(*str)
{
case '0':
dat = 0;
break;
case '1':
dat = 1;
break;
case '2':
dat = 2;
break;
case '3':
dat = 3;
break;
case '4':
dat = 4;
break;
case '5':
dat = 5;
break;
case '6':
dat = 6;
break;
case '7':
dat = 7;
break;
case '8':
dat = 8;
break;
case '9':
dat = 9;
break;
case '.':
dat = '.';
break;
}
if(dat == '.')
{
integer = 0;
i = 1;
str ++;
continue;
}
if( integer == 1 )
{
rev_d = rev_d * 10 + dat;
}
else
{
if(i<10000)
rev_d = rev_d + dat / (10 * i);
i = i * 10 ;
}
str ++;
}
return rev_d;
}
float Str_To_Float(char *buf)
{
xdata float rev = 0;
xdata uchar dat;
xdata uchar integer = 1;
xdata char *str = buf;
xdata int i;
while(*str != '\0')
{
switch(*str)
{
case '0':
dat = 0;
break;
case '1':
dat = 1;
break;
case '2':
dat = 2;
break;
case '3':
dat = 3;
break;
case '4':
dat = 4;
break;
case '5':
dat = 5;
break;
case '6':
dat = 6;
break;
case '7':
dat = 7;
break;
case '8':
dat = 8;
break;
case '9':
dat = 9;
break;
case '.':
dat = '.';
break;
}
if(dat == '.')
{
integer = 0;
i = 1;
str ++;
continue;
}
if( integer == 1 )
{
rev = rev * 10 + dat;
}
else
{
rev = rev + dat / (10 * i);
i = i * 10 ;
}
str ++;
}
return rev;
}
void Int_To_Str(int x,char *Str)
{
xdata int t;
xdata char *Ptr,Buf[5];
xdata int i = 0;
Ptr = Str;
if(x < 10) // 當整數小于10時,轉化為"0x"的格式
{
*Ptr ++ = '0';
*Ptr ++ = x+0x30;
}
else
{
while(x > 0)
{
t = x % 10;
x = x / 10;
Buf[i++] = t+0x30; // 通過計算把數字轉化成ASCII碼形式
}
i -- ;
for(;i >= 0;i --) // 將得到的字符串倒序
{
*(Ptr++) = Buf[i];
}
}
*Ptr = '\0';
}
void utc2btc(){
uchar xdata max;
shi=(SJ[0]-0x30)*10 + (SJ[1]-0x30); //時
fen=(SJ[2]-0x30)*10 + (SJ[3]-0x30); //分
miao=(SJ[4]-0x30)*10 + (SJ[5]-0x30); //秒
ri=(RQ[0]-0x30)*10 + (RQ[1]-0x30); //日
yue=(RQ[2]-0x30)*10 + (RQ[3]-0x30); //月
nian=(RQ[4]-0x30)*10 + (RQ[5]-0x30); //年
shi+=8; //轉換為北京時間 ,東8區要+8
if(shi>23) //如果超過23則到了第二天
{
shi-=24; //
ri+=1; //日+1
switch(yue) //獲取每月最大天數
{
case 2: //2月
if(nian%4==0) //判斷是否閏月,只取2000-2099年,因此簡單的%4運算
max=29; //閏月29天
else
max=28; //正常28天
break;
case 4: case 6:
case 9: case 11: //4,6,9,11月
max=30; //30天
break;
default:
max=31; //其他月份1,3,5,7,8,10,12月31天
break;
}
if(ri>max)
{
yue+=1;
ri=1;
if(yue>12)
{
nian+=1;
yue=1;
}
}
}
}
|