학습목표    1

학습주제    1

예습내용    1

실습방법    1

        1

PWM1(16비트)

학습목표

타이머/카운터1” 이용해 사각펄스(PWM1) 만든다. 이를 PC에서 RS232 이용해 주기(hz) 듀티(Duty) 조절한다.

학습주제

내용은 AVR Atmega128 마스터, 윤덕용, Ohm, P517~P523 참조 하였습니다.

16bit Phase Correct PWM Mode 펄스를 만든다. 출력은 PB6포트 이다.

[AVR 프로그램 내려받기]

[PC 프로그램 내려받기]

예습내용

Atmega128(L) 데이터북 P125~P140 참조한다.

원하는 펄스를 얻기 위해서 TCCR1A, TCCR1B 결정하고 Hz duty 따라 OCR1A, OCR1B 결정한다.

레지스터 TCCR1A=0x21 다음과 같이 구성된다. (데이터북 P129)

7

6

5

4

3

2

1

0

COM1A1

COM1A0

COM1B1

COM1B0

COM1C1

COM1C0

WGM11

WGM10

0

0

1

0

0

0

0

1

Compare Output Mode for Channel A

(OC1A)PB5

Compare Output Mode for Channel B

(OC1B)PB6

Compare Output Mode for Channel C

(OC2/OC1C)PB7

Waveform Generation Mode

Table 60

Table 60

Table 60

Table 61

2

1

여기 실험에서는 PB6(OC1B) 결과를 출력한다.

 

레지스터 TCCR1B=0x13 다음과 같이 구성된다. (데이터북 P132)

7

6

5

4

3

2

1

0

ICNC1

ICES1

-

WGM13

WGM12

CS12

CS11

CS10

0

0

0

1

0

0

1

1

아래참조

아래참조

아래참조

Waveform Generation Mode

Clock Select

 

 

 

Table 61

Table 62

1

3

Bit7 – ICNCn: Input Capture Noise Canceler

Bit6 – ICESn: Input Capture Edge Select

Bit5 – Reserved Bit

 

Table 60 (데이터북 P131)

COMnA1/COMnB1/

COMnC1

COMnA0/COMnB0/

COMnC0

 

0

0

Normal Port Operatio, OCnA/OCnB/OCnC

disconnected

0

1

WGMn3=0: Normal port operation,

OCnA/OcnB/OCnC disconnected.

WGMn3=1: Toggle OcnA on compare

Match, OCnB/OCnC reserved.

OCnA/OcnB/OCnC disconnected.

1

0

Clear OCnA/OCnB/OCnC on compare

Match when up-counting. Set

OCnA/OCnB/OCnC on compare match

when downcounting.

1

1

Set OCnA/OCnB/OCnC on compare match

when up-counting. Clear

OCnA/OCnB/OCnC on compare match

when downcounting.

 

Table 61 (데이터북 P132)

Mode

WGMn3

WGMn2

(CTCn)

WGMn1

(PWMn1)

WGMn0

(PWMn0)

Timer/Counter Mode of

Operation

TOP

Update of

OCRnx at

TOVn Flag

Set on

9

1

0

0

1

PWM, Phase and

Frequency Correct

ICRn

BOTTOM

BOTTOM

 

Table 62 (데이터북 P133)

CS02

CS01

CS00

 

0

0

0

No clock source (Timer/Counter stopped)

0

0

1

ClkTOS/1 (No prescaling)

0

1

0

ClkTOS/8 (Form prescaler)

0

1

1

ClkTOS/64 ( Form prescaler)

1

0

0

ClkTOS/256 ( Form prescaler)

1

0

1

ClkTOS/1024 ( Form prescaler)

1

1

0

External clock source on pin. Clock on falling edge

1

1

1

External clock source on pin. Clock on rising edge

아래 그림은 Hz,Duty 결정하면N,OCR1AH,OCR1AL,OCR1BH,OCR1BL 결정하여 이를 AVR 보내어 필요한 펄스를 만드는 프로그램이다.

 

실습방법

   

1. 주기조절

 

PWM 주기는 아래와 같이 계산된다. (데이터북 P127)

N “Table62”에서 결정하고 원하는 주기를 결정하면 윗식에서 TOP 값이 결정된다. 이를 OCR1A 저장한다.

여기서 OCR1A 16비트 값이므로 0~216 사이의 값이 되도록 N 적절하게 선택해야 한다.

 

2. 듀티조절

펄스의 듀티는 OCR1A 해당 duty 곱하여 이를 OCR1B 값을 정하면 원하는 플스를 얻을 있다..

 

3. PC프로그램

다음은 펄스를 만드는 프로그램 이다.

예제1 Hz,Duty에서 N,OCR1A,OCR1B 결정하여 송신 프로그램

CString strTemp;

double periodD,dutyD;

unsigned short period,duty;

char OCR1AH,OCR1AL,OCR1BH,OCR1BL;

char cClock; // 0x30=1024 0x31=256 0x32=64 0x33=8 분주

 

cClock = 0x30;

periodD=(int)(7812.5/m_hz.Value);                      // 1024분주  

if(periodD < 200) {

              cClock = 0x31;

              periodD=(int)(31250/m_hz.Value);         // 256분주 

}

if(periodD < 200) {

              cClock = 0x32;

              periodD=125000/m_hz.Value;                                           // 64분주  

}

if(periodD < 200) {

              cClock = 0x33;

              periodD=(unsigned int)(1000000/m_hz.Value);                  // 8분주  

}

 

m_cClock.Value = cClock;

 

dutyD = (unsigned short)(periodD*m_duty.Value/100);

period = (unsigned short)periodD;

duty = (unsigned short)dutyD;

 

m_periodD.Value = periodD;

m_dutyD.Value = dutyD;

 

OCR1AH = (period>>8);

OCR1AL = period & 0xff; 

OCR1BH = (duty>>8);

OCR1BL = duty & 0xff;

// 해당 데이터를 RS232 보냄

strTemp.Format( "%c%c%c%c%c%c%c",0x02,cClock,OCR1AH,OCR1AL,OCR1BH,OCR1BL,0x03);

m_ComuPort.WriteComm((unsigned char*)(LPCTSTR)strTemp,7);

 

 

4. AVR 프로그램

예제1”에서 RS232 전달된 문자는 rx_buffer0 [0]배열부터 차례로 저장된다.

예제2 N,OCR1A,OCR1B 결정하는 프로그램

if(rx_buffer0[0]==0x02) {

              switch(rx_buffer0[1]){

                             case 0x30:            

                                           TCCR1B=0x15;      // 1024분주

                                           break;

                             case 0x31:            

                                           TCCR1B=0x14;      // 256분주

                                           break;

                             case 0x32:            

                                           TCCR1B=0x13;      // 64분주

                                           break;

                             case 0x33:            

                                           TCCR1B=0x12;      // 8분주

                                           break;

              }

 

              OCR1AH = rx_buffer0[2];

              OCR1AL = rx_buffer0[3]; 

              OCR1BH = rx_buffer0[4];

              OCR1BL = rx_buffer0[5];

}

[전체 프로그램 보기]

 

처음