Ultraschallsensor AVR

Gast #2641936
Lesenswert?

Hallo, Ich habe einen Ultraschallsensor aufgebaut. Das 
Ultraschallsendesignal wird bei jedem Timer overflow gesendet(geht 
auch). Wenn die Empfänger Kapsel Signal sieht zieht sie den INT0 auf 1 
(Es liegt eine 1 An ab dem Sendezeitpunkt bis kein Signal mehr gesehen 
wird, funktioniert ebenfalls) Der Interrupt darf nur auf die erste 
fallende Flanke reagieren und dann bis zum nächstem Senden nicht mehr 
auf Flanken reagieren. Je nachdem welche Zeit ermittelt wird sollen die 
LED's angesteuert werden.

out = PD2 die Ansteuerung für das Senden
Out = PB0-7 LED's
IN = PC2 High wenn Signal empfangen wird low bei keinem Signal.

Allerdings funktioniert das ganze nicht wirklich... vill. hat ja jemand 
eine Idee oder einen Verbesserungsvorschlag zu dem bestehendem Programm.
danke.


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#define P_ENABLE_HIGH  PORTD |= (1<<PD2);
#define P_ENABLE_LOW  PORTD &= ~(1<<PD2);

#define INT0_ENABLE    EIMSK  |= (1<<INT0);
#define INT0_DISABLE  EIMSK  &= ~(1<<INT0);
#define true   1
#define false   0
volatile uint8_t Merker;
volatile unsigned char c;

ISR (INT0_vect)                      //Interrupt0
{

  c = TCNT0;

  if ( c < 15 )
  {
    PORTB   = 0b00000001;
  }
  else if ( c < 44 )
  {
    PORTB   = 0b00000011;
  }
  else if ( c < 76 )
  {
    PORTB   = 0b00000111;
  }
  else if ( c < 108 )
  {
    PORTB   = 0b00001111;
  }
  else if ( c < 140 )
  {
    PORTB   = 0b00011111;
  }
  else if ( c < 172 )
  {
    PORTB   = 0b00111111;
  }
  else if ( c < 204 )
  {
    PORTB   = 0b01111111;
  }
  else if ( c <= 255)
  {
    PORTB   = 0b11111111;
  }

}
ISR (TIMER0_OVF_vect)                  {
  Merker ^= true;                    }

int main (void)                 {
   DDRC  = 0b00000000;
  DDRD  = 0b00000100;
     DDRB    = 0b11111111;
     PORTB   = 0b00000000;
   EICRA  = 0b00000011;
         TCCR0A = 0;
  TCCR0B = 0b00000101;
  TIMSK0 = 0b00000001;
  Merker = 0;              sei();

  while(true)                 {
    wdt_reset();
    if (Merker == true)            {
    P_ENABLE_HIGH;

      INT0_DISABLE;
    }
    else                {
      P_ENABLE_LOW;
      if (TCNT0 > 5 && TCNT0 <128)               {
        INT0_ENABLE;
                            }
      else
      {
        INT0_DISABLE;              }
    }

   }
   return 0;                               }
Gast #2641959
Lesenswert?

Erstens, nimm Code-Tags, außerdem gewöhn' Dir die Binär-Schreibweise ab, 
die ist hier nicht angebracht.

Und ohne jetzt geschaut zu haben ob der Code überhaupt funktionieren 
kann, muss man beim (wieder-)erlauben von Interrupts darauf achten, dass 
man die in den entsprechenden Flag-Registern evtl. gesetzten Flags 
vorher löscht.

Sonst löst ein "gemerkter" Interrupt sofort zu dem Zeitpunkt aus, an dem 
er wieder erlaubt wird. Das kann die ganze Mechanik 
durcheinanderbringen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren