免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3577 | 回复: 5
打印 上一主题 下一主题

串口接入GPS卫星钟的问题sos [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-11-02 20:43 |只看该作者 |倒序浏览
串口接入GPS卫星钟的问题,我们原来的卫星钟信号是通过终端服务器如chase moxa接入局域网的,现在用户说网络有时延,要从串口接入,小弟我的头就大了,那位大哥能帮我一把?不胜感激!
环境:alpha Tru64系统,用的C/C++

论坛徽章:
0
2 [报告]
发表于 2003-11-03 12:58 |只看该作者

串口接入GPS卫星钟的问题sos

1. I use DS20 Alpha Server, Tru64 4.0F

2. The protocol is like that
(1)、格式1
RS-232C1、2
2脚为发送数据,3脚为接收数据,5脚为地。
       波特率:  4800bit/s  (出厂预置)
       数据位:  8位  (ASCII码)
       起始位:  1位
       停止位:  1位
       校验位:   无
       工作方式: 异步
    输出年,月,日,时,分,秒,工频钟面,钟差、周波数和外部事件产生的时刻(准确到微秒),每秒发送一次起始位与标准秒同步,误差小于0.2ms。
格式:
语句: BJT,YYYYMMDD,hhmmss,±XXXX.XX,HHFFPP,ff.f1f1f1<CR>;<LF>;
其中:  BJT表示北京时间。
        YYYY为年,MM为月,DD为日,hh为时,mm为分,ss为秒。±表示钟差的符号,XXXX。XX为钟差值(标准钟-工频钟),单位为秒。HHFFPP分别为工频钟的时,分,秒。ff为周波数的两位整数部分,f1f1f1为周波数的三位小数部分。

论坛徽章:
0
3 [报告]
发表于 2003-11-03 13:00 |只看该作者

串口接入GPS卫星钟的问题sos

3. the code is that :

#include<sys/types.h>;
#include<sys/signal.h>;
#include<sys/siginfo.h>;
#include<termios.h>;
#include<stdio.h>;
#include<unistd.h>;
#include<sys/ioctl.h>;
#include<sys/file.h>;
#include<sys/termios.h>;
#include<fcntl.h>;
#include<time.h>;
#include<sys/time.h>;
#include<math.h>;
#include <string.h>;
#include <stdlib.h>;
#define BAUDRATE B4800
#define MODEMDEVICE"/dev/tty01"
/**局部常量**/
FILE *freqFile;
#define FALSE 0
#define TRUE 1
char write_export[50];
char get_export[30];
int MaxSlew; /*最大调节量为500000微秒*/

/*局部变量*/
int fd,res,i,flags,lined;

int count;
short int STOP=FALSE;
short int WAIT=FALSE;
int ReviseTimer;/*两次校正时间间的秒数*/
int Adjuster;/*间隔多少秒校正一次时间*/
int TimeSlew1;/*上次调节时间差毫秒*/
int TimeSlew2;/*本次调节时间差毫秒*/
int SecGap;/*GPS与本地时间差秒*/
int uSecGap;  /*GPS与本地时间差毫秒*/
char buf[255];
int Year,Month,Day,Houth,Min,Sec;
int RecvError;
char ch[3];

char chone;
char freq[6];
float frequency;
int one;
const time_t tm_set;

struct tm bktime;
struct timeval TimeSet;
struct timeval TimeLocal;  
time_t SetTimeVal;

/*函数说明*/
void TP_Init();/*初始化端口函数,TP----Time Protocol*/
void Recv();/*从端口中读取数据*/
void DataDispose();

short int SetAdjum;
/*主函数*/

void main()
{
/*内部变量*/
/*初始化一些变量*/
  ReviseTimer=299;
  Adjuster=300;/*5分钟调节一次时间*/
  TimeSlew1=0;
  TimeSlew2=0;
count=41;
  MaxSlew=50000;
  RecvError=TRUE;
  /*初始化端口*/

  
  TP_Init();
  printf( "After TP_Init \n";
  while(STOP==FALSE)
  {

          Recv();
          
         /*如果是头一次或与上一次间隔有5分钟时进行时间调节*/
         
               DataDispose();

        continue;
         
          if(ReviseTimer>;=4)
          {
               ReviseTimer=0;
               DataDispose();
          }
                    
          gettimeofday(&TimeLocal,NULL);
        //   printf("%s\n%s,,,%d\n",buf,ctime(&TimeLocal.tv_sec),TimeLocal.tv_usec);
     
         
   }

  close(fd);
  
}


void TP_Init()
{
  struct termios newtio;

  fd=open(MODEMDEVICE,O_RDWR);
  if(fd<0)
  {
    perror(MODEMDEVICE);
    exit(-1);
  }

  isatty(fd);
  tcgetattr(fd,&newtio);
  bzero((void *) &newtio,sizeof(newtio));
  flags=fcntl(fd,F_GETFL,0);
  newtio.c_cflag=CS8|CRTSCTS|CREAD|CLOCAL;
  newtio.c_iflag=IXON|IXOFF;
  newtio.c_oflag=0;
  newtio.c_lflag=0;
  newtio.c_cc[VTIME]=0;
  newtio.c_cc[VMIN]=42;
  cfsetispeed(&newtio,BAUDRATE);/*设置输入波特率*/
  cfsetospeed(&newtio,BAUDRATE);/*设置输出波特率*/
  tcflush(fd,TCIOFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);
}

void Recv()
{
        int i;

        memset( buf, 0, sizeof( buf));
        read(fd,buf,43);
        printf( "\n%s", buf);

        ReviseTimer=ReviseTimer+1;
        if((buf[0]=='B')&&(buf[1]=='J')&&(buf[2]=='T')&&(buf[3]==','))
        {
           RecvError=FALSE;
           printf("asdddddddddddddddd\n";
            
        }
         if((buf[0]!='B')||(buf[1]!='J')||(buf[2]!='T')||(buf[3]!=','))
        {
             
            
            RecvError=TRUE;
            WAIT=FALSE;
            while(WAIT==FALSE)
            {

              one=read(fd,&chone,1);
              if((one>;0)&(chone=='B'))
              {
                 buf[0]=chone;
                 for( i=0;i<count-1
                 {
                   one=read(fd,&chone,1);
                   if(one>;0){
                     buf[i+1]=chone;
                    i=i+1;
                   }
               }
               WAIT=TRUE;            
            }
          }
                    
         }
         
}

/*
*把从串口读来的字符串转换成数字年月日分秒
*并且与本地时间相比得出一个时间差
*/

void DataDispose()
{
        /*把从串口读来的字符串转换成数字年月日分秒*/
        if(buf[12]==','){
           ch[0]=buf[6];
           ch[1]=buf[7];
           Year=atoi(ch)+2000;

           ch[0]=buf[8];
           ch[1]=buf[9];
           Month=atoi(ch);

           ch[0]=buf[10];
           ch[1]=buf[11];
           Day=atoi(ch);

           ch[0]=buf[13];
           ch[1]=buf[14];
           Houth=atoi(ch);

           ch[0]=buf[15];
           ch[1]=buf[16];
           Min=atoi(ch);

           ch[0]=buf[17];
           ch[1]=buf[18];
           Sec=atoi(ch);

           freq[0]=buf[36];
           freq[1]=buf[37];
           freq[2]=buf[38];
           freq[3]=buf[39];
           freq[4]=buf[40];
           freq[5]=buf[41];
           frequency=atof(freq);

           count=42;                                                      

           printf( "\n %d 20%c%c/%c%c/%c%c %c%c:%c%c:%c%c \n", __LINE__,
                   buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
                   buf[13], buf[14], buf[15], buf[16], buf[17], buf[18]);

           printf( " %d %d/%d/%d %d:%d:%d \n", __LINE__,
                   Year, Month, Day, Houth, Min, Sec);
      
}
      
else
      
{
      
           ch[0]=buf[3];
           ch[1]=buf[4];
           Year=atoi(ch)+2000;

           ch[0]=buf[5];
           ch[1]=buf[6];
           Month=atoi(ch);

           ch[0]=buf[7];
           ch[1]=buf[8];
           Day=atoi(ch);

           ch[0]=buf[10];
           ch[1]=buf[11];
           Houth=atoi(ch);

           ch[0]=buf[13];
           ch[1]=buf[14];
           Min=atoi(ch);

           ch[0]=buf[15];
           ch[1]=buf[16];
           Sec=atoi(ch);

           freq[0]=buf[34];
           freq[1]=buf[35];
           freq[2]=buf[36];
           freq[3]=buf[37];
           freq[4]=buf[38];
           freq[5]=buf[39];count=40;

           frequency=atof(freq);                             
      
}
   
   
  freqFile=fopen("/proj/data/Freq.dat","w";
        if((frequency>;3&&(frequency<60)){
         
      
  fprintf(freqFile,"%6.4f",frequency);
      
   }
      
   fclose(freqFile);
      
   /*转换为系统时间格式*/          
           bktime.tm_sec=Sec;
           bktime.tm_min=Min;
           bktime.tm_hour=Houth;
           bktime.tm_mday=Day;
           bktime.tm_mon=Month-1;
           bktime.tm_year=Year-1900;
           TimeSet.tv_sec=mktime(&bktime);
           TimeSet.tv_usec=0;

                        settimeofday(&TimeSet,NULL);


           return ;

           gettimeofday(&TimeLocal,NULL);
           /**********比较时间的大小*****************/
           SecGap=TimeLocal.tv_sec-TimeSet.tv_sec;
            
            printf("\n%d,,,%s,%d,...%6.4f\n",TimeLocal.tv_sec,ctime(&TimeLocal.tv_sec), SecGap,frequency);
      
         
           if(SecGap>;=2)
              SecGap=2;
           if(SecGap<=-2)
              SecGap=-2;
           uSecGap=SecGap*1000000+TimeLocal.tv_usec;
           TimeSlew1=(int)((uSecGap+TimeSlew2)/2);
         
         if((uSecGap>;-1000)&&(uSecGap<1000)&&(SetAdjum<100))
           {
                 MaxSlew=5000;
                 SetAdjum=100;
                 }
           else if((uSecGap>;-1000)&&(uSecGap<1000)&&(SetAdjum>;=100)&&(SetAdjum<1000))
                     SetAdjum=SetAdjum+1;
           if((uSecGap<-2000)&&(uSecGap>;2000)&&(SetAdjum>;100))          
                     SetAdjum=100;
           if((uSecGap<-2000)&&(uSecGap>;2000)&&(SetAdjum<100)&&(SetAdjum>;10))          
                      SetAdjum=SetAdjum-1;
           if((SetAdjum<95)&&(SetAdjum>;10)&&(uSecGap<-2000)&&(uSecGap>;2000))
           {
                   SetAdjum=0;
                  MaxSlew=50000;
           }
           if(SetAdjum>;105){
                SetAdjum=110;
                MaxSlew=500;
                }        
   /*如果说本机时间比读取GPS的大,说明要使本机时间性慢一点*/
           if(TimeSlew1>;=0)
           {
                   if((TimeSlew1>;MaxSlew))
                   {
                           TimeSlew1=MaxSlew;
                           ReviseTimer=200;/*如果差距太大缩短调节时间间隔*/
                   }
               

           }
           /*如果说本机时间比读取GPS的小,说明要使本机时间性快一点*/
         if(TimeSlew1<0)
           {
           if((TimeSlew1<-MaxSlew))
                   {
                           TimeSlew1=-MaxSlew;
                           ReviseTimer=200;/*如果差距太大缩短调节时间间隔*/
                   }
                              
           }
           TimeSlew2=TimeSlew1;       
           gettimeofday(&TimeLocal,NULL);
           TimeLocal.tv_usec=TimeLocal.tv_usec-TimeSlew1;
           if(TimeLocal.tv_usec>;=1000000)
           {
              TimeLocal.tv_usec=TimeLocal.tv_usec-1000000;
              TimeLocal.tv_sec=TimeLocal.tv_sec+1;
           
           }
           if(TimeLocal.tv_usec<0)
           {
               TimeLocal.tv_usec=TimeLocal.tv_usec+1000000;
              TimeLocal.tv_sec=TimeLocal.tv_sec-1;
            }
            
                        settimeofday(&TimeLocal,NULL);

            
}

论坛徽章:
0
4 [报告]
发表于 2003-11-03 14:42 |只看该作者

串口接入GPS卫星钟的问题sos

再问大哥一个问题:用的是c编译器还是cxx编译器?
谢谢

论坛徽章:
0
5 [报告]
发表于 2003-11-04 18:59 |只看该作者

串口接入GPS卫星钟的问题sos

我这里的GPS时钟原来是用串口接入的,也是Tru 64 下的系统。
但是客户说串口太慢,要该成终端服务器方式的,正好和这位的相反!
用户的要求真是千奇百怪。

论坛徽章:
0
6 [报告]
发表于 2003-11-05 08:20 |只看该作者

串口接入GPS卫星钟的问题sos

原帖由 "东子" 发表:
我这里的GPS时钟原来是用串口接入的,也是Tru 64 下的系统。
但是客户说串口太慢,要该成终端服务器方式的,正好和这位的相反!
用户的要求真是千奇百怪。

可以把你的串口程序发给我看看吗?谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP