Drehzahl an atmega16

Gast #981167
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
#981329
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)
Gast #981342
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.
Gast #981347
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
#981556
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.
Gast #981677
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
Gast #982119
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
Angehängte Dateien:

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.