wave.JPG
위의 그림처럼 듀티비가 50%인 구형파의 주파수를 알아내는 프로그램입니다.
아래 tip공개에 언급한 프린터 포트를 이용하였습니다.

프린터 포트중에 busy 시그널 입력 단자에 위의 그림처럼 dc 0-5v사이의 펄스를 인가하고,
아래 프로그램을 컴파일 한후 실행시키면 주기와 주파수가 측정 됩니다.

주파수 측정범위는 100hz까지가 정확하고, 그  이상은 오차가 발생합니다.
측정주파는 100hz미만이지만 느린주파수의 펄스 신호 같은 곳에는 사용이 편리할것입니다.
앞으로 전력측정기에 적용하여 가정용 전력을 실시간으로 감시 하려고 합니다.   

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/time.h>
#define BASETIME 100000L

void Settimer(void)
{
    struct itimerval t;
    t.it_interval.tv_sec = 0;
    t.it_interval.tv_usec = 0;
    t.it_value.tv_sec = BASETIME; /* 1시간   */
    t.it_value.tv_usec = 0;
    if (setitimer(ITIMER_REAL, &t, NULL) == -1){ perror("Failed to set virtual timer"); }
}

float Gettimer(void)
{
    struct itimerval t;
    float  diftime;
    if (getitimer(ITIMER_REAL, &t) == -1){perror("Failed to get virtual timer");}
   
    diftime=(float)BASETIME-((float)(t.it_value.tv_sec)+((float)t.it_value.tv_usec/1000000.0));
    return(diftime);   
}

int Initprinterport(void)
{
   int fd;       // File Descripter
   fd = open("/dev/port", O_RDWR);       // open /dev/port in read & write mode 
   if(fd < 0)                                            // open error, fd must be unsigned.
   {
        perror("/dev/port open error");
   }
   return(fd);
}

void Closeprinterport(int fd)
{
  close(fd); 
}

int Getbusyprinterport(int fd)
{
  unsigned char buffr[1];
  int op;
  lseek(fd,0x379,0);
  read(fd,buffr,1);
  buffr[0]>>=7;
  op=(int)(0x01&buffr[0]);
  return(op);
}

int main(void)
{
  int i,j;
  int fd;
  float tm,frq;
  fd=Initprinterport();
 
  while(1)    
  {
     while(1)
     {
        i=Getbusyprinterport(fd);
        if(i==1) break;   
     }
 
    Settimer();
     while(1)
     { 
        i=Getbusyprinterport(fd);
        if(i==0) break;
     }  
 
          tm=Gettimer();  
          frq=1.0/(tm*2.0);      
          printf(">T=%10.3f[sec] frq=%10.3f[hz]\n",tm,frq);
  }
  Closeprinterport(fd);

  return 0;
}

ter.jpg