728x90

# 프로그램 설명

1. TimeOne 라이브러리를 사용한다. 스케치-라이브러리 포함하기-라이브러리 관리에서 다운 받으면 사용할 수 있다. setup() 부분에 Timer1.initialize(50);이라고 선언하면 타이머 간격을 50us로 설정한다. Timer1.attachInterrupt(isr);이라고 선언하면 50us 마다 인터럽트를 발생시켜 isr함수를 호출한다. 


2. 입력 받은 주파수가 10000hz 이하 이면, 즉 주기가 100us 이상인 경우(주기/2가 50us 이상인 경우) 주파수가 출력 가능한 범위이고 주기가 100us 보다 작은 경우는 주파수가 출력 불가하다. 


3. 50us 마다 인터럽트 발생 시 호출되는 함수 isr에서 count(us) 값이 (주기/2) us 값과 같아지면 스피커 단자에 입력받은 주파수를 출력한다. 


4. 이외의 loop() 부분과 자체 함수 myTone()과 myNoTone() 함수의 내용은 12번과 동일

 

# 소스

#include <TimerOne.h>
#define spkPin 13        // 스피커 단자
volatile int state = 0;  // 상태를 저장하는 변수
volatile int speak = 0;  // 스피커 상태를 저장하는 변수
volatile int count = 0;   // 인터럽트 횟수를 세는 변수
int freq;                // 주파수
int x;                   // 주기/2

void setup() {
  Serial.begin(9600);
  pinMode(spkPin, OUTPUT); // 스피커 단자 출력 모드로 설정
  Timer1.initialize(50);  // 50us 마다 인터럽트 발생하게 설정
  Timer1.attachInterrupt(isr); // 인터럽트 발생 시 호출할 함수 설정
}

void loop() {
  if(state == 1){            // 상태가 1이면(주파수가 입력되어 출력 가능한 범위)
    if(speak == 1){          // 스피커 상태 변수가 1이면
      speak=0;                // 스피커 상태 변수를 0으로 바꾼 후
      myTone(spkPin,freq);    // 스피커 단자에 원하는 주파수의 음정 출력
      myNoTone(spkPin);       // 스피커 단자 소리 끔   
      state = 0;              // 상태 0으로 바꿈(주파수 입력 가능한 상태)
    }
  }
 
  String inString;  // 스트링 변수 선언
  
  if(state == 0){   // 상태가 0이면(주파수 입력 가능한 상태)  
    while(1){
      if(Serial.available()>0){       // 시리얼에 주파수 입력했으면
        char inChar = Serial.read();  // 들어온 값 문자단위로 읽음
        if(inChar == '\n')         
          break;
        Serial.print(inChar);      // 들어온 값 출력
        inString += (char)inChar;  // 스트링 변수에 더함
        freq = inString.toInt();   // int형으로 변환
        x = 1000000/(freq*2);         // (주기/2)us를 x에 저장
      }
    }
    Serial.println();
    state=1;                  // 상태를 1로 바꿈(주파수 입력한 상태)   

    if(x < 50){ // 주파수가 출력 불가능한 범위이면 거절 메세지 출력
      state = 0;
      Serial.println("생성할 수 없는 주파수입니다.");
    }
  }
}

void isr(){       // 인터럽트 발생 시 호출되는 함수
  if(state == 1)    // 상태가 1이면 (주파수가 출력 가능한 범위이면)
    count++;      // 인터럽트 발생할 때마다 count값 올림
  if(count == x){   // count(us)값이 (주기/2)us값과 같아지면
    count = 0;    // count값 0으로 초기화
    speak = 1;    // 스피커 상태 변수 1로 바꿈
  }
}

void myTone(int pin, int frequency){  // 원하는 주파수 출력하는 함수
  for(int i=0; i<frequency*2; i++){   // 2초 동안 출력
    digitalWrite(pin, HIGH);
    delayMicroseconds(x);
    digitalWrite(pin, LOW);
    delayMicroseconds(x);
  }
  delay(1000);
}

void myNoTone(int pin){  // 스피커 단자 소리 끄는 함수
  digitalWrite(pin, LOW);
}

 

# 실행화면(Tera Term)

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기