Forum: Compiler & IDEs ATMEGA 164 A Variabel wird nicht im Interrupt beschrieben


von benjamin s. (b-black)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

habe ein kleines Problem mit meinem Programm. Wende mich deswegen an 
euch in der Hoffnung das mir jemand einen Tipp oder Fehler zeigt.

Verwenden tu ich ein ATMEGA 164A. Extern getaktet auf 16MHz. 
Programmiere diesen über Visual-Studio in C. Aufgespielt wird über 
PonyProg und eine RS-232 Schnittstelle vom PC.

Zur Funktion:
An dem uC ist ein Sensor angeschlossen, welcher die Drehrichtung in 
unterschiedlicher Impulslänge ausgibt. Bei jedem erkannten Pol von dem 
Sensor soll ein Piepson ausgegen werden. Je nach länge des Impulses soll 
eine rote oder blaue LED leuchten (Drehrichtung bestimmung).

Mein Problem ist, das es nicht Funktioniert die Zeit zwischen der 
steigenden und fallenden Flanke (Impuls) zu messen. im Interrupt wird 
nicht die Variable beschrieben so dsa sie im Main ausgelesen werden 
kann.

Habe es schon auf verschiedenen Arten versucht und jegliche Foren 
durchforstet aber nie meinen Fehler gefunden.

Bitte schaut mal drüber ob ihr etwas findet, verbessern oder fehler 
findet.

Vielen dank im Vorraus!

gruß
Benny

von Johann L. (gjlayde) Benutzerseite


Lesenswert?


von Fabian O. (xfr)


Lesenswert?

Durch die Funktionsweise des Codes steige ich ehrlich gesagt nicht ganz 
durch, aber formal fallen schon mal zwei Dinge auf:

- Die globale Variable temp ist vom Typ uint_fast16_t. In der 
Endlosschleife weist Du sie dagegen an einen uint8_t zu. Das macht nicht 
so viel Sinn.

- Du musst die Zugriffe auf temp in der Hauptschleife atomar machen, 
sofern Du mehr machst als 8 Bit lesen oder schreiben. Sonst kann es 
passieren, dass zwischendurch der Interrupt die Variable verändert und 
Du inkonsistene Ergebnisse hast.
1
cli()
2
if ( temp > 0 )
3
{
4
  t1 = temp;
5
  temp = 0;
6
}
7
sei();

Dann allgemein: Du erhöhst in der Timer-ISR den Zähler temp um 1. Danach 
läuft die Hauptschleife, sieht dass der Zähler größer 0 ist und setzt 
ihn wieder auf 0. Wie soll er denn nennenswert größer als 1 werden, wenn 
Du ihn in der Hauptschleife jedes Mal gleich wieder zurücksetzt? Da 
müssten die Timer-Interrupts schon sehr schnell kommen ...

von benjamin s. (b-black)


Lesenswert?

Vielen Dank für die schnellen Antworten!

@ gjlayde: Danke nur versteh ich die Links nicht. kann leider nur C und 
all zu sehr kenn ich mich mit uC nicht aus. Was bedeutet das im 
klartext?

@ xfr: mit dem Variablen Typ hast du recht. Hab so oft schon etwas 
geändert das mir das nicht aufgefallen ist, macht natürlich so wenig 
sinn. Mit dem Cli(); und Sei(); habe ich es versucht, hat aber keine 
Änderung gezeigt, auch wenn ich sage das mein Temp nicht mehr auf 0 
gesetzt werden soll.
die Variable fängt glaub ich garnicht an hochzuzählen...

gruß

von Fabian O. (xfr)


Lesenswert?

benjamin schwarz schrieb:
> Danke nur versteh ich die Links nicht. kann leider nur C und
> all zu sehr kenn ich mich mit uC nicht aus. Was bedeutet das im
> klartext?

Da steht, dass es im avr-gcc-Compiler einen Fehler gab, der dazu führte, 
dass der Compiler beim ATmega164A Variablen an ungültige 
Speicheradressen gelegt hat. Der Fehler ist ab avr-gcc 4.6.2 behoben.

Falls Du also eine ältere Version des Compilers verwendest, musst Du ihn 
updaten. In Atmel Studio 6 bzw. der neusten Version der Atmel Toolchain 
ist avr-gcc 4.6.2 dabei.

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.