Archiv verlassen und diese Seite im Standarddesign anzeigen : Servoimpulse vom RC-Empfänger auswerten fehlgeschlagen
Hallo,
ich habe hier im Forum in verschiedenen Beiträgen Ansätze zum Auswerten eines Servosignals vom Empfänger gelesen. Nun habe ich versucht mir daraus mal einen eigenen Versuch zu programmieren um ein solches Signal auszulesen.
Mein Versuch sieht wie folgt aus:
Ich habe mein Signal auf den Eingang INT0 gelegt. Den Timer 1 habe ich mit dem Teiler CPU/8 gestartet (CPU-Takt 8MHz).
Nun wird bei der steigenden Flanke an INT0 ein Interrupt ausgelöst, da setze ich eine Variable, versuche den Counter TCNT1 in eine andere Variable abzulegen und setze den Interrupt auf fallende Flanke.
Bei der fallenden Flanke passiert das selbe in ähnlicher Weise.
void init_timer(void)
{
// Timer0 (8Bit)
TCCR0 |= (1<<CS00) | (1<<CS01); //Vorteiler auf CPU Takt/64
TIMSK |= (1<<TOIE0); //Interupt für Timer0 Overflow einschalten
//Timer 1 (16Bit)
TCCR1B |= (1<<CS11); //Vorteiler auf CPU Takt/8
}
void init_interrupt(void)
{
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke
GICR |= (1<<INT0); //Interrupt von INT0 auf Enable
}
ISR(INT0_vect)
{
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01);
}
if (flanke == 0)
{
stop = TCNT1;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke
flanke = 0;
}
}
Mein µC (zur Zeit Mega16 später auch im Mega8) scheint auch auf die Impulse vom Empfänger zu reagieren, also ein Interrupt wird ausgelöst.
Mit dem Timer0 lasse ich einen Zähler hochzählen der mir dann durch If anweisungen Ausgänge setzt oder rücksetzt.
Mein Problem:
Sobald ich den Empfängerimpuls anschließe wird nur noch der Interrupt ausgeführt, das restliche Programm läuft nicht mehr ab.
Da ich hier schon öfter davon gelesen habe, meine ich das auch mehrere Impulse ausgewertet werden können und trotzdem noch komplexe Programme ausgeführt werden.
Was mache ich falsch?
Ist der Code im Interrupt zu Zeitaufwendig? (Frequenz ist 50Hz Impulslänge von 1ms bis 2ms)
Ist mein auslesen des Counterregisters richtig? (beim 8Bit Timer ging es so)
Ich hoffe ich habe mein Problem ausführlich genug beschrieben, sonst bitte einfach nachfragen. Bin noch am Anfang mit der C-Programmiererei.
Danke schon einmal im voraus für die Hilfe
Hubert.G
07.04.2007, 19:21
Wo setzt du "flanke" auf 1, wenn "flanke" auf 0 ist warum setzt du sie anschließend wieder auf 0? Ausserdem ist das sicher nicht der ganze Code denn der macht ja wenig Sinn.
Hallo,
nein das ist nicht der ganze Code. Ich dachte die entscheidenen Teile wären die oben genannten.
//Einbinden der Funktionen aus den anderen Dateien
extern void init_digital (void);
extern void init_timer(void);
extern void init_interrupt(void);
extern void lcd_writetext(char *text);
extern void lcd_ini(void);
extern void lcd_gotopos (uint8_t zeile, uint8_t spalte);
//Globale Variable
volatile int Zaehler;
volatile int Zaehler2;
volatile int start;
volatile int stop;
volatile int impuls;
volatile int flanke;
volatile char impuls1;
int main(void)
//Hauptprogremm
{
//Variablen der Steuerwelle 0 bis Reset
int LED1 = 0;
int LED2 = 250;
//int LED3 = 50;
//int LED4 = 100;
//int LED5 = 0;
//int LED6 = 0;
//int LED7 = 0;
//int LED8 = 0;
//int LED9 = 0;
//int LED10 = 0;
//int LED11 = 0;
int test = 300;
int Reset = 500;
// Ende LED Steuerwellenvorgabe
init_digital(); // Ports initialisieren (eigene Funktion)
init_timer(); // Timer initialisieren (eigene Funktion)
init_interrupt();
lcd_ini();
flanke = 1; //Flankenmerker
sei(); //Interupts aktivieren
while(1)
{
if (Zaehler2 == test)
{
impuls = stop - start;
itoa(impuls, impuls1,10);
lcd_gotopos(2,1);
lcd_writetext("Impd: " + impuls1);
}
if (PIND & (1<<PIND5))
{
PORTC |= (1<<PC5); //Bit1 auf High setzen
}
// Blaulicht (Blitzer) Transistor T1
if (Zaehler == LED1)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 50)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
if (Zaehler == LED1 + 120)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 170)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T1
//************************************************** **************************
// Blaulicht (Blitzer) Transistor T2
if (Zaehler == LED2)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 50)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
if (Zaehler == LED2 + 120)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 170)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T2
//Zähler Reset
if (Zaehler >= Reset)
{
Zaehler = 0;
}
//Zähler2 Reset
if (Zaehler2 >= Reset)
{
Zaehler2 = 0;
}
//************************************************** **************************
if (!(PIND & (1<<PIND5)))
{
PORTC &= ~(1<<PC5);
}
} //while
} //ENDE main
ISR(TIMER0_OVF_vect)
//Interrupt bei Timer0 Overflow
{
Zaehler++;
Zaehler2++;
}
ISR(INT0_vect)
{
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01);
}
if (flanke == 0)
{
stop = TCNT1;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
flanke = 0;
}
}
Das ist jetzt der ganze. Ist ja auch nur ein Testprogrämmchen.
Flanke wird beim ersten Start des Controllers auf 1 gesetzt und dient nur dazu im Interrupt in die richtige Schleife zu sprinngen.
Hubert.G
07.04.2007, 20:12
Wenn du das Signal direkt vom Empfänger auswerten willst weiss ich nicht was du mit Flankenumschalten willst. Die Zeit für das Servo liegt doch im Abstand der Impulse die der Empfänger ausgibt also nur auf steigende oder fallende Flanke setzen.
Von dem Abgesehen sehe ich nicht wo du auf "flanke =0" stellst.
Ich möchte ja die Impulszeit haben, sonst habe ich ja immer unverändert die 50 Hz.
Wichtig ist Zeit zwischen der steigenden und fallenden Flanke des Impulses
Hubert.G
07.04.2007, 20:44
Dann willst du die bereits dekodierten Impulse für das Servo auswerten. Das ist was anderes.
Ich sehe nicht wo du deinen INT0 initialisierst, nehme an er steht auf steigende Flanke, die steigende Flanke löst den ISR aus, startet den Timer, stellt den INT0 auf fallende Flanke, setzt "flanke" auf 0. Die nächste fallende Flanke löst ISR aus, stoppt den Timer, Timer auslesen,INT0 auf steigende Flanke, "flanke" auf 1. usw.
Ich weiss nicht ganz wo da das Problem liegt.
Hubert
Ja, die steigende Flanke lege ich beim Initialisieren des Interrups fest.
Mein Proglem liegt darin, das die anderen Befehle (If) die mir ein paar LED's zum blinken bringen sollen nicht mehr ausgeführt werden. Die LED's hören auf zu blinken.
Also mein Code sollte demnach funktionieren, oder verstehe ich dich da falsch?
Hubert.G
07.04.2007, 21:28
Dein ISR(INT0_vect) kann nicht funktionieren, ausser du sagst mir wo du auf "flanke =0" umschaltest.
Hallo,
Du hast Recht, ich habe vergessen auf Flanke 0 zu schalten. Ich probiere es mal aus ob es dann klappt.
Melde mich dann noch einmal hier
Hmm,
das hatte ich wohl versehendlich gelöscht beim testen. Das Programm wird immer noch nicht weiter abgearbeitet wenn ein Impuls anliegt.
Code sieht jetzt so aus:
//Einbinden der Funktionen aus den anderen Dateien
extern void init_digital (void);
extern void init_timer(void);
extern void init_interrupt(void);
extern void lcd_writetext(char *text);
extern void lcd_ini(void);
extern void lcd_gotopos (uint8_t zeile, uint8_t spalte);
//Globale Variable
volatile int Zaehler;
volatile int Zaehler2;
volatile int start;
volatile int stop;
volatile int impuls;
volatile int flanke;
volatile int z1;
volatile char impuls1;
volatile char z11;
int main(void)
//Hauptprogremm
{
//Variablen der Steuerwelle 0 bis Reset
int LED1 = 0;
int LED2 = 250;
//int LED3 = 50;
//int LED4 = 100;
//int LED5 = 0;
//int LED6 = 0;
//int LED7 = 0;
//int LED8 = 0;
//int LED9 = 0;
//int LED10 = 0;
//int LED11 = 0;
int test = 300;
int Reset = 500;
// Ende LED Steuerwellenvorgabe
init_digital(); // Ports initialisieren (eigene Funktion)
init_timer(); // Timer initialisieren (eigene Funktion)
init_interrupt();
lcd_ini();
flanke = 1; //Flankenmerker
z1 = 0;
sei(); //Interupts aktivieren
while(1)
{
if (Zaehler2 == test)
{
impuls = stop - start;
itoa(impuls, impuls1,10);
itoa(z1, z11,10);
lcd_gotopos(2,1);
lcd_writetext("Impd: " +impuls1);
lcd_gotopos(3,1);
lcd_writetext(z11);
}
if (PIND & (1<<PIND5))
{
PORTC |= (1<<PC5); //Bit1 auf High setzen
}
// Blaulicht (Blitzer) Transistor T1
if (Zaehler == LED1)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 50)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
if (Zaehler == LED1 + 120)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 170)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T1
//************************************************** **************************
// Blaulicht (Blitzer) Transistor T2
if (Zaehler == LED2)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 50)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
if (Zaehler == LED2 + 120)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 170)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T2
//Zähler Reset
if (Zaehler >= Reset)
{
Zaehler = 0;
}
//Zähler2 Reset
if (Zaehler2 >= Reset)
{
Zaehler2 = 0;
}
//************************************************** **************************
if (!(PIND & (1<<PIND5)))
{
PORTC &= ~(1<<PC5);
}
} //while
} //ENDE main
ISR(TIMER0_OVF_vect)
//Interrupt bei Timer0 Overflow
{
Zaehler++;
Zaehler2++;
}
ISR(INT0_vect)
{
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
flanke = 0;
}
if (flanke == 0)
{
stop = TCNT1;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
flanke = 1;
z1++;
}
}
Ich würd sagen, Du hast da einen Denkfehler im Programm.
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
flanke = 0;
}
if (flanke == 0)
{
stop = TCNT1;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
flanke = 1;
z1++;
Wenn die flanke 1 ist wird die if Anweisung ausgeführt und am Ende flanke=0 gesetzt.
dadurch wird aber sofort wieder die zweite if anweisung für flanke == 0 ausgeführt.
Du müsstest also von der ersten if anweisung aus die zweite überspringen, sonst wird ser Interrupt immer nur bei der steigenden Flanke ausgeführt.
Mal ne Frage - Testet ihr sowas nicht mit dem AVR - Studio aus ?
Da wär Dir das sofort aufgefallen.
Ich halt auch die Verwendung des Timers 0 für gefährlich.
Wenn der Interrupt 0 kurz vor einem Überlauf des Timers 0 aktiv wird, kann der Timer 0 schon wieder auf 0 stehen, ohne aber das externe Überlauf register zu erhöhen. Was dann einen Messfehler von 0,256 ms zur Folge hat.
Ich würd den Timer 1 frei laufen lassen, solange du nicht am TCNT 1 register rummanipulierst, kannst Du diesen Timer sogar noch für andere Aufgaben verwenden und du hast eine zuverlässige 16Bit Auswertung.
Die Impulswerte können durch subtraktion in der INT 0 Routine ermittelt werden.
Hallo,
da mmuss ich Dir Recht geben. Das hatte ich nicht gesehen.
Hatte unabhängig davon gerade mal das zweite If durch ein Else ausgetauscht, das sollte doch dieses Problem ebenfalls beheben, oder?
Mein Problem wird dadurch allerdings nicht gelöst, funktioniert trotzdem nicht.
Mein Programm wird trotzdem nicht weiter ausgeführt und die Ausgaben zeigen auch nur Müll auf dem Display, kann aber natürlich das selbe Problem mit der Abarbeitung sein.
Und nein ich teste nicht im AVR Studio, ich teste direkt im Controller ;)
Für AVR-Studio war ne Registrierung notwendig, oder?
Mein ISR sieht jetzt so aus:
ISR(INT0_vect)
{
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
flanke = 0;
}
else
{
stop = TCNT1;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
flanke = 1;
z1++;
}
}
Für AVR-Studio war ne Registrierung notwendig, oder?
Nö, soweit ich weiß ist da keine Registrierung nötig.
Müsste was Neues sein.
Der Vorteil ist halt, du kannst im Simulator vom Studio einzelne Eingänge von Hand setzen oder löschen, Du hast ne Uhr und nen Zyklenzähler drin, Du kannst alle Speicherinhalte auslesen usw.
Dadurch kannst Du dann virtuell auch alle Register anschauen und auch austesten, ob die gewünschten Routinen auch wirklich wie gewünscht ausgeführt werden.
Lediglich mit Zeitschleifen ist das immer ein kleines gerödel, weil die im Studio halt sehr lange brauchen für nen Durchlauf.
Was auch immer ein wenig problematisch ist, wenn der AVR mit anderen Chips interagieren muss. Alle Leitungen zum richtigen Zeitpunkt zu setzen ist immer ein kleineres Problem. Standard LCD's zu simulieren ist auch immer etwas schwierig.
Aber für so ne popelige Servoroutine klappt das allemal.
Dann muss ich mir das auf der Webseite noch einmal anschauen, ich meine letztens gesehen zu haben das man da Name und Adresse usw. angeben mußte um den Download zu starten.
Aber auch ohne muss es ja eigentlich Laufen, kann ja nicht sein das der Controller (ob nun Mega8 oder, 16 oder 32) schon bei der Auswertung von einem Signal überfordert ist. Sonst laufen zur Zeit ja nur einfache Zähler hoch die dann über If ein paar Ausgänge setzten und rücksetzen.
Das ist eigentlich das was mich etwas wundert :(
Da hast Du schon recht,
So ein AVR langweilt sich mit so einer Servoauswerteroutine, aber wenn ein Programm- (Denk-) fehler drin ist, hilft halt die ganze Geschwindigkeit nichts.
Ich wollte Dich mit dem Hinweis auf das Überlaufproblem der 8 Bit Timer nicht schocken, dieser Fehler wird sicherlich in den seltensten Fällen zum tragen kommen.
Da das Timing aber in diesem Fall von einer externen Quelle stammt, kann das Problem halt hin und wieder mal auftreten.
Leider will er aber trotzdem noch nicht so wie ich. Ich habe nun schon den Timer0 deaktiviert und immer noch kein Erfolg.
Sooooo dämlich kann ich mich doch auch nicht angestellt haben :(
Ich kann leider dein Prog nicht austesten weil ich nicht mit Win AVR arbeite.
Wie ist das ?
Wird ein gesetztes Byte durch die Anweisung beim MCUCR Register zurückgesetzt ?
Wenn das nicht so ist müsstest Du das Register mit & und einem Wert der alle Bits auf 1 setzt, bis auf das zu löschende Bit z.B. 0b11111110 .
Dieser Befehl müsste das Letzte Bit eines Wertes löschen.
Im MCUCR sind doch das ISC01 und das ISC00 Bit gesetzt
Wenn Du also das ISC01 mit dem Inhalt des MCUCR veroderst, bleibt doch das ISC00 gesetzt, und der Controller reagiert wieder auf die steigende Flanke ?
Wie wärs, wenn du Assembler Befehle zum setzen und löschen der Bytes verwenden würdest
#asm
sbi MCUCR,ISC01; ASSEMBLER Befehl zum setzen eines Bits in einem I/O Register
sbi MCUCR,ISC00
#endasm
bzw.
#asm
cbi MCUCR,ISC00; ASSEMBLER Befehl zum löschen eines Bits in einem I/O Register
sbi MCUCR,ISC01
#endasm
Die ASM Einbindung geht bei CodeVision so, wie es bei Win AVR geht weiß ich nicht.
if (flanke == 1)
{
start = TCNT1;
Diese Zeile in Deinem Quellcode meine ich ->MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
flanke = 0;
Das mit dem Sttzen des Bits auf null kann ich noch einmal versuchen.
Könnte ein Problem sein, ich dachte halt das es dann auf Null gesetzt ist. Aber wenn ich mir das recht überlege, woher sollte es null sein ;)
Ich probier es mal.
Hallo nocheinmal,
ich habe noch ein wenig expirimentiert und habe es geschafft ersteinmal meine Impulsdauer in ms anzuzeigen. Da hatte ich die Variable falsch deklariert (statt int32_t als int).
Das Prinzip funktioniert also schon einmal.
Nun habe ich aber immer noch das Problem das meine blinkenden LED's durcheinander kommen.
Es steht also nicht mehr das ganze Programm, sondern das blinken ist unregelmäßig (nicht so wie programmiert).
Das möchte ich jetzt gern noch als nächstes lösen.
Wo könnte da noch mein Fehler liegen, denn wie schon geschrieben, nur wegen dem einen Signal was ich auwerten möchte (lieber noch 1-2 andere zusätzlich) kann ja der µC noch nicht an der Leistungsgrenze sein.
und sas lächerliche LED blinken ist mit Sicherheit auch nicht so rechenintensiv ;)
Hier noch einmal der Programmcode wie er jetzt ist:
int main(void)
//Hauptprogremm
{
//Variablen der Steuerwelle 0 bis Reset
int LED1 = 0;
int LED2 = 250;
//int LED3 = 50;
//int LED4 = 100;
//int LED5 = 0;
//int LED6 = 0;
//int LED7 = 0;
//int LED8 = 0;
//int LED9 = 0;
//int LED10 = 0;
//int LED11 = 0;
//int test = 300;
int Reset = 500;
// Ende LED Steuerwellenvorgabe
init_digital(); // Ports initialisieren (eigene Funktion)
init_timer(); // Timer initialisieren (eigene Funktion)
init_interrupt();
lcd_ini();
flanke = 1; //Flankenmerker
impuls = 0;
sei(); //Interupts aktivieren
while(1)
{
lcd_gotopos(1,1);
lcd_writezahl(impuls,1,0);
if (PIND & (1<<PIND5))
{
PORTC |= (1<<PC5); //Bit1 auf High setzen
}
// Blaulicht (Blitzer) Transistor T1
if (Zaehler == LED1)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 50)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
if (Zaehler == LED1 + 120)
{
PORTB |= (1<<PB1); //Bit1 auf High setzen
}
if (Zaehler == LED1 + 170)
{
PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T1
//************************************************** **************************
// Blaulicht (Blitzer) Transistor T2
if (Zaehler == LED2)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 50)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
if (Zaehler == LED2 + 120)
{
PORTB |= (1<<PB2); //Bit2 auf High setzen
}
if (Zaehler == LED2 + 170)
{
PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
}
//ENDE Blaulicht (Blitzer) Transistor T2
//Zähler Reset
if (Zaehler >= Reset)
{
Zaehler = 0;
}
//************************************************** **************************
if (!(PIND & (1<<PIND5)))
{
PORTC &= ~(1<<PC5);
}
} //while
} //ENDE main
ISR(TIMER0_OVF_vect)
//Interrupt bei Timer0 Overflow
{
Zaehler++;
}
ISR(INT0_vect)
{
if (flanke == 1)
{
start = TCNT1;
MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
MCUCR &= ~(1<<ISC00);
flanke = 0;
}
else
{
stop = TCNT1;
impuls = stop - start;
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
flanke = 1;
}
}
Ich danke zwischendurch mal allen die mir hier schon mit Tips geholfen haben
Hubert.G
10.04.2007, 23:14
Versuche es mal ohne LCD-Anzeige, wenn du darin hängst funktionieren zwar die ISR aber das andere nur mit verzögerung.
Hallo Hubert,
das hat geholfen, danke.
Nun kann ich mein Signal auswerten wie ich es gern hätte.
Ist zwar schade das ich dann meine Werte nicht zu testzwecken auf dem Display habe, aber da kann ich ja ggf. ne Anteige auf Tastendruck einbauen. Denn die werte brauch ich ja um darauf reagieren zu können.
Aber das hat mich einen großen Schritt weitergebracht.
Hubert.G
11.04.2007, 16:40
Dein LCD-Prog verwendert warscheinlich R/W nicht, da ist dann eine fixe Wartezeit eingebaut und das ist der Grund des Übels.
Hubert
Hallo Hubert,
ich habe gerade mal wegen dem Display mal nachgesehen. Auf dem von mir verwendeten Board ist R/W wirklich nicht verwendet (es liegt auf Masse). Und im dazugehorigen Displaycode (den es dazu zum download gibt) sind auch delay's drin.
Na ja, nicht so schlimm, zum Testen kann ich mir ja dann ein Programm schreiben welches mir den wert nur anzeigt um einstellungen im eigentlichen Programm zu machen.
An dem Mega8 wo diese Funktion erst einmal zum Einsatz kommen soll ist auch kein Display vorgesehen ;)
Bin mit eurer Hilfe ja zu meinem eigentlichen Ziel gekommen. Notfalls kann ich ja den wert per serieller Schnittstelle an einen weiteren µC übertragen der dann nur die Aufgabe hat die Anzeige zu verwalten.
Hubert.G
11.04.2007, 23:25
Es gibt fertige LCD-Code die R/W verwenden z.B. von P.Fleury mit denen sollte es kaum Probleme geben.
Hubert
Hast Du da auch ggf. einen Link? (am besten sogar deutschsprachig ;) )
Hubert.G
12.04.2007, 10:15
http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html
www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
www.roboternetz.de/wissen/index.php/LCD-Modul_am_AVR
Danke, das werd ich mir dann mal zu gemüte führen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.