반응형

1. GPIO방법은 간단하죠

DDRA.0=1; // out
while(1){

PORTA.0=1; delay_us(50); PORTA.0=0; delay_us(50);

}

장점 : 임의의 포트에 출력 할 수 있습니다.

단점 : 다른 코드가 존재하는 경우 주파수를 맞추기 어렵습니다.



 


2. (비교매치)타이머 인터럽트를 사용하는 방법

오버플로우 인터럽트를 사용 할 수도 있으나 비교매치 인터럽트가 정확합니다.

DDRA.0=1; // out
TCCR0=0x0B; OCR0=24; TIMSK=2; //16000000/32/(1+24)=20000Hz=50us
SREG=0x80; // sel

interrupt [TIM0_COMP] void timer0_comp_isr(void){ // 50us 주기

PORTA.0=~PORTA.0; // PA0 토글
}

장점 : 임의의 포트에 출력 할 수 있습니다.

단점 : 다른 인터럽트가 존재하는 경우 주파수 오차가 발생합니다.




3. CTC 토글모드를 사용하는 방법

DDRB.5=1; // out
TCCR1A=0x40; TCCR1B=9; TCCR1C=0x80; OCR1A=799; //16000000/ 1/(1+799)=20KHz=50us
장점 : 정확한 주파수를 출력

단점 : 특정핀에서만 출력이 가능, 50% 듀티만 가능




4. FAST PWM 출력을 사용하는 방법

DDRB=0x20; // PB5 out
TCCR1A=0x82; TCCR1B=0x1A;
// FAST PWM, 16Mhz/8분주=0.5usec
OCR1A=99; ICR1=199;
// 0.5usec*(1+199)=100usec=10KHz

장점 : 정확한 주파수를 출력, 임의의 듀티도 가능

단점 : 특정핀에서만 출력이 가능



예) AT90USB1287 OC2B 핀으로 주파수 출력

void PWM_START(void)

{

DDRD |= 0x03; // PD6 is now an output

OCR2B = 128; // set PWM for 50% duty cycle

//Output Compare Register 0~255 숫자. 127인 경우 5:5듀티임.

TCCR2A |= (1 << COM2B1); // set none-inverting mode

TCCR2A |= (1 << WGM21) | (1 << WGM20); // set fast PWM Mode

TCCR2B |= (1 << CS22)|(1 << CS21)|(0 << CS20); // set prescaler to 64 and starts PWM

}

void PWM_STOP(void)

{

TCCR2A = 0x00; //Normal port operation, OC2 disconnected

DDRD &= ~0x03;

}




예) Atmega329pa pwm test OC1A 핀으로 주파수 출력

void fnInit_Timer(void) //100msec //OK

{

//Clear OC1A/OC1B on Compare Match (Set output tolow level).

//MODE:Fast PWM, 9-bit

//TOP:0X01FF

//clkI/O/8 (From prescaler)


TCCR1A=0x82; TCCR1B=0x19; // 1Mhz = Fast PWM, 9-bit

OCR1AL=124; ICR1L=249; // 1M / 4K(부저주파수) = 250이며 0부터 시작이기 때문에 (250-1)

}



위에서 1+799 라든가 1+199라고 적은 것은

0~799, 800

0~199, 200

0~99, 100

카운터가 0부터 시작하기 때문에 1 적은 수를 넣어줘야지 정확한 카운트가 됩니다.

다른 종류PWM이 한가지 더 있지만 생략합니다.


반응형

+ Recent posts