@ Thomas (Gast)
>Ja, laut der Anleitung musste die Voreinstellung stimmen.>Stimmt aber leider nicht, das Register ist bei mir auf 0x00.
Und genau das brauchst du ja!
MFG
Falk
Du kannst das nicht lesen, weil du dann immer nur das Alternativregister
(ist ja ein Doppelregister) liest! Tu dir und uns einen Gefallen und
glaube dem Datenblatt, dass die Voreinstellung OK ist und mach einfach
weiter an dieser Stelle.
Mit diesem Programm müsste mir der Hyperterminal doch eigentlich das
Hallo ausgeben, oder?
von RS232 über Nullmodemkabel an PC und die Hyperterminal-Einstellungen
wie bei USART.
Thomas wrote:
> von RS232 über Nullmodemkabel an PC und die Hyperterminal-Einstellungen> wie bei USART.
Wenn Du das Pollinbrett hast, dann brauchst Du ein Verlängerungskabel
(1:1) und kein Nullmodemkabel.
Ich muss euch nochmal nerven.
Bekomme nur ein Zeichen (ein großes C mit Punkt drüber) auf dem
Hyperterminal dargestellt, wenn ich beim Hyperterminal eine Baudrate
tiefer als bei USART_init.
Benutze einfaches serielles Verlängerungskabel, Flusssteuerung aus.
Hatte dein Eingang TX RX vom MAX232 schon überbrückt, dann bekomme ich
das Echo vom Hyperterminal zurück.
Was mache ich falsch? Wo muss so ein externer Quarz ran?
Danke...
@ Thomas (Gast)
>Bekomme nur ein Zeichen (ein großes C mit Punkt drüber) auf dem>Hyperterminal dargestellt, wenn ich beim Hyperterminal eine Baudrate>tiefer als bei USART_init.
Warum tiefer? Sie muss GLEICH sein.
>Benutze einfaches serielles Verlängerungskabel, Flusssteuerung aus.>Hatte dein Eingang TX RX vom MAX232 schon überbrückt, dann bekomme ich>das Echo vom Hyperterminal zurück.
D.h. dein Kabel + MAX sind OK. Bleiubt nur noch der uC.
>Was mache ich falsch? Wo muss so ein externer Quarz ran?
An den uC. Und dann auch die AVR Fuses so setzen, dass der auch
verwendet wird.
MFg
Falk
Thomas wrote:
> Was mache ich falsch?
Meine gerade aus der Reparatur gekommene Kristallkugel behauptet, dass
du noch mit dem internen RC-Oszillator (1 MHz bei Vcc = 5 V) arbeitest
statt mit einem Quarz.
Thomas wrote:
> Was mache ich falsch? Wo muss so ein externer Quarz ran?
Wo sind denn jetzt die ganzen Experten, die noch vor ein
paar Tagen behauptet haben mit dem internen Takt gäbe es
bei UART überhaupt keine Probleme?
Bin schon neugierig wie ihr diesen Fall jetzt lösen wollt.
Karl heinz Buchegger wrote:
> Wo sind denn jetzt die ganzen Experten, die noch vor ein> paar Tagen behauptet haben mit dem internen Takt gäbe es> bei UART überhaupt keine Probleme?
Es gibt nur ein einziges Problem damit, vermute ich mal: er schwingt
einfach mal nicht auf 16 MHz...
So, funktioniert. Externer Quarz war der Schlüssel zur Lösung.
Nachdem ich die Fusebits gesetzt hab ging es.
Ich danke euch alle...
nochmal ne frage zum internen Clock, auf welcher Frequenz läuft der beim
Atmega32. Hab irgendwo 1Mhz gelesen. Ist das richtig?
Danke nochmal!
Gast wrote:
> Internal Calibrated RC Oscillator Operating Modes -> 1/2/4/8MHz
Beim ,,alten'' RC-Oszillator, das waren da noch vier verschiedene
Oszillatoren, und automatisch kalibriert wurde nur der erste
davon.
Die neueren AVRs (das beginnt beim ATmega88 & Co.) haben nur noch
einen RC-Oszillator, und der wird automatisch vorkalibriert (in
der Regel für einen Betrieb bei Vcc = 5 V). Der Oszillator selbst
läuft dort mit 8 MHz, allerdings ist im Auslieferungszustand die
CKDIV8-Fuse gesetzt, die den clock prescaler auf 1:8 voreinstellt,
sodass er effektiv auch wieder mit 1 MHz startet.
Mein Display funktioniert jetzt jedoch nicht mehr, sobald ich auf
externen Quarz umschalte. Kann das an den Delay Schleifen liegen, das
dort jetzt eine andere Zeit rein muss?
warum gebe ich dann die Frequnenz vom µC vor, wenn die sowieso abhängig
ist von intern oder externen Quarz?
#define F_CPU 16000000UL //CPU Takt vorgeben
#include <util/delay.h> //Header für delay
Mit der 16 x fachen Zeit (vorher 1Mhz intern, jetzt 16Mhz extern)
in delay geht es aber leider auch nicht.
Danke euch...
An den Parametern der _delay_XX-Aufrufe wird gar nichts geändert! Nur
die Taktfrequenz muss richtig angegeben werden. Wenn die stimmt, dann
stimmen auch die Wartezeiten.
Kann aber natürlich sein, dass dein Display einfach mal langsamer
ist als die Annahmen, die der Code gemacht hat (vielleicht braucht
der Controller einfach mehr Zeit, als der originale HD44780
spezifiziert hatte). Solange deine Delays alle auf Grund des
falschen Taktes 16x so lange waren, hat's dann noch funktioniert,
nun nicht mehr.
Auch muss man die maximalen Werte bei der _delay_ms und _delay_us
Funktion beachten.
Die Maximalwerte sind nämlich von der F_CPU abhängig und wenn die
eigenen Werte diese überschreiten, gibt es keine "Funktionsgarantie"
mehr.
Unter Umständen muss man also ein _delay_ms(LANGEZEIT) in mehrere
_delay_ms(KURZEZEIT) aufteilen.
Bei einem Wechsel von 1 MHz auf 16 MHz ist es nahezu sicher, dass hier
im Quellcode nachgearbeitet werden muss. Der Maximalwert bei 16 MHz ist
nur 1/16-tel des Wertes bei 1 Mhz...
Ging mit 16-fach auch nicht.
Also, habe das FuseBit auf 16MHz externen Quarz eingestellt,
danach ging das Display nicht mehr.
Hab jetzt in der Header von delay die 1Mhz durch 16Mhz ersetzt
#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
#define F_CPU 16000000UL // <-----Hier
#endif
In meinen Programmkopf steht trotzdem noch mein CPU Takt
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
Leider funktioniert es aber immernoch nicht. Habe auch spassighalber
mal die Delays verlängert. Auch keine Änderung!
Stefan "stefb" B. wrote:
> Auch muss man die maximalen Werte bei der _delay_ms und _delay_us> Funktion beachten.
...Steht aber auch alles in der erwähnten Dokumentation...
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
Das hat nur eine Wirkung, wenn F_CPU nicht anderswo definiert ist. Wenn
F_CPU anderswo definiert ist, wird der dortige Wert genommen.
Anderswo kann heissen in den Projekteinstellungen (project
configuration) von AVR Studio oder im Makefile, wenn du mit WinAVR
arbeitest oder AVR Studio mit einem externen Makefile arbeitest.
Benutze mal nur
#define F_CPU 16000000UL
und achte auf Warnungen bzgl. Redefinition von F_CPU bzw. ob das LCD
jetzt funktioniert.
Wenn du den LCD Code in einem extra *.c File hast, achte darauf, dass
dort auch die richtige F_CPU ankommen muss! Es nutzt nix das im main.c
zu setzen und im lcd.c wegen fehlendem F_CPU einen anderen Defaultwert
zu benutzen.
Johannes M. wrote:
> Stefan "stefb" B. wrote:>> Auch muss man die maximalen Werte bei der _delay_ms und _delay_us>> Funktion beachten.> ...Steht aber auch alles in der erwähnten Dokumentation...
Für 2008 habe ich mir vorgenommen, einmal am Tag das RTFM zu vermeiden
;-)
So läuft wieder mit den alten Delay Einstellungen.
Nur in der Header von delay die neue Frequenz eingestellt.
Muss jedoch den Optimierungsgrad auf von Os auf O0 (keine Optimierung)
stellen. Andere Optimierungsgrade gehen auch nicht.
Leider wird mein Programm dadurch zu groß.
Kann ich da noch was dran ändern?
Warum wird die Delay Funktion mit Optimiert?
Deine Zeiten sind zu kurz für dein Display!
Glaub's doch endlich, statt mit trial&error hier irgendwas
zusammenzuwurschteln.
Ermittle doch bitte mal einfach systematisch, welche der Zeiten du
vergrößern musst, damit das Display wieder ,,spielt''. U. U. ist es
nur eine einzige Zeit, an der du was drehen musst, z. B. die für den
E-Impuls.
Thomas wrote:
> So läuft wieder mit den alten Delay Einstellungen.> Nur in der Header von delay die neue Frequenz eingestellt.> Muss jedoch den Optimierungsgrad auf von Os auf O0 (keine Optimierung)> stellen.
Die Funktionen aus der delay.h funktionieren aber nur mit
eingeschalteter Optimierung korrekt. Dass es bei Dir jetzt funktioniert,
liegt mit Sicherheit daran, dass durch die abgeschaltete Optimierung die
Zeiten viel länger sind, als eingestellt.
Die delay Zeiten sind lang genug.
Hab den Grund jetzt raus gefunden. Und zwar frage ich ab einer betimmten
Stelle bei der Display init nur noch das Busy ab. Dazu werden die Werte
von PINB gelesen. Wenn das Display jedoch noch nicht fertig ist, gehe
ich in eine Schleife und Frage immer wieder Busy ab. Jedoch wird der
Wert an PINB nicht mehr aktualisert. Er bleibt in der Schleife hängen.
Hab es schon mit volatile PINB versucht. Klappt aber auch nicht. Werd
weiter suchen...
#define PINB* (volatile unsigned char*)0x16
//Funktion fragt das Busy des Display2 ab, ob Display bereit ist
//neue Befehle zu verarbeiten
void dis2_ready(void)
{
volatile unsigned char a=0;
unsigned char busy=1,status;
DDRB=0xF0; //B0-B3 Eingänge, B4-B7 Ausgänge
while (busy) //Schleife solange Busy=1
{
PORTB = 0x00; //EN2=0, RS=0, R/W=0
PORTB = PORTB | 0x10; //R/W=1
PORTB = PORTB | 0x80; //EN2=1
a=PINB; //PORTB lesen, High Nibbel 1
PORTB = PORTB &~ 0x80; //EN2=0
status = (a<<4) & 0xF0; //4x shifting links
PORTB = PORTB | 0x80; //EN2=1
a = PINB & 0x0F; //PORTB lesen, low Nibbel 2
PORTB = PORTB &~ 0x80; //EN2=0
status = status | a;
if ((status & 0x80)==0x00)
busy=0; //Busy=0 Abbruch
}
Leg da
> PORTB = PORTB | 0x80; //EN2=1> a=PINB; //PORTB lesen, High Nibbel 1
mal eine kleine Pause dazwischen und gib dem Display
ein bischen Zeit auf deinen Leseversuch zu reagieren
und die Daten auf den Bus zu legen
Karl heinz Buchegger wrote:
> ... mal eine kleine Pause dazwischen und gib dem Display> ein bischen Zeit auf deinen Leseversuch zu reagieren> und die Daten auf den Bus zu legen
Jaja, da bin ich seinerzeit auch drüber gestolpert bei meiner
LCD-Bibliothek. ;-) Das ist ein AVR-Feature (ist so dokumentiert):
Das Sampeln der Eingangsdaten an PINx erfolgt vor dem Aktivieren
der Ausgangsdaten von PORTx. Gesampelt wird auf der steigenden
Taktflanke des CPU-Taktes, aber die Ausgangsregister werden erst mit
der fallenden Flanke aktualisiert. Das LCD müsste also einige 100 ns
vorher bereits ahnen, dass es jetzt das BUSY-Bit ausgeben soll...
Ein einzelner NOP (oder jeder beliebige andere Befehl) dazwischen
genügt.
Mit ausgeschalteter Optimierung geht es, weil die PORTx- und PINx-
Aktivitäten dann über LDS/STS in mehreren Befehlen realisiert werden.