白钻会员
主题
帖子
积分54909
阅读权限50
注册时间2010-5-23
最后登录1970-1-1
在线时间 小时
|
本帖最后由 benli 于 2015-3-13 20:32 编辑
别叫俺老师,惭愧啊!那GPS板子上有稳压器,可以直接5v供电,与单片机也可以直接连接
51单片机默认是弱上拉的开漏结构,
C程序移植很简单,GPS接收是独立的程序模块,可以方便的加入原程序之中
至于汇编,就不懂了- 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; //数据计数
- // static bit RX_start; //GPS数据接收开始标志位
- uchar idata GPRMC[6]={0x24,0x47,0x50,0x52,0x4D,0x43}; //GPS选择接收字符$GPRMC,
- 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==9) //保存日期数据
- RQ[da_count++]=Rx_temp;
- else
- if(fg_count>10) //接收完毕
- {
- RX_over=1;
- // RX_start=0;
- fg_count=0;
- da_count=0;
- Rx_count=0;
- }
- }
- }
- }
- }
- void GPSdata()
- {
- static uchar idata hour[2],min[2],sec[2],year[2],mon[2],day[2]; //临时时间数据 ,为了预防数据传输的误码,使用了2次数据比较
- static uchar a,max;
- RX_over=0;
- //保存临时时间数据
- hour[a]=(SJ[0]-0x30)*10 + (SJ[1]-0x30); //时
- min [a]=(SJ[2]-0x30)*10 + (SJ[3]-0x30); //分
- sec [a]=(SJ[4]-0x30)*10 + (SJ[5]-0x30); //秒
- day [a]=(RQ[0]-0x30)*10 + (RQ[1]-0x30); //日
- mon [a]=(RQ[2]-0x30)*10 + (RQ[3]-0x30); //月
- year[a]=(RQ[4]-0x30)*10 + (RQ[5]-0x30); //年
- a++;
- for(max=0;max<6;max++)
- {
- SJ[max]=0;
- RQ[max]=0;
- }
- if(a>1)
- {
- a=0;
- //如果第二次秒比上次小1,并且分,时,日,月年相同
- if(sec[1]-sec[0]==1&&min[1]==min[0]&&hour[1]==hour[0]&&day[1]==day[0]&&mon[1]==mon[0]&&year[1]==year[0])
- {
- sec[1]+=1; //GPS时间是包含毫秒的,加上1秒补偿传输和程序处理的延时
- if(sec[1]>59)
- {
- sec[1]=0;
- min[1]+=1;
- if(min[1]>59)
- {
- min[1]=0;
- hour[1]+=1;
- }
- }
- hour[1]+=8; //转换为北京时间 ,东8区要+8
- if(hour[1]>23) //如果超过23则到了第二天
- {
- hour[1]-=24; //
- day[1]+=1; //日+1
- switch(mon[1]) //获取每月最大天数
- {
- case 2: //2月
- if(year[1]%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(day[1]>max)
- {
- mon[1]+=1;
- day[1]=0;
- if(mon[1]>12)
- {
- year[1]+=1;
- mon[1]=0;
- }
- }
- }
- DS1302_WriteData(0x8e, 0x00); //允许写操作 写入时间数据到1302
- DS1302_WriteData(0x80, sec[1]/10*16 + sec[1]%10 ); //秒
- DS1302_WriteData(0x82, min[1]/10*16 + min[1]%10 ); //分
- DS1302_WriteData(0x84, hour[1]/10*16 + hour[1]%10 ); //时
- DS1302_WriteData(0x86, day[1]/10*16 + day[1]%10 ); //日
- DS1302_WriteData(0x88, mon[1]/10*16 + mon[1]%10 ); //月
- DS1302_WriteData(0x8c, year[1]/10*16 + year[1]%10 ); //年
- DS1302_WriteData(0x8e, 0x80); //写保护
- GPS_POW=1; //关闭GPS电源
- // ES_OFF;
- GetAllTime(); //读取全部时间
- GetNL_ri(); //农历转换
- }
- }
- }
- main()
- {
- if(RX_over&&DW_OK) //接收完一帧数据并且收到定位成功信息后进行数据处理,定位后的时间肯定是准确的
- // if(RX_over && (RQ[5]>0x34 & RQ[5]<0x39) ) //如果信号较差能收到时间却没有定位可以用这句降低处理条件
- GPSdata();
- if(shi1==0&&shi2==1&&fen1==0&&fen2==0) //1点同步时间
- {
- ES_ON; //打开独立波特率发生器 ]
- GPS_POW=0; //打开GPS电源
- }
- }
复制代码 |
评分
-
查看全部评分
|