임베디드 기초 강좌 5 - clock


임베디드 기초 강좌 5 - clock

 

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]


 

안녕하세요. 고명호 입니다 

 이번에는 임베디드 MPU를 다루는데 있어서 심장부가 되는 클럭에 대해서 알아보겠습니다.

 일반적인 TTL등의 descrete IC를 이용하는 전자 기기에서는 클럭이 필요하지 않은 경우도 

 많이 있습니다만 임베디드 MPU를 제어하는데는 정해진 순서대로 프로그램이 

 수행되어야 하는데 이러한 프로그램이 정확한 시간에 수행되기 위해서 

 클럭은 필수적인 요소가 됩니다.

 

 

 

단순한 키트류의 부품또는 CPLD나 FPGA를 제외하고 프로그램이 수행되는 모든 전자기기에는

 클럭이 존재합니다. 

 

 

 

일반적으로 똑같은 MPU를 사용하는경우에 클럭이 빠르면 명령어의 수행이 

 더 빠르게 이루어 지게 됩니다. 즉 6Mhz로 동작하는 회로에서 12Mhz로 동작하도록 

 클럭을 변경하게되면 모든 작업들이 2배로 빨리 실행되게 됩니다.

 (그렇지만 MPU의 정해진 한계클럭이 존재하기 때문에 

 무한정 클럭을 올릴수는 없고 또한 클럭이 올라감과 더불어 소비전력도 비례하여 

 늘어나기 때문에 모바일 기기에서는 될수있으면 똑같은 작업을 하더라도 적은 클럭으로 

 작업을 수행하는 것이 유리합니다.) 

 

 

클럭의 소스로 쓰이는(클럭을 발생시킬수 있는) 부품에는 몇가지종류 또는 회로가 존재합니다.

 (다음회에는 클럭의 원천이 되는 몇 종류의 부품 또는 회로에 대해서 알아 보겠습니다)

 아두이노같이 이미 부품이 실장된 전자 회로의 경우 다음의 모양처럼 생긴 부품들을 본적이 

 있을 것입니다.  

 



 

(그림1. 세라믹 레조네이터 와 수정 크리스탈)

 

 

 

 

아두이노 uno등에서는 2종류의 클럭이 사용되고 있습니다. 

 (하나는 USB 통신용, 하나는 메인 칩용입니다.)

  



 

그림에서의 길고 흰모양의 부품이 Quartz crystal 이라고 하는것으로 비교적 정밀한

 주파수의 클럭을 얻을수 있는 부품인 반면에 ATMEGA chip 바로 위쪽의 작은 부품은 

 ceramic resonator 라 불리는 부품으로 Quartz crystal(수정발진자) 보다는 정밀도가 

 떨어지지만 RC, LC 발진회로보다는 비교적 정밀도가 높기 때문에 

 중등도 타이밍회로, 또는 정확한 타이밍이 요구되지 않는 전자 회로에서 많이 이용되는 

 부품입니다.

 

MPU에서 클럭은 명령을 수행할 때의 타이밍의 기준이 됩니다.

 MPU내부에서 명령을 가져오고 해석하여 최종적인 명령이 수행될때 각각 한클럭씩 소요가 되나

 최근의 MPU들은 명령 인식과 해석및 실행단계에 파이프라인이라는 처리과정을 거쳐서 

 - 각 파이프라인이 각각 독립적으로 작동하여- 파이프라인이 한클럭에 한꺼번에 실행됩니다.

 

 

  

 클럭   

   클럭   

           클럭   

     클럭  

    클럭

 명령을 가져옴

 명령의 해석 

 명령의 수행

 

 

 

 명령을 가져옴

 명령의 해석

 명령의 수행 

 

 

 

 명령을 가져옴

 명령의 해석

 명령의 수행

 

 

      <특정 순간>

 

 

 

 

