PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Temperatur anzeige auf dem LCD wird nicht aktualisiert?



Ferdinand
15.01.2012, 16:20
Hallo ich möchte mir eine Steuerung für ein Ätzgerät basteln.

Ich möchte die Laufzeiten der Heizung und die Laufzeiten der Aquariumpumpe einstellen können, wann sie Beginen und wann sie Stoppen, dazu Wil ich die Temperatur einstellen und einen schwel wert für die Heizung einstellen können, weil die ja eine Wärme Kapazität hat und eine Kapazität damit sie nicht Sekunden weise einschaltet und wider aus schaltet zur Regelung, ich möchte die Einstellungen später im EEPROM speichern können.

Nun möchte ich die Temperatur dauernd anzeigen, nur funktioniert das nicht die Anzeige des LCD's wird nur nach einem Tastendruck aktualisiert




//
// ATMega644
// lcd-routines.c, lcd-routines.h, i2c.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <stdbool.h>
#include "lcd-routines.h"
#include "i2c.h"

int main(void) //Hauptschleife
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0xff; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string(" LCD Start !!! ");
_delay_ms(500); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

lcd_clear();
lcd_home();
lcd_string(" Taste druecken");


TWI_init(FAKTOR, TEILER);

char temperatur; //Temperaturvariable
char einer; //Temperaturvariable einer
char zehner; //Temperaturvariable zehner
char Buffer[100]; //itoa Array 3 stelig
int i = 25; //Laufzeitvariable

while(1) //Programmschleife
{


temperatur = TWI_empf(ADRESSE_R); //Temperaturvariablen
einer = ( temperatur % 10 ) + 48;
zehner = ( temperatur / 10 ) + 48;

if(!(PIND & (1<<PD0))) // Taste 0 an PORTD PD0
{
_delay_ms(10);

i++;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD0)));
_delay_ms(10);
}

if(!(PIND & (1<<PD1))) // Taste 1 an PORTD PD1
{
_delay_ms(10);

i--;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD1)));
_delay_ms(10);
}

if (dat2 >= 0b10000000)
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",5C ");
}

else
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",0C ");
}

}

return(0);
}

damaltor
15.01.2012, 16:45
Du wartest ja auch an dieser Stelle



while(!(PIND & (1<<PD1)));
_delay_ms(10);
}
auf einen Tastendruck. An dieser Stelle bleibt dein Programm so lange in der While-Schleife hängen, bis eine Taste gedrückt wird.

Ferdinand
15.01.2012, 18:18
Dan müsste ich ja beide gedrückt haben.
Nun zurzeit ist es egal, welche Taste gedrückt wird.




if(!(PIND & (1<<PD0))) // Taste 0 an PORTD PD0 { _delay_ms(10); i++; lcd_setcursor( 0, 1); lcd_string("Aetzlaufzeit "); itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln lcd_string( Buffer ); while(!(PIND & (1<<PD0))); _delay_ms(10); } if(!(PIND & (1<<PD1))) // Taste 1 an PORTD PD1 { _delay_ms(10); i--; lcd_setcursor( 0, 1); lcd_string("Aetzlaufzeit "); itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln lcd_string( Buffer ); while(!(PIND & (1<<PD1))); _delay_ms(10); }




Und wen ich das verwende.



if(!(PIND & (1<<PD0))) // Taste 0 an PORTD PD0
{
_delay_ms(10);

i++;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

if(!(PIND & (1<<PD0)))
{
_delay_ms(10);
}
}

if(!(PIND & (1<<PD1))) // Taste 1 an PORTD PD1
{
_delay_ms(10);

i--;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

if(!(PIND & (1<<PD1)))
{
_delay_ms(10);
}
}



Dann wen ich denn Taster gedrückt halte, zählt die Variable rauf oder runter.

Danke

damaltor
15.01.2012, 18:39
Hm. Ich geh mal davon aus, dass du die Taster gegen Masse angeschlossen hast und mit dem internen Pullup-Widerständen betreibst, wie es in deinem Quellcode steht. Das Display geht also an, "LCD Start" wird ausgegeben, und die Temperatur wird EIN mal angezeigt und dann nicht aktualisiert. ist das so?

Ferdinand
15.01.2012, 18:51
ja stimmt !!!

Kampi
15.01.2012, 19:18
Ja weil das Programm hier stehen bleibt:

while(!(PIND & (1<<PD0)));

damaltor
15.01.2012, 19:59
Dort dürfte es ja eigentlich nur dann stehen bleiben wenn die Taste gedrückt ist, und an der stelle eine null im Register ist.

Kampi
15.01.2012, 20:18
Er kann ja mal testen wo das Programm stehen bleibt indem er eine LED schaltet. Einfach verschiedene Stellen im Programm einen Pin auf High setzen. Dann sieht er ja wo es stehen bleibt.

damaltor
15.01.2012, 20:24
ja, so hab ich das auch immer gemacht. wenn dir ein jtagICE zur verfügung steht, kannst du den code auch live laufen lassen und schauen wo es hängt.

Ferdinand
15.01.2012, 20:42
Ja schon nur das wartet ja so lange, bis ich die Taste wider losgelassen habe.

Noch mal mein Code etwas übersichtlicher.


//
// ATMega644
// lcd-routines.c, lcd-routines.h, i2c.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <stdbool.h>
#include "lcd-routines.h"
#include "i2c.h"

int main(void) //Hauptschleife
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0xff; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string(" LCD Start !!! ");
_delay_ms(500); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

lcd_clear();
lcd_home();
lcd_string(" Taste druecken");


TWI_init(FAKTOR, TEILER);

