본문 바로가기
공부,일/atmega328P

atmega 328p PWM & timer counter (4) 실습 (Normal mode)

by fromnothing1 2021. 7. 27.

1. Normal Mode 

1 초마다 13pin 에 출력을 주는 코드를 만들어 보자 

 

cpu 클럭수는 16Mhz 이고 기본 분주비는 64 로 사용하겠다. 

 

출처 https://blog.naver.com/alsrb968/220867860815

일단 1 ms 마다 overflow 가 발생하도록 하기 위해서는 

위의 그름을 보면 n = 250 이여야 한다. 

 

따라서 초기 값은 6 으로 해주면 6 - 255 =249

255 -> 0 으로 바뀔때   overflow 인터럽트가 동작하므로 딱 250 클럭이 된다. 

 

즉 1초마다 불빛이 들어 오기 위해서는 1000 번 overflow 가 발생하면 된다. 

 

추가 셋팅 

timer0 의 경우 아두이노에서 pwm 용으로 사용하기 위해서 overflow 인터럽를  <wiring.c> 에다가 정의 해 놨다 

때문에 ISR()을 사용할 경우 중복 정의 오류가 발생한다. 

 

때문에 <wiring.c> 에서 overflow 인터럽트 정의 부분을 #ifndef 를 이용해서 _DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_ 가 정의 되어 있다면 미리 정의 하지 않게 수정 해야 된다. 

<wiring.c>

빨간 네모 박스 부분 추가 해야됨  

 

wiring.c 위치 

C:\Users\ad\Desktop\ARDUINO\arduino-1.8.15\hardware\arduino\avr\cores\arduino

 

나는 아두이노 바탕화면 ARDUINO 안에다가 깔아서 저럼 

 

 

1초마다 깜빡거리는 코드 

#define _DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_
#include <wiring.c>

volatile  uint16_t count = 0;
char toggle = 1;

void setup()
{
  pinMode(13, OUTPUT);
  TCNT0 = 0x06;
  TCCR0A = 0x00; // 노멀모드 초기화 
  TCCR0B = 0x03; //분주비 64
  TIMSK0 = 0x01; // overflow 인터럽트 발생가능
  sei(); // 인터럽트 사용
}

void loop() 
{
 
}


ISR(__vector_16)
{
    count++;
  
      if(count>999)
      { 
        if(toggle)
        {
         digitalWrite(13,HIGH);
         toggle = 0;
        }
        else 
        {
          digitalWrite(13,LOW);
          toggle = 1;
        }
        count=0;
      }
      TCNT0 = 0x06;
}

 

댓글