위와 같은 과정이 무한히 반복됩니다.

 위처럼 3번째의 세로줄을 살펴보면 명령가져오고 해석과 수행이 한번에 이루어져서 

 거의 모든 명령이 한클럭에 실행이 되도록 하고 있습니다. 

 (단 MPU내에는 인터럽터 처리등의 회로가 부가되기 때문에 엄밀히는 위보다 더 많은 

 단계의 파이프라인 처리부분이 존재합니다. 

 

마찬가지로 코드의 분기명령어는 분기후 파이프라인이 재 설정되므로 이런 경우에는 명령이 

 한 클럭으로 완료되지 않습니다.)

 

 

아두이노에서 쓰이는 AVR 계열의 MPU는 레지스터 제어 명령이 1클럭에 수행이 되며 

 분기명령및 기타 메모리관련 명령은 2클럭에 수행됩니다.

 마이크로칩사의 PIC 계열의 경우에는 분기명령을 제외한 모든 명령이 4클럭에 수행이 되며 

 분기명령만 8클럭에 수행이 됩니다. 

 

(타이밍을 맞추는데는 AVR보다 PIC이 좀더 수월합니다. 하지만 PIC계열은 AVR보다 4배나 빠른 

 클럭을 사용해야 합니다.)

 

(물론 C 언어로 프로그래밍을 하는경우에는 각각 컴파일된 코드의 길이가 다르므로 

 정확한 타이밍이 요구되는 경우에는 AVR이던, PIC이던 직접 어셈블리로 

 코드를 작성하여 타이밍을 맞추어야 합니다.)

 

 MPU를 이용해서 일정한 주파수의 소리를 발생시킨다거나, 아니면 UART 시리얼 등으로 

 타 주변기기와의 통신을 하는경우에는 정확한 클럭이 필요하게 되는데, 이때 MPU는 

 클럭에서 발생된 기준클럭을 두배 혹은 세배, 아니면 n 배를 해서 기준클럭의 

 배수가 되는 더 느린 클럭을 만들어서 각종 내부 제어회로에 이용하게 됩니다.

  

MPU내부에서 클럭이 사용되는 경우는 일반적으로 다음과 같습니다.

 

UART, PWM, 카운터, 타이머

 이중 카운터 타이머의 경우에는 정해진 숫자의 값을 카운트 다운 또는 카운트 업 하여 

 정해진 숫자에 도달하면 인터럽트를 발생시켜 필요한 동작을 수행합니다.

 이렇게 하면 모든 IO 핀을 매번 모니터링 하거나 일일히 

 명령의 instruction cycle을 계산하지 않고도 정확한 시간에 정해진 작업을 수행할 수 있습니다.

 

즉 예를 들자면 아두이노등에서의 sleep명령처럼 아무일도 하지 않고 노는 시간에 다른 일을 

 할 수 있는것 입니다.

 

타이머는 대개 내부의 기준 클럭이 일정한 시간에 발생하는 클럭 펄스에 의해서 동작하며

카운터의 경우 외부의 펄스변화를 인식하여 각 펄스가 정해진 갯수가 되는 경우에 인터럽트가

발생합니다.

마찬가지로 UART의 경우에는 전송되는 데이터 값을 어느정도 시간동안 유지해야 하는지를 

결정하는데 클럭이 사용되며

PWM의 경우에는 펄스폭의 길이를 결정하는데 클럭이 이용됩니다. 

 

이때 기준 클럭보다 엄청나게 긴 시간동안의 카운팅이 일어나야 하는데 

프리스케일러라는 내부 회로를 두어서 클럭을 2배 4배 또는 심지어 256 배 정도 까지의 긴 

 

시간동안을 한 단위로 하여 타이밍을 맞추는 데 사용하고 있습니다.

 

설명을 위해서 다음과 같은 프로그램을 봅시다.

 

 

// the setup function runs once when you press reset or power the board

void setup() {

  // initialize digital pin 13 as an output.

  pinMode(13, OUTPUT);

}

 

// the loop function runs over and over again forever

void loop() {

  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)

  delay(1000);              // wait for a second

  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW

  delay(1000);              // wait for a second

}


 

 

위의 예제는 아두이노의 블링크 예제 입니다. 

 

