Micom_Electric/마이컴_원칩 2011. 5. 15. 14:06
Duty 제어법
=== 블로그에서 ===
http://blog.naver.com/mmxtechn?Redirect=Log&logNo=140129718074

==까페에서 =============
http://search.naver.com/search.naver?sm=tab_hty&where=nexearch&query=fast+pwm&x=0&y=0

http://cafe.naver.com/circuitsmanual.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=5142&
====================-===
 // 20KHz 50% PWM OCR1B 출력
main(void){
    DDRB = 0XFF;
    TCCR1A = 0X22;
    TCCR1B = 0X19;
    OCR1B = 0X031F/2;
    ICR1= 0X31F;
    TCNT1 = 0XFCE1;
    sei();

    while(1){ }
}
 
위 코드에 대한 설명을 요구 하는 지식인 질문에 대한 답글입니다.
//===========================================================
PWM은 동작 모드 부터 확인 해야 합니다.
http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf
상기 데이터시트를 여세요

타이머 모드를 결정 하는 레지스터인 TCCR1B로 검색 해보죠
몇번 클릭만에 Table 61. Waveform Generation Mode Bit Description 이것을 찾았습니다.
135페이지를 일단 적어 두시고
찾기를 더 클릭 합니다.
TCCR1B  ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
TCCR1B = 0X19; // 0001 1001 // WGM13=1, WGM12=1
모드를 결정 하는 WGMxx 중에서 두개는 찾았고 두개만 더 찾으면 되는군요
마우스로 조금 올리니까 TCCR1A에 두개가 더 있군요
TCCR1A = 0X22 = 0010 0010
TCCR1A  COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
 WGM11=1, WGM10=0
 
135페이지 Table 61. Waveform Generation Mode Bit Description 에서 모드를 보면
모드14 - Fast PWM 모드군요
Timer/Counter Mode of Operation - Fast PWM 
TOP - ICR1 // TCNT1  카운팅 하는 꼭대기 값은 ICR1레지스터의 값
Update of OCR1x at - BOTTOM // OCR1x 값을 변경 하면 언제 적용 되는지, BOTTOM 시 적용 됨
TOV1 Flag Set on - TOP // 타이머 오버플로우 플래그는 TOP 값에서 세트 됨

모드는 다 체크 한거 같고
TCCR1A  COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C WGM11 WGM10
COM1A1 COM1A0 = 00 // Normal port operation, OC1A disconnected.
COM1B1 COM1B0 = 10 // 아래 설명
COM1C1 COM1C0 = 00 // Normal port operation, OCnC disconnected.

Table 59. Compare Output Mode, Fast PWM를 보면
COM1B1 COM1B0 = 10 조건은
Clear OC1A/OC1B/OCnC on compare match,  // OC1B와 같으면 Clear(0)
set OC1A/OC1B/OCnC at BOTTOM, (non-inverting mode) // BOTTOM에서 set(1)

TCNT1의 클럭 분주비 CS12 CS11 CS10 보러 TCCR1B로 다시 가죠
TCCR1B = 0X19; // 0001 1001
Table 62. Clock Select Bit Description
clkI/O/1 (No prescaling)
분주비는 1입니다. 128이 16MHz 클럭이면 TCNT1 타이머도 16MHz 클럭으로 움직입니다.
TOP = ICR1= 0X31F=799
OCR1B = 0X031F/2 = 799/2 = 399; 
TCNT1이
0부터 증가를 하다가 399(OCR1B)를 되면 PWM 출력OC1B = 0
계속해서 400부터 증가를 하다가 799(ICR1)가 되면 오버플로우 하면서 0이됨 PWM 출력OC1B = 1
위 과정 반복
TCNT1 = 0XFCE1 = 64737 ;// 65536-64737 = 799
TCNT1이 0XFCE1부터 증가해서 오버플로우 하게되면 PWM 출력OC1B = 1이 되고
PWM 과정을 시작 함

PWM주파수

TCNT1클럭(분주비1,16MHz) / ICR1
16000000Hz/800 = 20000Hz = 20KHz

PWM 출력OC1B 을 위해서 포트B는 출력으로 설정 했군요
DDRB = 0XFF;  

ICR1 값을 바꾸면 PWM 주파수가 바뀌고
OCR1B 값은 듀티를 바꾸는 겁니다.

PWM은 듀티를 바꾸는 것이므로
주파수가 한번 결정되면 ICR1 값을 바꿀일 없이
OCR1B 값만 바꿔서 듀티를 정하겠군요

PWM 3개 출력으로 모두 사용 하려면
TCCR1A 설정에서 OC1A, OC1C 도 OC1B와 똑같이 설정 해 줍니다.
 
ICR1= 0x31F; //0x31F는 0~799입니다.
OCR1A,OCR1B,OCR1C 모두 0~799로 설정 해주면 PWM출력이 나갑니다.

posted by 털보네i
: