본문 바로가기

AVR

[AVR] PWM LED dimming 제어

/*
 * MAKE_TIME0_PWM.c
 *
 * Created: 2022-08-11 오후 1:11:25
 * Author : kcci
 */ 

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>   // printf, scanf등이 정의 되어 있다.
#include <string.h>  // strcpy, strncmp, strcat 등이 들어 있다.

// 16.4ms 마다 이곳으로 진입 
volatile int tim_16ms =0;
ISR(TIMER0_OVF_vect)
{
	TCNT0 = 0;  // 주의 CTC아닌 경우는 반드시 초기화 해 줘야 한다. 
	tim_16ms++;
}
// OC0 : PWM 파형 출력 신호 PB.4 으로 출력을 설정 
init_timer0_pwm()
{
	// 파형 출력 핀 PB.4(OC0)을 출력으로 설정
	DDRB |= (1 << 4);   // 상향카운터만 존재하는 고속 PWM로 동작하도록 설정
	// 타이머/카운터 0번을 고속 PWM 모드로 설정
	TCCR0 |= (1 << WGM01) | (1 << WGM00); // P344 표 15-3
	// 비반전 모드 OCR --> LOW
	TCCR0 |= (1 << COM01); // P344 표 15-4
	// 분주비를 1024 16000000/1024(분주비) : 15625HZ 
	// 15625HZ 에서 1펄스 의주기 : t = 1/f 1/15625 ==> 0.000064sec (64us)
	//  0.000064sec (64us) x 256 = 16.4ms  16.4ms마다 TImer0 Overflow INT 발생 
	TCCR0 |= (1 << CS02) | (1 << CS01) | (1 << CS00);
    TIMSK |= (1 << TOIE0);   // 타이머 0 overflow INT 설정 
	TCNT0 =0;
}
int main(void)
{
#if 0 // 어두워졌다가 밝아지게
	int dim=0;  //밝기
	int direction=1; 
	
	init_timer0_pwm();
	sei();
	
	OCR0 = dim;
    while (1) 
    {
		 // duty cycle 설정: 1클럭 64us
		 // 초기 OCR0:1(64us) 부터 OCR0:255(16.4 ms)까지 
		 // 16.4ms단위로 서서히 밝아 지도록 한다 OCR0: 0==>255
		 if (tim_16ms >= 1)
		 {
			 tim_16ms =0;
			 OCR0 = dim;
			 dim += direction;   // 밝기 변화 
		 }
    }
#else
	int dim=255;  //밝기
	int direction=-1;
	
	init_timer0_pwm();
	sei();
	
	OCR0 = dim;
	while (1)
	{
		// duty cycle 설정: 1클럭 64us
		// 초기 OCR0:1(64us) 부터 OCR0:255(16.4 ms)까지
		// 16.4ms단위로 서서히 밝아 지도록 한다 OCR0: 0==>255
		if (tim_16ms >= 1)
		{
			tim_16ms =0;
			OCR0 = dim;
			dim--;
			dim += direction;   // 밝기 변화
		}
	}
#endif
}

 

 

0323.mp4
1.72MB