#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;
}
}
}
}
|