Forum: Mikrocontroller und Digitale Elektronik Drehzahl an atmega16


von Daniel (Gast)


Lesenswert?

Hallo zusammen,

ich befasse mich erst seit kurzem wieder mit Mikrocontroller und habe 
bisher eigentlich nur Spielereien damit programmiert.

Jetzt habe ich mich an einen Drehzahlmesser rangewagt. Zur Erklärung:

Die Drehzahl wird mit einem Hall-Sensor abgenommen und liefert mir pro 
Umdrehung ein High-Signal. Um die Drehzahl zu bestimmen wollte ich nun 
die Zeit zwischen den Flankenwechseln messen.
Die U/min sollen mir dann auf einem LCD (2 Zeilen, 32 Zeichen) angezeigt 
werden.
Der verwendete Mikrocontroller ist ein Atmega16, da ich die 
Flankenwechsel an PD6/ICP einlesen wollte. Programmieren wollte ich mit 
C.

Aus älteren Schulunterlagen hatte ich noch einen Quelltext, mit dem man 
die Zeit zwischen zwei Flankenwechsel messen kann. Die Zeit wird dann 
auf vier BCD 7-Segment-Anzeigen ausgegeben die an Port A und Port B 
hängen.

Jetzt zu meinem Problem, ich bekomme den Quelltext nicht so abgeändert, 
das es mir die Zeit, bzw. die U/min auf dem Display anzeigt. Ich bekomme 
den „wert“ aus der Service-Funktion nicht in das Main-Programm.

Die LCD-Initialisierung klappt und zeigt mir auch was an. Ich habe die 
LCD-Routines aus dem AVR-GCC-Tutorial verwendet und auf Port C 
umgeschrieben.

Ich bin für jede Hilfe dankbar. Die C-File befindet sich im Anhang
Gruß Daniel

von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Anhang ist nicht mitgekommen!

von Timmo H. (masterfx)


Lesenswert?

Das Problem ist, das "wert" einmal in der Signal Funktion als lokale int 
Variable und einmal vor main als globale float variable deklariert ist. 
Mach die mal ganz an den Anfang als int und in der Signal funktion lässt 
du das weg.
Normalerweise müsste der Compiler auch so meckern. (mach mal gcc -Wall)

von STK500-Besitzer (Gast)


Lesenswert?

>Das Problem ist, das "wert" einmal in der Signal Funktion als lokale int
>Variable und einmal vor main als globale float variable deklariert ist.
>Normalerweise müsste der Compiler auch so meckern. (mach mal gcc -Wall)
Dem Compiler ist es ziemlich egal, wie wo welche Variable mit welchem 
Namen deklariert wird.

>Mach die mal ganz an den Anfang als int und in der Signal funktion lässt
>du das weg.

Mit einem "volatile" bei der Deklaration geht man sicher, dass der 
Compiler die Variable nicht einfach wegoptimiert, wenn er der "Meinung" 
ist, dass sie nirgends weiter benutzt wird.

von Marc (Gast)


Lesenswert?

hi,
du hast wert in deiner interrupt routine declariert und noch einmal in 
deiner main funkition. wenn du auf die variable sowohl im interrupt, als 
auch in der main funktion zugreifen willst musst du sie erstens ueber 
beiden funktionen deklarieren und somit global, und ich denke du kannst 
dir das register keyword sparen und durch ein 'volatile' ersetzen.

ungefaehr so:
1
volatile uint16_t wert;
2
3
ISR (TIMER0_OVF_vect) {
4
   /* Interrupt routine */
5
   wert = blubb;
6
}
7
8
int
9
main (void) {
10
   /* hauptroutine */
11
12
   /* ausgabe wert */
13
}

gruss
Marc

von Timmo H. (masterfx)


Lesenswert?

>Dem Compiler ist es ziemlich egal, wie wo welche Variable mit welchem
>Namen deklariert wird.
Ihm ist es aber nicht egal, wenn eine Variable mit gleichem Namen 
zweimal deklariert wird.

>Mit einem "volatile" bei der Deklaration geht man sicher, dass der
>Compiler die Variable nicht einfach wegoptimiert, wenn er der "Meinung"
>ist, dass sie nirgends weiter benutzt wird.
Verhindert aber auch keine doppel-deklaration.

von Marc (Gast)


Lesenswert?

der compiler wird das nicht als fehler erkennen. fuer den compiler ist 
der namespace der globalen ab der deklaration abwaertz. somit wird die 
lokale in der interrupt routine nicht von der globalen ueberdeckt, denn 
die ist erst ab kurz vor der main gueltig. volatile bringt da auch 
nichts, aber volatile ist notwendig, damit du in der ISR den wert 
aendern kannst und er auch im in der main schleife aktuell ist

Gruss
Marc

von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Erstmal vielen Dank für eure Hilfe.

Es war mir schon klar, das ich die Variable „wert“ 2x deklariert habe. 
Bzw, es war ein versehen das diese noch im Quelltext stand den ich 
gepostet habe. Durch die 2te deklarierung und das gleichzeitige Setzen 
der Variable auf 9999 (float wert=9999;) wollte ich die Berechnungen und 
die LCD-Ausgabe testen.

@ Marc: Dein Vorschlag war genau der Richtige, jetzt funktioniert es... 
theoretisch zumindest.

Habe diese Schaltung bisher nur mit der Software „Proteus 7 
Professional“ von Labcenter simuliert, da läuft sie. Man tastet an PD6 
und auf dem LCD erscheinen die U/min.
Nach dem ich sie jetzt Hardware-Technisch aufgebaut habe lässt sich das 
LCD nicht initialisieren. Woran kann das liegen?

Selbst mit dem Quelltext aus dem AVR-Tutorial, womit man nur „Test – 
Hallo Welt“ auf das LCD schreibt, Funktioniert nicht.
Mit einem Atmega8 gibt es keine Probleme. Nur der 16er will nicht.
Ich muss ehrlich gesagt zugeben, dass ich das erste Mal einen Atmega16 
benutze, bisher hat ein 8er immer gereicht.

Die Verdrahtung und die Funktion des LCD habe ich mehrere male 
überprüft. Lasse den Atmega16 derzeit mit den ab Werk eingestellten 1 
MHz laufen.

Kann sich jemand mal die header-files ansehen? Packe das ganze Projekt 
mal in den Anhang.

Vielen Dank

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.