J 창고

[Atmega128] Fast PWM with LED 본문

컴퓨터/Firmware

[Atmega128] Fast PWM with LED

JSFamily 2015. 1. 5. 14:40







Fast PWM을 활용하여 LED 점등을 구현해봄








위의 영상 같이 LED가 점점 밝아짐을 확인해 볼 수 있다









Fast PWM은 기본적으로 톱니바퀴(?) 방식으로 카운트를 하는데


카운트를 하면서 OCRn 레지스터와의 비교를 통해


Compare Match가 되면 인터럽트가 발생하고 OCn Output을 Toggle 한다.


TCNTn의 카운트가 0xFF가 되거나 Interrupt가 발생했을 때 OCn Output을 초기상태로 리셋해준다.





 Fast PWM과는 다르게 Phase Correct PWM은




TCNTn 카운트를 처음엔 Up카운트를 하고 그 이후에 Down카운트를 한다.


인터럽트는 최고 카운트 0xFF가 되었을 때 나오고 


최하 카운트 0x00에서는 TOVn Interrupt Flag가 셋 된다.


이와중에 OCRn 레지스터와 값을 비교하여 같아지면 Interrupt가 발생하고


OCn Output이 Toggle 된다.






Fast PWM과 Phase Correct PWM과의 차이는 


Fast PWM은 높은 주파수의 PWM에서 사용하고


Phase Correct PWM은 높은 분해능을 필요로 하는 곳에서 사용하는데서 차이가 난다,






여기서 OCn Output으로 파형을 출력할지 말지에 대한 것과 이 출력을


전시킬지에 대한 것을 셋팅하는 레지스터가 있는데


아래의 Table 54. 에 나와있듯이


TCCR0 레지스터 안에 COM0 [1:0] 에서 설정할 수가 있다.













뭐 회로도는 거창한 것은 없고 아래와 같이 연결하여


PWM 듀티비를 PORTD에 연결된 LED 게이지를 통해 확인할 수 있다.

(LCD 또는 UART 통신을 아직 하질 않아서.. ㅎㅎㅎ)




8 Bit Timer/Counter를 사용하여 하드웨어 PWM을 사용


그래서 TCCR0 = 0x6A 를 줌


F = 16MHz/(N *256),  N = 8 prescaler


따라서 f = 7.8125KHz, T = 128usec


PWM 주기는 128usec 가 된다.








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
 * PWMGenerator.c
 *
 * Created: 2015-01-05 오후 1:14:01
 *  Author: user
 */ 
 
 
#include <avr/io.h>
#include <util/delay.h>
 
void pwm0_out(unsigned char duty){
    OCR0 = duty;
}
 
int main(void)
{
    unsigned char number;
    unsigned char led[9] = {
        0b00000000,
        0b00000001,
        0b00000010,
        0b00000100,
        0b00001000,
        0b00010000,
        0b00100000,
        0b01000000,
        0b10000000
    };
    
    DDRD  = 0xFF;
    PORTD = 0x00;
    
    DDRB  = 0xFF;
    PORTB = 0xFF;
        
    TCCR0 = 0x6A;
    TCNT0 = 0x00;
    OCR0  = 0x00;
        
    while(1)
    {
        for( number = 0 ; number < 256 ; number++ ){
            pwm0_out(number);
            _delay_ms(100);
            PORTD = led[number/28];
        }
    }
}
cs


Comments