LED를 점등하고 1초를 기다리고, 또 소등하고 1초를 기다리는 프로그램입니다.

 위 프로그램은 기다리는 동안 아두이노는 아무일도 못하고 단지 기다리기만 할 뿐입니다.

 (이러한 루프를 idle loop라고 부릅니다.)

 그렇지만 인터럽트를 이용하면 

 

 

 

// avr-libc library includes

#include

#include

#define LEDPIN 13

 

void setup()

{

pinMode(LEDPIN, OUTPUT);

// initialize Timer1

cli();         // disable global interrupts

TCCR1A = 0;    // set entire TCCR1A register to 0

TCCR1B = 0;    // set entire TCCR1B register to 0 

               // (as we do not know the initial  values) 

 

// enable Timer1 overflow interrupt:

TIMSK1 | = (1 << TOIE1); //Atmega8 has no TIMSK1 but a TIMSK register

 

// Set CS10 bit so timer runs at clock speed: (no prescaling)

TCCR1B |= (1 << CS10); // Sets bit CS10 in TCCR1B

// This is achieved by shifting binary 1 (0b00000001)

// to the left by CS10 bits. This is then bitwise

// OR-ed into the current value of TCCR1B, which effectively set

// this one bit high. Similar: TCCR1B |= _BV(CS10);

 

// enable global interrupts:

sei();

 

ISR(TIMER1_OVF_vect)

{

 

digitalWrite(LEDPIN, !digitalRead(LEDPIN));

// or use: PORTB ^= _BV(PB5);// PB5 =pin 19 is digitalpin 13

}


 

 

 

이렇게 작성할 수 있고, 뭔가 조금 복잡해 보이기는 해도 

 노는 시간동안 아두이노는 다른 유익한 일을 할 수가 있습니다.

 

 

임베디드 프로그래밍도 최적화를 잘 하면 더 상위의 MPU를 쓰지 않고도 원하는 작업이 가능합니다.

 즉 임베디드 하드웨어를 잘 이해하면 이해할 수록 효율적인 프로그래밍이 가능하다는 것입니다.

 

이야기가 길어져서 

 클럭 설명드리다가 인터럽트, 타이머까지 간단히 설명을 드리게 되었습니다.

 모든 제어회로의 기준 시간이 된다는 사실을 말씀드린것 이구요..

 

 

암튼 ..

 

결론적으로 말씀드리면 임베디드 기기에서는 클럭을 선정할때 전원의 소모, 프로그램의 수행시간, 

 그리고 심지어는 UART회로, PWM회로 타이머, 카운터의 거의 모든 회로가 영향을 받기 때문에

 기준클럭을 선정해야할 때 목적에 맞는 최적의 클럭을 선정하도록 해야 합니다.

 

  

예전에는 임베디드 프로그래밍을 할때는 UART통신을 하기 위해서 클럭이 바뀔때 마다 

 통신 제어 레지스터에 일일히 계산을 해서 계산된 값을 입력해 줘야하는 불편함이 있었습니다만

 요즘은 대개 정해진 클럭을 사용하는 상용화 제품들이 많고 (아두이노의 경우에 기준클럭은 16Mhz 

 입니다.) 또한 각 칩마다 클럭에 따라 각각의 계수들을 계산해 주는 도우미 어플리케이션이 

 많이 있어서 

 

(예를 들자면 PIC - http://www.nicksoft.info/el/calc/?ac=spbrg 

 AVR - http://wormfood.net/avrbaudcalc.php

 등의 사이트)

 

현재는 예전처럼 클럭 제어 레지스터를 직접 다루어야 하는 일은 많지 않아졌습니다.

  

이번에는 클럭을 바꿀때 프로그램도 바뀌어야 한다는 것만 알고 가시면 될것 같습니다.

  

도움이 되셨는지요 ??

  

많은 도움이 되셨기를 바라며 이번회의 강좌를 마치도록 하겠습니다.

  

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]


 

 

참고 사이트

 

 

http://www.nicksoft.info/el/calc/?ac=spbrg 

 

http://wormfood.net/avrbaudcalc.php

 

https://www.arduino.cc/en/Tutorial/Blink

 

https://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/

 

 

 

참고 부품

 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P000360693

 

http://www.icbanq.com/P001943166/S