Forum: Compiler & IDEs tiny24 analog comparator input capture resetet mc


von Reinhold B. (kangarnix)


Angehängte Dateien:

Lesenswert?

Hallo,

ich wollte mit dem tiny24 eine Ultraschall-Entfernungsmesser bauen, der 
über den i2c bus abgefragt werden kann.
Für den i2c-bus benutze ich die dateien aus diesem beitrag: 
Beitrag "TWI Slave mit USI AVR312"
I2c funktioniert.
Synchronisation erfolgt über Interrupt0. Signal ist mit nem Oszi zu 
erkennen.
Ultraschall Signal wird vom Empfänger auch detektiert. Gibt ein schönes 
deutliches Signal. der MC reagiert aber nicht wie erwartet.

ich habe zum Fehlersuchen 2 Led auf der platine (PA0 und PA3)
1
/*Wenn Reset Flag gesetzt Lampen an*/
2
if ( MCUSR & (1<<WDRF) )
3
{
4
  PORTA &= ~(1<<PA3);//test led setzen
5
  PORTA |= (1<<PA0); 
6
}
7
if ( MCUSR & (1<<BORF) )
8
{
9
  PORTA |= (1<<PA3);//test led setzen
10
  PORTA &= ~(1<<PA0); 
11
}
12
if ( MCUSR & (1<<EXTRF) )
13
{
14
  PORTA &= ~(1<<PA3);//test led setzen
15
  PORTA &= ~(1<<PA0); 
16
}
17
if ( MCUSR & (1<<PORF) )
18
{
19
  PORTA |= (1<<PA3);//test led setzen
20
  PORTA |= (1<<PA0); 
21
}
22
  MCUSR &= ~ ((1<<WDRF) | (1<<BORF) | (1<<EXTRF) | (1<< PORF)); //Flags wieder löschen

Damit sollten ja beide LEDs angehen wenn es ein einfacher Power down 
Reset war.
1
void AC_Initialise(void)
2
{
3
//Analog Comparator
4
  ACSR |= (1<<ACI); // Interrupt Flag clearen
5
6
  ACSR   |= (1<<ACIS1)    // Output Rising Edge
7
    | (1<<ACIS0)   // Output Rising Edge
8
    | (1<<ACIC);  // Input Capture Timer1
9
10
  //nach sei(); noch ACSR |= (1<<ACIE) zum Enablen
11
  
12
  //     PORTA &= ~((1<<PA0) | (1 << PA3) | (1 << PA7)); //alle test Led löschen
13
14
//Timer1  
15
  TCCR1B |= (1 << CS11); //Prescaler = 8   //Timer läuft
16
17
  TIFR1 |= (1<<ICF1) | (1 << TOV1); // Input Capture Flag + Timer overflow flag clearen // Pending interrupts beenden
18
  TIMSK1 |= ((1<<ICIE1) | (1<<TOIE1)) ; //Input Capture Interrupt enable + timer overflow interrupt enable  
19
20
  //Timer reseten
21
  TCNT1 = 0;
22
  
23
  PINA = _BV(PA3);//test led togglen
24
}

dieser Aufruf soll PA3 toggeln also led2 auschalten
1
ISR(ANA_COMP_vect)
2
{
3
  Timestamp = 53; //ICR1;
4
  dataInTimestamp = TRUE;
5
6
//  PORTA &= ~(1<<PA3);//test led löschen
7
  PINA = _BV(PA0);
8
}
Das ist meine Interrupt-Routine für den Input Capture Interrupt. Sobald 
die auslöst soll (PA0) led1 toggeln, um festzustellen, dass es 
tatsächlich aufgerufen wurde.

Problem:
Wenn ich die Spanung anschließe, leuchten beide leds auf //OK
Led2 geht ganz kurz danach aus //OK
empfange ich ultraschall und das synchronisationssignal, leuchtet led2 
kurz wieder auf //Fehler, hat der MC sich gerade resetet?

ich lese mit dem i2c-master immer nur 52 aus.
demnach immer overflow?
weshalb leuchtet die led kurz auf?

hab diesen beitrag bei meiner fehlersuche gefunden
Beitrag "Kein Zugriff auf globale Variable im Interrupt"
das ist das erste projekt mit dem gcc und nem tiny24 von mir.

Würde mich freuen wenn mir jemand weiterhelfen kann.

von Johannes M. (johnny-m)


Lesenswert?

Reinhold B. wrote:
> Das ist meine Interrupt-Routine für den Input Capture Interrupt.
Nö. Das ist der Handler für den Analog-Komparator-Interrupt und nicht 
für Input Capture. Da der Capture-Interrupt freigegeben ist, nicht aber 
der Analog-Komparator-Interrupt, vermute ich mal, dass Du da irgendwo 
ganz gewaltig durcheinander geraten bist.

BTW:
Ein Reset deutet darauf hin, dass tatsächlich ein Interrupt freigegeben 
sein könnte, für den kein Handler existiert.

von Reinhold B. (kangarnix)


Lesenswert?

du hast recht gehabt.

ich hab zusätzlich das hier eingefügt
1
ISR(TIM1_CAPT_vect)
2
{
3
  Timestamp = 54; //ICR1;
4
  dataInTimestamp = TRUE;
5
  TCCR1B &= ~((1<<CS10) | (1<<CS11) | (1<<CS12)); // Timerstop
6
  PINA = _BV(PA0);
7
}

und beim externen Interrupt:
1
ISR(INT0_vect)
2
{
3
  Timestamp = 51;
4
  TCNT1= 0; //Timer reset
5
  TCCR1B |= (1 << CS11); //Prescaler = 8   //Timer läuft    
6
}

jetzt toggelt led1 schön und ich erhalte 54 vom i2c-master zurück.

Vielen Dank!

jetzt werden ja beide Interrupts (Input Capture/ Analog Comparator) 
aufgerufen.  und anscheinend IC zuletzt. Kann ich dann die gesamte 
Routine für ANA_COMP_vect entfernen, oder rationalisiert der compiler 
dann den ganzen Interrupt-handler weg und ich hab wieder nen reset drin?

von Johannes M. (johnny-m)


Lesenswert?

Für einen freigegebenen Interrupt muss immer ein Handler existieren. 
Wenn Du keinen schreibst, dann gibt es eben keinen (und das hat nichts 
mit "wegrationalisieren" zu tun).

Abgesehen davon bietet die interrupt.h die Möglichkeiten eines leeren 
Handlers (in dem dann auch nicht zeitraubend Register gepusht und gepopt 
werden) und eines Default-Handlers, der alle freigegebenen Interrupts 
auffängt, für die kein eigener Handler existiert. Ohne explizit 
angegebenen Default-Handler führt ein solcher Interrupt zu einem 
Neustart des Programms (was strenggenommen kein echter Reset ist, aber 
vom Ablauf her wie einer aussieht).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.