char temperatur; //Temperaturvariable
char einer; //Temperaturvariable einer
char zehner; //Temperaturvariable zehner
char Buffer[100]; //itoa Array 3 stelig
int i = 25; //Laufzeitvariable

while(1) //Programmschleife
{


temperatur = TWI_empf(ADRESSE_R); //Temperaturvariablen
einer = ( temperatur % 10 ) + 48;
zehner = ( temperatur / 10 ) + 48;

if(!(PIND & (1<<PD0))) // Taste 0 an PORTD PD0
{
_delay_ms(10);

i++;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD0))); //Warte solange Taste noch getrückt ist.
_delay_ms(10);

}

if(!(PIND & (1<<PD1))) // Taste 1 an PORTD PD1
{
_delay_ms(10);

i--;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD1))); //Warte solange Taste noch getrückt ist.
_delay_ms(10);

}

if (dat2 >= 0b10000000)
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",5C ");
}

else
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",0C ");
}

}

return(0);
}



Wie gesagt ich hab nur Probleme mit der Temperatur aktualisieren.

Danke

damaltor
15.01.2012, 21:02
versuch doch mal rauszufinden, an welcher stelle das Programm hängen bleibt.

Kampi
15.01.2012, 21:06
Wie schon gesagt das kannst du testen indem du an verschiedene Stellen einfach eine LED einschaltest (du kannst auch nur eine LED einschalten und die Stelle wo sie eingeschaltet wird immer wechseln). Dadurch siehst du recht gut was wann passiert und wie sich dein Programm verhält. Alternativ kannst du das auch mittels Ausgabe über UART und einem Terminalprogramm am PC machen (oder z.B. dein LCD :) )

Ferdinand
15.01.2012, 21:13
OK

Ich hab mal 2 LED's mit eingebunden, also beim Start sind beide LED's aus. Wen ich Taste 0 drücke Dan geht LED 1 an, wen ich Taste 1 drücke Dan geht LED 0 an.
Allerdings weis ich nicht ob die LED's beim STK500 nach GND schalten.
Hier hab ich mal den Code.



//
// ATMega644
// lcd-routines.c, lcd-routines.h, i2c.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <stdbool.h>
#include "lcd-routines.h"
#include "i2c.h"

int main(void) //Hauptschleife
{
DDRA = 0xff; // Pins sind Ausgang
PORTA = 0xff; // LED's Aus

DDRD = 0x00; // Pins sind Eingang
PORTD = 0xff; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string(" LCD Start !!! ");
_delay_ms(500); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

lcd_clear();
lcd_home();
lcd_string(" Taste druecken");


TWI_init(FAKTOR, TEILER);

char temperatur; //Temperaturvariable
char einer; //Temperaturvariable einer
char zehner; //Temperaturvariable zehner
char Buffer[100]; //itoa Array 3 stelig
int i = 25; //Laufzeitvariable

while(1) //Programmschleife
{


temperatur = TWI_empf(ADRESSE_R); //Temperaturvariablen
einer = ( temperatur % 10 ) + 48;
zehner = ( temperatur / 10 ) + 48;

if(!(PIND & (1<<PD0))) // Taste 0 an PORTD PD0
{
_delay_ms(10);

PORTA = (1<<PD0); //LED0
i++;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD0))); //Warte solange Taste noch getrückt ist.
_delay_ms(10);

}

if(!(PIND & (1<<PD1))) // Taste 1 an PORTD PD1
{
_delay_ms(10);

PORTA = (1<<PD1); //LED 1
i--;
lcd_setcursor( 0, 1);
lcd_string("Aetzlaufzeit ");
itoa( i, Buffer, 10 ); //Laufzeitvariable in Integer wandeln
lcd_string( Buffer );

while(!(PIND & (1<<PD1))); //Warte solange Taste noch getrückt ist.
_delay_ms(10);

}

if (dat2 >= 0b10000000)
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",5C ");
}

else
{
lcd_setcursor( 0, 2);
lcd_string("Temperatur ");
lcd_data(zehner);
lcd_data(einer);
lcd_string(",0C ");
}

}

return(0);
}



Danke

damaltor
15.01.2012, 21:42
Warte... wenn du 0 drückst geht 1 an und umgekehrt? Das ist ja fast nicht möglich o0

Ferdinand
16.01.2012, 05:09
Ja die LED's leuchten wen pin nach gnd schaltet.

Kampi
16.01.2012, 08:26
Was Damaltor sagen will ist, dass es nicht sein kann das der Controller beim drücken der Taste 0 in die zweite If-Abfrage springt um dort die LED1 anzuschalten ;)
Sicher das du die Taster richtig angeschlossen hast?
Wenn du möchtest, dass das LCD regelmässig aktualisiert wird kannst du doch auch mit einem Timer arbeiten und mit dem das LCD 1x pro Sekunde aktualisieren-

damaltor
16.01.2012, 13:55
Ich glaube mitterweile auch dass da etwas falsch angeschlossen ist, bzw. du die Anschlüsse auf dem STK500 falsch interpretierst. Kann es sein, dass die Taster nicht gegen Masse, sondern gegen 5V schalten? Bin mir nicht mehr sicher. Das könnte aber der Grund sein, dass das Programm nur dann weiterläuft wen ein Taster auf 5V gelegt wird.

Edit: Ich habe gerade noch mal in den Schaltplan vom STK500 geschaut. Die Taster schalten auf Masse und haben bereits einen PullUp-Widerstand von 10k auf dem Board aufgelötet.

Die LEDs zeigen "in Richtung des Prozessors" und leuchten, wenn eine Null am entsprechenden Pin ausgegeben wird.