Moin moin liebe Gemeinde,
Ich hab mich nun nach Jahren wieder an die kleinen Käfer gewagt und bin
auf ein seltsames Problem gestoßen, ich hatte damals ein LCD Projekt
hier im Forum was auch super lief nun hab ich das ganze wieder aufgebaut
und bekomm das 16x2 Display nur zum laufen wenn die CPU mit 8mhz
definiert wird obwohl der interne Quarz mit 1mhz gewählt wurde.
Gibt es ein Problem mit der delay.h in der avr studio 7
MFG
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>
#define DatenPort PORTD
#define SteuerPort PORTB
void Setup(void)
{
SteuerPort |= (1 << 0);
_delay_us(5);
SteuerPort &= ~(1 << 0);
}
void Text(void)
{
SteuerPort |= (1 << 1);
SteuerPort |= (1 << 0);
_delay_us(5);
SteuerPort &= ~((1 << 0) | (1 << 1));
}
int main(void)
{
DDRB = 0xff;
DDRD = 0xff;
{
_delay_ms(15);
DatenPort = 0b00110000; //Interface auf 8-Bit setzen
Setup();
DatenPort = 0b00000000;
_delay_ms(5);
DatenPort = 0b00110000; //Interface auf 8-Bit setzen
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00110000; //Interface auf 8-Bit setzen
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00110000; //Interface auf 8-Bit setzen
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00111000; //2-zeilig, 5x8-Punkt-Matrix
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00001000; //Display aus
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00000001; //Display löschen
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00000110; //Kursor nach rechts wandernd, kein Display
shift
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 0b00001100; //Display ein
Setup();
DatenPort = 0b00000000;
_delay_us(120);
DatenPort = 'T'; // T Senden
Text();
DatenPort = 0x00;
}
while(1);
}
Gast
#6194109
Pierre G. schrieb: > Ich hab mich nun nach Jahren wieder an die kleinen Käfer gewagt und bin > auf ein seltsames Problem gestoßen, ich hatte damals ein LCD Projekt > hier im Forum was auch super lief nun hab ich das ganze wieder aufgebaut > und bekomm das 16x2 Display nur zum laufen wenn die CPU mit 8mhz > definiert wird obwohl der interne Quarz mit 1mhz gewählt wurde. Alsonoch mal ganz der reihe nach: welchen quarz hast du eingebaut welche frequenz musst du eintragen damit es läuft um welchen prozessor handelt es sich was hast du als taktquelle gewählt und wie hast du die CKDIV8 fuse eingestellt?
Verwendet wird ein Atmega16 an dem ein 16x2 LCD angeschlossen ist und das ganze über ein 5V Netzteil versorgt wird. Das LCD ist an PORTB Eingang 7-0 für die Daten und an PORTD Eingang 2-0 für RW RS und E angeschlossen. Der Mikrocontroller ist in dem Fusebits auf Grundeinstellung 1Mhz interner Quarz eingestellt Wenn ich den Code Compiliere mit #define F_CPU 1000000UL zeigt das Display nichts an aber sobald ich den Wert auf 8000000UL anhebe zeigt das Display das gewollte Zeichen an. MFG
Gast
#6194260
Vielleicht hattest du damals unwissend ein Problem, daß jetzt rauskommt.
Gast
#6194266
avr gcc hatte da das problem dass die NOPs verschwinden. Ich vermute dass es das ist. (Ich verwende den gcc nicht mehr fuer uC. Ist zu beschissen geworden.) Versuch an die disassembly zu kommen. ich glaube nm or objdump kann das. Dann kannst' die NOPs zaehlen.
Pierre G. schrieb: > Verwendet wird ein Atmega16 > > Der Mikrocontroller ist in dem Fusebits auf Grundeinstellung 1Mhz > interner Quarz eingestellt Was ist "interner Quarz"? Zeige bitte den Screenshot.
Gast
#6194287
Hast du in den Fuses CLK/8 ausgewählt? Vermutlich schon, ist bei den meisten AVR Standard.
Wenn ich heut abend zu Hause bin mach ich mal ein screen shoot der eingestellten Fuses
Gast
#6194468
Kannst den Fuse CKDIV8 auch einfach ausschalten (bzw. einschalten, je nach Programm) Brauchst nicht vorher nen screenshot zu senden. Dein uC läuft halt gerade mit 1Mhz / 8.
Pierre G. schrieb: > Verwendet wird ein Atmega16 an dem ein 16x2 LCD angeschlossen ist und > das ganze über ein 5V Netzteil versorgt wird. > > Der Mikrocontroller ist in dem Fusebits auf Grundeinstellung 1Mhz > interner Quarz eingestellt Es gibt keinen "internen Quarz". Du meinst wohl, er ist auf den internen RC-Oszillator gestellt und die CKDIV8 Fuse ist aktiviert, so daß er real mit 1MHz Takt läuft. > Wenn ich den Code Compiliere mit #define F_CPU 1000000UL zeigt das > Display nichts an aber sobald ich den Wert auf 8000000UL anhebe zeigt > das Display das gewollte Zeichen an. Das würde bedeuten, daß entweder - dein ATMega16 doch schneller als mit 1MHz läuft -oder- - das Timing für das LCD immer schon grenzwertig war -oder- - du sonst etwas falsch machst Compilierst du mit Optimierung? Ohne funktionieren die _delay* Funktionen nicht. Ferner fällt mir auf, daß du in
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
zwar die Länge der H-Zeit der Impulse an E großzügig auf 5µs setzt, nicht jedoch die Länge der L-Zeit. Für den ersten Punkt oben mach doch einen einfachen Test, schließ eine LED an irgendeinen IO an und laß die mit 1Hz Blinken mit einer Endlosschleife a'la
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
das ganze natürlich mit F_CPU auf 1000000. Wenn deine LED dann mit 1Hz blinkt, dann läuft die CPU wirklich mit 1MHz. Falls es doch 8MHz sein sollten, siehst du es direkt.
Gast
#6194611
Axel S. schrieb: > Der Mikrocontroller ist in dem Fusebits auf Grundeinstellung 1Mhz > interner Quarz eingestellt > > Es gibt keinen "internen Quarz". Du meinst wohl, er ist auf den internen > RC-Oszillator gestellt und die CKDIV8 Fuse ist aktiviert, so daß er real > mit 1MHz Takt läuft. > > Wenn ich den Code Compiliere mit #define F_CPU 1000000UL zeigt das > Display nichts an aber sobald ich den Wert auf 8000000UL anhebe zeigt > das Display das gewollte Zeichen an. > > Das würde bedeuten, daß entweder > > - dein ATMega16 doch schneller als mit 1MHz läuft -oder- Deine interpretation ist etwas merkwürdig, warum sollte die CPU schneller laufen, wenn man im Code eine höhere angeben muss? Er läuft mit 1Mhz und hat CKDIV8 an. Dadurch läuft er real nur mit 125khz. Damit die Software nun richtig läuft, wird dem Programm vorgegaukelt, 8 mal länger warten zu müssen (8mhz statt 1Mhz also 8 mal länger für Timer und sonstiges zählen) dadurch kommt er dann mit 125khz wieder auf 1Mhz. Oder anders, die Frequenz des internen Oszillators wird durch 8 geteilt mit dem Fuse CKDIV8, und dann wieder mit 8 multipliziert durch 8mhz anstatt 1Mhz Angabe. Am Ende kommt dann 1 als Multiplikator raus
Gast
#6195102
Janos schrieb: > Er läuft mit 1Mhz und hat CKDIV8 an Wo soll bei einem ATmega16 eine CKDIV8 fuse sitzen? Weder das DS noch der Fuse Calculator kennt die. http://www.engbedded.com/fusecalc
Pierre G. schrieb: > obwohl der interne Quarz mit 1mhz gewählt wurde Sicher? Zeig mal die Fusebytes.
Janos schrieb: > Axel S. schrieb: >> Der Mikrocontroller ist in dem Fusebits auf Grundeinstellung 1Mhz >> interner Quarz eingestellt >> >> Es gibt keinen "internen Quarz". Du meinst wohl, er ist auf den internen >> RC-Oszillator gestellt und die CKDIV8 Fuse ist aktiviert, so daß er real >> mit 1MHz Takt läuft. >> >> Wenn ich den Code Compiliere mit #define F_CPU 1000000UL zeigt das >> Display nichts an aber sobald ich den Wert auf 8000000UL anhebe zeigt >> das Display das gewollte Zeichen an. >> >> Das würde bedeuten, daß entweder >> >> - dein ATMega16 doch schneller als mit 1MHz läuft -oder- > > Deine interpretation ist etwas merkwürdig, warum sollte die CPU > schneller laufen, wenn man im Code eine höhere angeben muss? Das F_CPU Makro dient nicht zur Einstellung der Taktfrequenz. Mit diesem Makro teilst du <delay.h> mit, mit welcher Taktfrequenz dein Controller läuft, damit es ausrechnen kann, wieviele Durchläufe der Warteschleife gebraucht werden, um z.B. 5µs zu warten. Wenn man hier einen zu großen Wert angibt, dauert die Warterei entsprechend länger. Bei einem zu kleinen dann kürzer. > Er läuft mit 1Mhz und hat CKDIV8 an. Dadurch läuft er real nur mit > 125khz. Quatsch. Ich habe gerade erst mal selber in das Datenblatt schauen müssen (habe noch was mit dem ATMega16 gemacht). Der hat gar keine CKDIV8 Fuse. Allerdings kann der interne RC-Oszillator wahlweise mit 1, 2, 4 oder 8MHz laufen. Default ist 1MHz.
Ich teste gleich mal die idee mit der blinkfrequenz von 1s und im anhang schicke ich einmal einen Screenshoot von den Fuses.
Als nächstes hab ich ganz Simpel 1000ms an und 1000ms aus und siehe da genau das macht der Uc auch hatte den internen oszillator auf 8 Mhz erhört und das Programm darauf hin angepasst aber das Display regiert nicht hab auch das Display ausgetauscht selbes ergebnis. Meine nächste idee wäre es Extern einen quarz anzulöten und dann nochmal das selbe versuchen.
Zeig doch mal das .lss-File (als Dateianhang).
Gast
#6195498
Pierre G. schrieb: > Als nächstes hab ich ganz Simpel 1000ms an und 1000ms aus und siehe da > genau das macht der Uc auch hatte den internen oszillator auf 8 Mhz > erhört und das Programm darauf hin angepasst aber das Display regiert > nicht hab auch das Display ausgetauscht selbes ergebnis Von Satzzeichen hast du wohl noch nie etwas gehört oder ist das reine Faulheit?
Pierre G. schrieb: > Als nächstes hab ich ganz Simpel 1000ms an und 1000ms aus und siehe da > genau das macht der Uc auch hatte den internen oszillator auf 8 Mhz > erhört und das Programm darauf hin angepasst aber das Display regiert > nicht hab auch das Display ausgetauscht selbes ergebnis. An sich sieht dein Timing gut aus. Nur daß du halt die Setup- und Hold-Zeiten bezüglich des Impulses am E-Pin nicht einhältst. Probier mal
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
und genauso in der Text() Funktion.
Axel S. schrieb: > Pierre G. schrieb: >> Als nächstes hab ich ganz Simpel 1000ms an und 1000ms aus und siehe da >> genau das macht der Uc auch hatte den internen oszillator auf 8 Mhz >> erhört und das Programm darauf hin angepasst aber das Display regiert >> nicht hab auch das Display ausgetauscht selbes ergebnis. > > An sich sieht dein Timing gut aus. Nur daß du halt die Setup- und > Hold-Zeiten bezüglich des Impulses am E-Pin nicht einhältst. Probier mal > >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
> > und genauso in der Text() Funktion. Ändert leider nichts an der Funktion, hab das Program nun so abgeändert und die .lss Datei angehängt.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
Gast
#6195567
Pierre G. schrieb: > #ifndef F_CPU > #define F_CPU 1000000UL > #endif Soetwas kann eine ziemliche Falle sein. Ist F_CPU möglicherweise schon vorher in der IDE definiert, aber anders?
Wolfgang schrieb: > Pierre G. schrieb: >> #ifndef F_CPU >> #define F_CPU 1000000UL >> #endif > > Soetwas kann eine ziemliche Falle sein. > Ist F_CPU möglicherweise schon vorher in der IDE definiert, aber anders? ? Ich bin da leider schon echt lange raus aus dem Thema, gibt es denn irgendwo die möglich die frequenz für den Compiler einzustellen. MFG
Gast
#6195883
Pierre G. schrieb: > gibt es denn irgendwo die möglich die frequenz für den > Compiler einzustellen Der Compiler hat da nichts mit zu tun. Der nimmt, was er vom Präprozessor übergeben bekommt. Meist kann das in der IDE unter irgendwelchen Defines eingetragen werden. "avr studio 7" gibt es nicht. Entweder heißt deine IDE "Atmel Studio" oder du hast dich mit der "7" vertan. ;-)
Das Listing ist korrekt für F_CPU = 1MHz. Diese Loop dauert 3 Zyklen * 40 = 120 Zyklen;
1 | |
2 | |
3 | |
4 | |
5 | |
Zeig mal das Listing für 8MHz.
Gast
#6196021
Pierre G. schrieb: > Ich bin da leider schon echt lange raus aus dem Thema, gibt es denn > irgendwo die möglich die frequenz für den Compiler einzustellen. Das Stichwort dazu heißt "defines". In den meisten Entwicklungsumbegungen kann man Definitionen in den Projekteinstellungen vornehmen. Teileweise als Dialogfenster aufbereitet, teilweise als simple Liste von Name/Werte Päärchen, wobei Defines auch ohne Wert (nur mit Name) existieren können. Diese werden dem Compiler als Kommandozeilenparameter -D übergeben. Schau Dir mal an, wie diene Kommandozeile vom gcc Aufruf aussieht.
Gast
#6196075
Stefan ⛄ F. schrieb: > Diese werden dem Compiler als Kommandozeilenparameter -D übergeben. Auch um diese "defines" kümmert sich bereits der Präprozessor und der Compiler bekommt soetwas wie "F_CPU" gar nicht mehr zu sehen.
Wolfgang schrieb: > Ist F_CPU möglicherweise schon vorher in der IDE definiert, aber anders? Vermutlich da (Bild) :-) Project -> Properties (letzter Eintrag in der Auswahlliste)
Pierre G. schrieb: > Wolfgang schrieb: >> Pierre G. schrieb: >>> #ifndef F_CPU >>> #define F_CPU 1000000UL >>> #endif >> >> Soetwas kann eine ziemliche Falle sein. >> Ist F_CPU möglicherweise schon vorher in der IDE definiert, aber anders? > > ? Ich bin da leider schon echt lange raus aus dem Thema, gibt es denn > irgendwo die möglich die frequenz für den Compiler einzustellen. Der wesentliche Punkt ist IMHO nicht rüber gekommen. Es ist vollkommen egal, ob man F_CPU im Quelltext per #define festlegt oder ob man das in der Build-Umgebung macht (Makefile, IDE, $WHATEVER). Der Fehler besteht darin, beim Fehlen dieses Makros einfach einen aus den Fingern gesaugten Wert einzusetzen. Wenn man das wegläßt, dann wird <util/delay.h> eine Fehlermeldung werfen, daß F_CPU nicht definiert ist. Und das ist wesentlich hilfreicher, weil man dann weiß, daß man was vergessen hat. Der jetzige Zustand überdeckt den eigentlichen Fehler und macht ihn dadurch schwerer zu finden.
Gast
#6196363
Axel S. schrieb: > Es ist vollkommen egal, ob man F_CPU im Quelltext per #define festlegt Genau, die Falle ist die Verpackung der Festlegung in #ifndef ... #endif
Hugo H. schrieb: > Wolfgang schrieb: >> Ist F_CPU möglicherweise schon vorher in der IDE definiert, aber anders? > > Vermutlich da (Bild) :-) Project -> Properties (letzter Eintrag in der > Auswahlliste) 32000000 ist dann wohl etwas zu viel.
Pete K. schrieb: > 32000000 ist dann wohl etwas zu viel. Du bist ja ein ganz schlauer Typ.
Gast
#6196845
Axel S. schrieb: > Quatsch. Ich habe gerade erst mal selber in das Datenblatt schauen > müssen (habe noch was mit dem ATMega16 gemacht). Der hat gar keine > CKDIV8 Fuse. Allerdings kann der interne RC-Oszillator wahlweise mit 1, > 2, 4 oder 8MHz laufen. Default ist 1MHz. Das stimmt so nicht. Der Oszillator selber läuft immer mit ca. 8Mhz (sofern nicht mutwillig per OSCCAL davon abgebracht). Die Fuses der ollen Megas machen letztlich dasselbe wie die der modernen, sprich: sie steuern einen Prescaler. Der einzige Unterschied ist halt, dass man bei den moderneren Megas auch softwaremäßigen Zugriff auf den Prescaler hat, dafür aber eben weniger per Fuse festlegen kann, nämlich darüber nur noch aus zwei Varianten wählen kann, statt der vier der ollen Megas. Oder anders ausgedrückt: hier wurde schlicht eine Fuse eingespart, um sie anderen Zwecken widmen zu können.
Pierre G. schrieb: > ich hatte damals ein LCD Projekt > hier im Forum was auch super lief Nö. Dein Programm ist fehlerhaft, kann also nie gelaufen sein. Einige Befehle dauern 1,64ms, Du wartest aber nur 120µs. Dadurch werden nachfolgende Befehle nicht ausgeführt.
Guten Tag und vielen Dank für die großartige Hilfestellung hier im Forum, ich habe nun nochmal das Internet durchsucht und alles zusammengetragen was man zum Timing wissen sollte. Ich hab nun nochmal das komplette Programm neugeschrieben (Bitte kein Kommentar warum ich keine Funktionen benutzte für mich ist es so erstmal einfacher) aber das Ergebnis ist immer noch dasselbe. Nicht wundern warum der DatenPort sich geändert hat von B auf C, ich habe um Fehler eingrenzen zu können das ganze nun auf eine Lochraster Platine aufgelötet.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
Weiter oben im Thread wurde ein Bild von den Fuse Einstellungen gezeigt, aus dem ersichtlich ist das JTAG eingeschaltet ist. Ich bin mir nicht 100% sicher, meine aber mal gelesen zu haben, das es dadurch zu Problemen an den Pins PC2 - PC5 kommt.
Holger L. schrieb: > Weiter oben im Thread wurde ein Bild von den Fuse Einstellungen gezeigt, > aus dem ersichtlich ist das JTAG eingeschaltet ist. > Ich bin mir nicht 100% sicher, meine aber mal gelesen zu haben, das es > dadurch zu Problemen an den Pins PC2 - PC5 kommt. Okay danke das schau ich mir mal an.
Gast
#6200875
Holger L. schrieb: > ... zu Problemen an den Pins PC2 - PC5 kommt. JTAG - "We call it a Klassiker" ("When the JTAG interface is enabled, this pin can not be used as an I/O pin.)
Ich hab mal mit dem Handy ein Foto vom PORTD. 6 gemacht, wo man das Timing recht gut erkennen kann und ich finde da sieht man ganz gut die 500ms.
Geschafft … uff ich hab jetzt nach jedem Befehl die Wartezeit für den Nächsten Befehl auf 2ms angehoben und siehe da jetzt gibt das Display auch Zeichen aus. Ich hatte auch die Datenleitung vom Display wieder auf den PORTB gelegt, da auf PORTC einige PORT's High Signal tragen, kann man die PORT's auch über Fuses umschalten oder ist das nicht möglich. Mfg
Pierre G. schrieb: > Ich hatte auch die Datenleitung vom Display wieder auf den PORTB gelegt, > da auf PORTC einige PORT's High Signal tragen, kann man die PORT's auch > über Fuses umschalten oder ist das nicht möglich. Siehe... Holger L. schrieb: > Weiter oben im Thread wurde ein Bild von den Fuse Einstellungen > gezeigt, > aus dem ersichtlich ist das JTAG eingeschaltet ist. > Ich bin mir nicht 100% sicher, meine aber mal gelesen zu haben, das es > dadurch zu Problemen an den Pins PC2 - PC5 kommt.
Pierre G. schrieb: > ich hab jetzt nach jedem Befehl die Wartezeit für den > Nächsten Befehl auf 2ms angehoben Man muß nicht gleich übertreiben. Schau mal ins Datenblatt des HD44780. Es sind nur 2 Befehle, die max 1,64ms dauern.
Pierre G. schrieb: > ich hab jetzt nach jedem Befehl die Wartezeit für den > Nächsten Befehl auf 2ms angehoben und siehe da jetzt gibt das Display > auch Zeichen aus. Kanonen auf Spatzen. Du mußt nicht nach jedem Befehl 2ms warten. Sondern nur nach denen, die länger dauern. Und überhaupt: die deutlich bessere Strategie besteht darin, das BUSY Flag des Displays auszulesen. Wenn du das gemacht hättest, dann hätte es den ganzen Thread von Anfang an nicht gebraucht. Stumpfes Warten ist nur die zweitbeste (von zwei möglichen) Strategien.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.


