Forum: Mikrocontroller und Digitale Elektronik Programmablauf des Drehzahlmesser in C stockt.


von gerd (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Erst mal einen schönen Dank an dieses tolle Forum ich komme zwar nicht 
oft zum  schreiben aber das lesen macht echt Spaß!

Ich habe ein großes Problem mit meinem Atmega 32. Ich möchte ein 
Drehzahl messen (als Interrupt über den ICP Pin) und diese auf einem 
Display anzeigen. Und nebenbei soll noch ein Eingang überwacht werden 
und auch erst mal einfach auf dem Display visualisiert werden(später 
werden entsprechend auch noch diverse Ausgänge geschaltet).

Grundsätzlich funtioniert das auch alles, aber nur solange auch ein 
Drehzahlsignal kommt.
Wenn kein Signal mehr am ICP ankommt stockt mein Programm laufend alle 
ca 3 sek. für ca. 2 sek. dann gehts erst weiter.
Ich vermute das hat irgendwie damit zu tun dass wenn keine zweite Flanke 
kommt ich auf der Anzeige die Drehzahl auf 0 stellen wollte. nur finde 
ich den bug nicht; (

Dieses Problem macht mich jetzt seit Tagen! fast wahnsinnig, ich hoffe 
es kann mal jemand über den Code gucken und mir kann jemand helfen!

aller besten Dank
gruß
gerd

von Karl H. (kbuchegg)


Lesenswert?

gerd schrieb:

> Ich vermute das hat irgendwie damit zu tun dass wenn keine zweite Flanke
> kommt ich auf der Anzeige die Drehzahl auf 0 stellen wollte. nur finde
> ich den bug nicht; (

Du hast deine ganze Abfragelogik (auch das Abfragen des Notaustasters) 
in main() davon abhängig gemacht, dass ProgrammDurchlauf TRUE werden 
muss. Diese Variable wird aber nur durch 2 Ereignisse TRUE
* entweder es wird ein kompletter Messzyklus durchgeführt (was bei
  dir nicht der Fall ist, weil ja kein Signal kommt)
* Oder der Timer alle 2 Sekunden entsprechend viele Overflows generiert
  hat.

Frage: Ist die Abfrage des Notaustasters wirklich davon abhängig, dass 
ein entsprechender Frequenz Messzyklus abgeschlossen wurde oder ist es 
nicht eher so, dass beides voneinander unabhängig ist?

von gerd (Gast)


Lesenswert?

Moin,
Die Not Ausfunktion(wie auch der Rest des Programms der noch folgen 
wird) sollen unabhängig von der Drehzahl überwacht werden, das wäre wohl 
wichtig.

Wo muss ich in diesem Fall denn mit der Abfrage des Notaustasters hin 
damit das funktioniert? Oder andersrum gefragt wo muss ich das Flag 
"Programmdurchlauf=TRUE" setzten damit auch bei fehlendem Signal ein 
kompletter Durchlauf statt findet?

Danke,
Gruß
gerd

von Karl H. (kbuchegg)


Lesenswert?

gerd schrieb:

> Wo muss ich in diesem Fall denn mit der Abfrage des Notaustasters hin
> damit das funktioniert? Oder andersrum gefragt wo muss ich das Flag
> "Programmdurchlauf=TRUE" setzten damit auch bei fehlendem Signal ein
> kompletter Durchlauf statt findet?


Da die Abfrage und Behandlung des Notaus-Knopfes wohl nichts mit 
Programmdurchlauf zu tun hat, ist es auch nicht sinnvoll, diese Aktionen 
davon abhängig zu machen.

Das sollte doch wohl klar sein.
Also: Warum machst du das dann? Warum trennst du die beiden 
Funktionalitäten nicht einfach erst mal:

1
void Messwerte_ausgeben(void)
2
3
{    
4
  //Drehzahl auf dem Display ausgeben
5
  itoa( drehzahl, lcdDrehzahlString, 10 );  // Das Ergebnis fuer die Anzeige aufbereiten  
6
7
  // Messergebnisse auf dem Displayausgeben
8
  lcd_clear();    
9
  
10
  set_cursor( 0,1 );          // Gehe zu Pos. XY 
11
  lcd_string(lcdDrehzahlString);    // Datenwert
12
  lcd_string("U/min");        // Ausgabe Maske
13
}
14
15
void Notaus_ausgeben(void)
16
{
17
  //Notaus Status auf dem Display ausgeben
18
  itoa( NotStatus, lcdNotausString, 10 );  // Das Ergebnis fuer die Anzeige aufbereiten  
19
20
  set_cursor( 0,2 );          // Gehe zu Pos. XY 
21
  lcd_string(lcdNotausString);    // Datenwert
22
  lcd_string("Status");        // Ausgabe Maske
23
}
24
25
int main(void)
26
{
27
  lcd_init();              //lcd initialisieren
28
29
  DDRC = 0b00000000;  //Setzten der Pins an PortC auf Eingang
30
  PORTC = 0b11111111;  //Aktivieren der internen Pull up Wiederst�nde an C
31
32
  init_interrupt();          //Interrups klar machen
33
34
  
35
  while(1)              //diese Schleife soll das Programm immer wiederholen.
36
  {  
37
  
38
    if( ProgrammDurchlauf == TRUE)  // liegt ein vollst�ndiger Durchlauf vor?
39
    {
40
      Drehzahl_berechnen();
41
      Messwerte_ausgeben();
42
      ProgrammDurchlauf = FALSE;
43
    }
44
45
    Notaus_pruefen();
46
    Notaus_ausgeben();
47
  }
48
}

von gerd (Gast)


Lesenswert?

Hallo,
Simmt die Anzeige des Notaus und der Drehzahl zu trennen, irgendwie 
hatte ich die Idee bisher gar nicht;)

Hab ich das jetzt richtig verstanden so wie du das gändert hast:
Der Notaus wird durchgängig überwacht und auch auf dem Display angezeigt 
zusammen mit dem "alten Drehzahlwert",
sobald der Programmdurchlauf=TRUE wird zeigt er die aktuelle Drehzahl 
an,( das wäre dann nach der zweiten Flanke oder nach 2sek ohne Signal)

Was passiert jetzt wenn während "Notaus_pruefen()" ein Drehzahlsiganl 
kommt?
Dann löst der Interrupt aus und das Programm kehrt zurück zu 
"Notaus_pruefen" arbeitet da zuende und beim nächsten Durchgang wird
dann erst die If schleife durchlaufen udn die Drehzahl angezeigt?

Hab ich das alles so richtig verstanden?

Danke für die Hilfe,

gruß
gerd

von gerd (Gast)


Lesenswert?

Hallo,
So ich habe grad die Änderung in dem Programm ausprobiert, und es 
funktioniert; )
Die Drehzahl arbeitet jetzt unabhängig von der Notausabfrage.

Lediglich das Display zeigt aus mir noch unerfindlichen Gründen etwa 
alle 2 sek für etwa 2 sek( so genau kann ich das gar nicht stoppen..) 
unsauber an. Also es ziehen sich ca. 2sek lang kleine "Stiche" durch die 
schwarzen Zahlen, dann sind die Zahen wieder 2sek lang sauber 
dargestellt...
Das hat das Display vorher auch schon gemacht aber in dem Zeitraum in 
dem die Zahlen sauber dargestellt wurden konnte kein Eingang mehr 
verarbeitet werden, darum hab ich in meinem anfänglichen Threat 
geschrieben das Programm stockt..
Wenn immer wieder ein Drehzahlsignal kommt zeigt das Display durchgehend 
problemlos an.

Das Display zeigt also so lange sauber an, bis mein Overflow Zähler nach 
2 Sek ohne Drehzahlsignanl den Drehzahlwert auf 0 setzt.dann hab ich ca 
2sek lang Striche im Display und dann gehts wieder.

Vielleicht hat dafür ja auch noch jemand eine Idee??
Erst mal schon besten Dank für die Hilfe!!

gruß
gerd

von Karl H. (kbuchegg)


Lesenswert?

Das liegt daran, dass dein Timer ja weiterläuft.
Und er läuft und läuft und läuft ... bis er einen Overflow hat.
Die ersten 2 Sekunden spielt das keine große Rolle, aber nach dem 122 
Overflow setzt die Overflow ISR das 0-Flag und stößt mittels 
ProgrammDurchlauf einen Update der Drehzahlanzeige an. Tja. Nur. Der 
Timer läuft weiter und macht den 123-ten Overflow. Und schon wieder wird 
mittels ProgrammDurchlauf  ein Display Update angestossen. Und der Timer 
läuft weiter und macht den 124-ten Overflow. Und schon wieder kommt ein 
Update.

Das alleine wär noch gar nicht so schlimm. Aber bei jedem Update deiner 
Drehzahlanzeige am Display wird das LCD gelöscht.

Zusammengenommen: Nachdem der Timer den 122-ten Overflow gemacht hat, 
folgt ein Display-Löschen und neumalen auf das nächste. Und zwar 
ziemlich schnell hintereinander. So schnell wie der Timer in den 
nächsten Overflow kommt. Und das ist ziemlich schnell.

von gerd (Gast)


Lesenswert?

Hallo,
ich hab grad noch etwas getwas gespielt, und das "lcd clear" ganz 
rausgenommen.
jetzt hab ich eine absolut saubere anzeige und soweit ich geprüft hab 
keine probleme.
warum sollte man das "lcd clear" überhaupt einsetzten?
Wann macht das lcd clear sinn?

schönen gruß
gerd

von gerd (Gast)


Lesenswert?

ah ich habs gesehen... wenn eine stelle vom display vorher beschrieben 
worden ist und einen drurchlauf später nciht überschrieben wird bleibt 
das stehen...
eigentlich logisch..

jetzt muss ich mir blos ne stelle suchen wo das lcd clear hin kann damit 
es nciht "dauernd" durchgeführt wird..

es gibt noch viel zu tun..
gruß
gerd

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.