mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Delay timing Problem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Pierre G. (bqube)


Bewertung
-1 lesenswert
nicht lesenswert
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);
}

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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?

von Pierre G. (bqube)


Bewertung
0 lesenswert
nicht lesenswert
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

von booze (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hattest du damals unwissend ein Problem, daß jetzt rauskommt.

von Johann Klammer (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
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.

von Georg M. (g_m)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Hannes (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hast du in den Fuses CLK/8 ausgewählt? Vermutlich schon, ist bei den 
meisten AVR Standard.

von Pierre G. (bqube)


Bewertung
0 lesenswert
nicht lesenswert
Wenn ich heut abend zu Hause bin mach ich mal ein screen shoot der 
eingestellten Fuses

von Hannes (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
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.

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
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
void Setup(void)
{
  SteuerPort |= (1 << 0);
  _delay_us(5);
  SteuerPort &= ~(1 << 0);
}

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
while (1) {
  LED_on();
  _delay_ms(500);
  LED_off();
  _delay_ms(500);
}

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.

von Janos (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Wolfgang (Gast)


Bewertung
1 lesenswert
nicht lesenswert
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

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Pierre G. schrieb:
> obwohl der interne Quarz mit 1mhz gewählt wurde

Sicher?
Zeig mal die Fusebytes.

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Pierre G. (bqube)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich teste gleich mal die idee mit der blinkfrequenz von 1s und im anhang 
schicke ich einmal einen Screenshoot von den Fuses.

von Pierre G. (bqube)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Zeig doch mal das .lss-File (als Dateianhang).

von Forist (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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?

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
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
void Setup(void)
{
  _delay_us(1);
  SteuerPort |= (1 << 0);
  _delay_us(2);
  SteuerPort &= ~(1 << 0);
  _delay_us(1);
}

und genauso in der Text() Funktion.

von Pierre G. (bqube)


Angehängte Dateien:

Bewertung
-1 lesenswert
nicht lesenswert
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
>
>
> void Setup(void)
> {
>   _delay_us(1);
>   SteuerPort |= (1 << 0);
>   _delay_us(2);
>   SteuerPort &= ~(1 << 0);
>   _delay_us(1);
> }
> 
>
> 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.
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>
#define DatenPort PORTB
#define SteuerPort PORTD

void Setup(void)
{
  _delay_us(1);
  SteuerPort |= (1 << 0);
  _delay_us(2);
  SteuerPort &= ~(1 << 0);
  _delay_us(1);
}

void Text(void)
{
  _delay_us(1);
  SteuerPort |= (1 << 0);
  _delay_us(2);
  SteuerPort |= (1 << 2);
  _delay_us(2);
  SteuerPort &= ~(1 << 0);
  _delay_us(2);
  SteuerPort &= ~(1 << 2);
  _delay_us(1);
}

int main(void)
{
  DDRB = 0xFF;
  DDRD = 0xFF;
  PORTB = 0x00;
  {
    _delay_ms(15);
    DatenPort = 0b00110000; //Interface auf 8-Bit setzen
    Setup();
    DatenPort = 0x00;

    _delay_ms(5);
    DatenPort = 0b00110000; //Interface auf 8-Bit setzen
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00110000; //Interface auf 8-Bit setzen
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00110000; //Interface auf 8-Bit setzen
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00111000; //2-zeilig, 5x8-Punkt-Matrix
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00001000; //Display aus
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00000001; //Display löschen
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00000110; //Kursor nach rechts wandernd
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 0b00001100; //Display ein
    Setup();
    DatenPort = 0x00;

    _delay_us(120);
    DatenPort = 'T';    // T Senden
    Text();
    DatenPort = 0x00;
  }


  

  while(1)
  {
  PORTD |= (1<<6);
  _delay_ms(500);
  PORTD &=~(1<<6);
  _delay_ms(500);
  }
}

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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?

von Pierre G. (bqube)


Bewertung
0 lesenswert
nicht lesenswert
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

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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. ;-)

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Das Listing ist korrekt für F_CPU = 1MHz.
Diese Loop dauert 3 Zyklen * 40 = 120 Zyklen;
  d0:  28 e2         ldi  r18, 0x28  ; 40
  d2:  2a 95         dec  r18
  d4:  f1 f7         brne  .-4        ; 0xd2 <main+0x46>

    _delay_us(120);

Zeig mal das Listing für 8MHz.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Hugo H. (hugohurtig1)


Angehängte Dateien:
  • preview image for Da.jpg
    Da.jpg
    56,2 KB, 67 Downloads

Bewertung
0 lesenswert
nicht lesenswert
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)

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Pete K. (pete77)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Hugo H. (hugohurtig1)


Bewertung
0 lesenswert
nicht lesenswert
Pete K. schrieb:
> 32000000 ist dann wohl etwas zu viel.

Du bist ja ein ganz schlauer Typ.

von c-hater (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Pierre G. (bqube)


Bewertung
0 lesenswert
nicht lesenswert
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.
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>

int main(void)
{
  DDRC = 0xFF;
  DDRD = 0xFF;
  
  
  _delay_ms(15); // Reset Abwarten
  
  PORTC = 0b00110000; // 8 Bit Modus muss 3 mal gesendet werden.
  _delay_us(5);
  
  PORTD |=  (1<<7);  // Enable auf PORTD Bit7
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_ms(5);    // Interne verarbeitung abwarten
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_ms(5);      // Interne verarbeitung abwarten
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC =   0b00110000;  // 8 Bit Modus senden
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC =  0b00111000;  // 8 Bit / 2 Zeilen / 5x8 Matrix senden
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC = 0b00001000;    // Display AUS
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC = 0b00000001;    // Display Löschen
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC = 0b00000110;    // Kurser nach rechts kein Display shift
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100);
  PORTC = 0b00001100;    // Display Ein
  _delay_us(5);
  
  PORTD |=  (1<<7);
  _delay_us(5);
  PORTD &=~ (1<<7);
  _delay_us(5);
  
  _delay_us(100); // T
  PORTC = 'T';
  _delay_us(5);
  PORTD |= (1<<5);
  _delay_us(5);
  PORTD |= (1<<7);
  _delay_us(5);
  PORTD = 0x00;
  PORTC = 0x00;
  _delay_us(5);
  
  
  
  while(1)
  {
    PORTD |= (1<<6);
    _delay_ms(500);
    PORTD &=~ (1<<6);
    _delay_ms(500);
  }
}

von Holger L. (max5v)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Pierre G. (bqube)


Bewertung
0 lesenswert
nicht lesenswert
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.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.