공부,일/atmega328P

my 초음파 센서 만들기

fromnothing1 2021. 9. 15. 15:51

1. 외부 인터럽트


INT0 번 2번핀  change 인터럽트시 

falling edge 인터럽트 

void setup() {
  // put your setup code here, to run once:
  cli();
  DDRD = DDRD | (1<<7)| (1<<6)| (1<<5);
  EIMSK = EIMSK|1; // INT0 인터럽트 허용
  EICRA = EICRA|(1<<1)&(~1); 
  sei();
}

void loop() {
  // put your main code here, to run repeatedly:

}

int togle = 1;

ISR(__vector_1)
{
  if (1 == togle )
  {
    PORTD = (1<<7);
    togle = 0;
  }
  else
  {
     PORTD = (1<<6);
     togle = 1;
  }
    

}

change 인터럽트

void setup() {

  cli();
  DDRD = DDRD | (1<<7)| (1<<6)| (1<<5);
  EIMSK = EIMSK|1; // INT0 인터럽트 허용
  //EICRA = EICRA|3;  // rising
  //EICRA = EICRA|(1<<1)&(~1); // falling
  //EICRA = EICRA&0; // lowlevel
  EICRA = EICRA|1;
  sei();
}



void loop() 
{
}
int togle = 1;

ISR(__vector_1)
{
  if (1 == togle )
  {
    PORTD = (1<<7);
    togle = 0;
  }
  else
  {
     PORTD = (1<<6);
     togle = 1;
  }
}

 

 

falling , rising change 인터럽트


void setup() {
  // put your setup code here, to run once:
  cli();
  DDRD = DDRD | (1<<7)| (1<<6)| (1<<5);
  EIMSK = EIMSK|1; // INT0 인터럽트 허용
  EICRA = EICRA|3; //상승
  sei();
}

void loop() {}

ISR(__vector_1)
{
  if(1 == (EICRA&1))
  {
    PORTD = (1<<7);
    EICRA = (EICRA|(1<<1))&(~1);
  }
  else
  {
    PORTD = (1<<6);
    EICRA = EICRA|3; 
  }
}

2. tiemr , timer 2 로 1초마다 7번 6번 번갈아서 LED 출력 

volatile  uint16_t count = 0;
char toggle = 1;

void setup()
{
  cli();
  DDRD =DDRD |(1<<7)|(1<<6)|(1<<5);
  //ASSR = ASSR|(1<<5);
  while(ASSR&(1<<4));// register is bussy?
  TCNT2 = 0x06;
  while(ASSR&(1<<0)); // register is bussy?
  TCCR2A = 0x00; // 노멀모드 초기화 
  TCCR2B = 0x04; //분주비 64
  TIMSK2 = 0x01; // overflow 인터럽트 발생가능
  sei(); // 인터럽트 사용
}

void loop() 
{
}

ISR(__vector_9)
{
    count++;
      if(count>999)
      { 
        if(toggle)
        {
         PORTD = (1<<7);
         toggle = 0;
        }
        else 
        {
          PORTD = (1<<6);
          toggle = 1;
        }
        count=0;
      }
      while(ASSR&(1<<4));
      TCNT2 = 0x06;
}

 

burst delay ( 10us 지연 timer 0 사용 )

 

unsigned int count = 0;
unsigned int tick = 0;
unsigned int clck = 0;
volatile unsigned int flag = 1;

void setup()
{
  init_timer2();
  init_externINT();
  DDRD = (1<<7); // 7번을 trigger 로 사용
  DDRD = DDRD|(1<<6)|(1<<5);
  Serial.begin(9600);
}

void init_timer2()
{
  cli();
  while(ASSR&(1<<0)); // register is bussy?
  TCCR2A = 0x00; // 노멀모드 초기화 
  TCCR2B = 0x04; //분주비 64
  TIMSK2 = 0x01; // overflow 인터럽트 발생가능
  sei(); // 인터럽트 사용
}

void init_externINT()
{
    cli();
    EIMSK = EIMSK|1; // INT0 인터럽트 허용
    EICRA = EICRA|3; //상승
    sei();
}

unsigned int distanceCalulate()
{
  clck = 0;
  tick = 0;
  PORTD = PORTD|(1<<7);
  delayMicroseconds(10);
  PORTD = PORTD &(~(1<<7));
  while(flag); // echo 대기
  flag = 1;
  return (clck*14 + tick*3482) ;
}


void loop() 
{
  unsigned int result;
  result = distanceCalulate();
  Serial.print(result/100);
  Serial.print(".");
  Serial.print(result%100);
  Serial.println(" cm");
  delay(1000);
}

ISR(__vector_1)
{
  if(1 == (EICRA&1))
  {
    EICRA = (EICRA|(1<<1))&(~1);
    while(ASSR&(1<<4));
    TCNT2 = 0; // 카운터 0 으로초기화
    count = 0;
  }
  else
  {
    
    flag = 0;
    tick = count;
    clck = TCNT2;
    EICRA = EICRA|3; 
  }
}

ISR(__vector_9)
{
    count++;
}