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이 한가지 더 있지만 생략합니다.
'Study > 8-bit MCUs' 카테고리의 다른 글
코드비젼/ AVR EDIT/ ICC/ AVRSTUDIO/ IAR/ 컴파일러 변경시 참조 (0) | 2015.06.11 |
---|---|
pwm duty (0) | 2015.06.11 |
Atmega128 타이머 참고 (0) | 2015.06.09 |
스위치를 이용한 led제어 소스코드 (0) | 2015.06.09 |
Atmega8a - Timer/Counter 레지스터 (0) | 2015.06.08 |