Did you know that you can navigate the posts by swiping left and right?
인터럽트 개념을 배웠고 그 다음으로 타이머/카운터를 이용하는 것을 배웠는데 이를 이용하기 위해서 어떤 모드를 사용할 것인지를 우선적으로 생각하고 코딩을 해야했다. 이 모드에는 일반모드, CTC모드, Fast PWM모드, PC PWM모드가 있는데 나는 주로 일반모드와 CTC모드를 사용했는데 TCNTx로 인터럽트 주기를 정해주고 OCRx(비교값)로 어느지점에서 조건을 또 수행할지 정해준다. 제어, 마스크, 상태 레지스터는 전에 배운대로 지정해주고 이렇게 자신이 원하는 타이머를 쓸 수 있게 된다.
이후에 직접 서보모터를 테스트보드에 연결해 모터를 돌려보았는데 신호선은 PORTC에 연결해 PORTC = HIGH와 PORTC = LOW로 모터수행을 할 수 있도록 하였다. 초기에 특정한 값을 지정해주고 임의의 변수로 증가값을 받는 변수를 지정해줘서 두 값을 비교하면서 위의 HIGH와 LOW로 모터를 돌려준다. (이건 익숙해질때까지 직접 코딩해보는게 좋을 것 같다.)
다음은 avr책에서 본 코딩을 내 test board에 맞게 코딩해본것이다.
#include <mega128.h>
#include <delay.h>
#include <alcd.h>
#define Switch_1 (!PINE.4)
#define Switch_2 (!PINE.5)
#define Switch_3 (!PINE.6)
unsigned int tim0_cnt, mot_pos, change;
unsigned int rc_time[3] = {56, 152, 252};
void main()
{
DDRC = 0xFF; //포트 C 출력 설정
tim0_cnt = 0; //타이머/카운터0 오버플로우 횟수 리셋
mot_pos = 0; //모터 위치 = 0도
change = 0; //각도 변화 주기 리셋
TIMSK = 0x01; //TOIE0 = 1;
TCCR0 = 0x02; //일반모드, 프리스케일 = CK/8
TCNT0 = 238; //타이머/카운터0 레지스터 초기값
SREG = 0x80; //전역 인터럽트 인에이블 비트 셋
tim0_cnt = 0;
PORTC = 0xFF; //모터 HIGH 출력
while(1)
{
if(tim0_cnt >= 2000)
{
tim0_cnt = 0;
PORTC = 0xFF; //모터 HIGH 출력
change++;
if(change == 100)
{
mot_pos = (mot_pos + 1) % 3;
change =0;
}
}
if(tim0_cnt >= rc_time[mot_pos]) PORTC = 0x0; // 모터 LOW 출력
}
}
interrupt [TIM0_OVF] void timer_int0(void)
{
tim0_cnt++;
TCNT0 = 238;
}
출처: 알기쉽게 배우는 AVR Atmega 128