www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Variablenänderung erkennen


Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich haebe derzeit das Problem, dass ich möglichst exakt an dem Punkt, an 
welchem eine Variable ihren Wert ändert einen ADC - Wert aufnehmen muss.
Diese Variable hat außerdem noch einen Einfluss auf einen Ausgabepin und 
hat nur die Zustände eins und Null.
Die Variable wird durch eine Interruptroutine eines Timers geändert.
Mein bisheriger Ansatz ist folgender:
sens[0] = 0;
sens[1] = 0;
sens[2] = 0;

if (freq == 1)
{
  while(freq == 1)
  {}
}
while (freq == 0)
{}
for (counter = 0; counter < 3; counter ++)
{
  abfragen(counter);
  sens[counter] = result;
}
min[0] = sens[0];
min[1] = sens[1];
min[2] = sens[2];
    
while (freq == 1)
{}
for (counter = 0; counter < 3; counter ++)
{
  abfragen(counter);
  sens[counter] = result;
}
max[0] = sens[0];
max[1] = sens[1];
max[2] = sens[2];

...

set_cursor(0,2);
lcd_string("                ");
    
set_cursor(10,2);
lcd_string("    ");
char Buffer[20];
itoa(delta[0], Buffer, 10);
set_cursor(1,2);
lcd_string( Buffer );

itoa(max[0], Buffer, 10);
set_cursor(6,2);
lcd_string( Buffer );

itoa(min[0], Buffer, 10);
set_cursor(10,2);
lcd_string( Buffer );
abfragen(0);
long_delay(200);

Der Teil den ich durch ... erstezt habe funktioniert einwandfrei und die 
LCD - Ausgabe unten auch, das habe ich mit älteren Versionen getestet, 
welche noch nicht diesen Wechsel benötigten.

Das Problem ist nun, dass der Controller irgendwo hängen bleibt, er 
arbeitet das Programm mindestens bis zu der ersten beschriebenen Zeile 
ab kommt aber nie bei der LCD - Ausgabe an. Der Takt wird auch an dem 
Pin ausgegeben, es kann also nicht an der Variablen liegen.

Controller: ATmega8
Verw. Timer: 2
Takt: 16MHz


Mfg Pat

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es macht keinen Spaß, das zu debuggen, weil es 1. Spagetticode und 2. 
ein Codefetzen ohne Anfang und Ende ist. Deshalb lasse ich das.

Ich würde eine kleine Hauptschleife bauen und darin die betreffende 
Variable abfragen.
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t beobachtete_variable;

void arbeitsroutine(void)
{
  // Portpin schalten

  // ADC-Messung ausführen

  // LCD-Ausgabe machen
}

int main(void)
{
  ddr_einstellen();
  timer2_initialisieren();
  sei();

  while(1)
  {
    if ( beobachtete_variable == 1 )
    {
      arbeitsroutine();
      beobachtete_variable = 0; // Alles abgearbeitet
    }
  }
}

Dabei ist darauf zu achten, dass die arbeitsroutine() beendet sein muss, 
wenn die nächste Änderung der beobachteten_variable passiert. Das kann 
je nach Frequenz deines Timer2 und der Änderungsfrequenz der 
beobachteten_variable sehr kritisch sein oder man kann es entspannt 
angehen.

Um herauszufinden ob man sich Sorgen machen muss, kann man in der Timer2 
ISR seinerseits die beobachtete_variable prüfen. Wenn in der Timer2 ISR 
eine Änderung notwendig wird, aber die beobachtete_variable vom 
vorherigen Aufruf noch auf 1 steht, dann ist ein Zeitkonflikt 
aufgetreten, Das kann man zählen und entsprechend die arbeitsroutine() 
optimieren.

Optimierungspotential sehe ich bei:

* der ADC-Messung. Die ADC-Messung selbst braucht eine gewisse Zeit. 
Wenn Mittelwerte gebildet werden, umso länger.

Man kann diese Zeit verkürzen, wenn die ADC-Initialisierung einmalig 
vorab gemacht wird und die Referenz etc. nicht umgeschaltet wird. Auch 
kann man sich überlegen die ADC Messung bereits in der Timer2 ISR zu 
starten und in der Arbeitsroutine nur noch kurz Ergebnis warten zu 
müssen.

* die LCD-Ausgabe.

Man kann diese Zeit verkürzen, indem man einen Teil der Ausgabe bereits 
macht, wenn die beobachtete_variable noch nicht geändert ist. Wenn die 
Änderung kommt, setzt man nur noch den eigentlichen Wert in die mit 
vorbereitete LCD Anzeige ein.

* dem Schalten des Portpins.

Das kann man ebenfalls in der Timer2 ISR erledigen, wenn man den Inhalt 
der beobachtete_variable ändert. Wenn die Änderung des Portpins 
besonders wichtig ist, könnte man den auch ändern, wenn die 
arbeitsroutine() unterbrochen wurde.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.