Moin und Schönen Sonntag zusammen.
Nachdem ich mit meinem Programm fertig bin, wollte ich mich nun an
einige Änderungen setzten.
Unter anderem beinhaltet dies auch, das die UART entsprechend der im
EEPROM abgelgten Einstellung sich auf eine der verwendeteten
Übertragungsraten einstellt und somit dann auch zB mit 115200 Baud Ihre
Datenströme überträgt.
mein Ansatz sieht im Kern wie folgt aus.
1
UBAUD=9600;// Akuelle Übertragungsrate
2
EE_R_Baud();
3
switch(_BAUD)
4
{
5
case1:{UBAUD=9600;break;}
6
case2:{UBAUD=19200;break;}
7
case3:{UBAUD=57600;break;}
8
case4:{UBAUD=115200;break;}
9
}
10
11
_delay_ms(100);
12
13
uart(true);
zu kurzen Erklärung.
Damit ich überhaupt erst mal von außen war reinbekommen Wird UBAUD
vordefiniert. somit liegt es meiner Überlegung nach nur auf der Hand,
das der Rest mehr oder weniger übersprungen wird, da nicht die Werte
enthalten sind, welche ich vorgebe.
Nachdem ich allerdings via
1
$23>
dem EEPROM sagen, das der die Konstante für 57600 Baud schreiben soll,
was er ja auch definiv macht ist es mir ein Rätsel, warum er auch deinen
9600 Baud bleibt.
In der Hoffnung, das ihr meinen Gedankenkang nachvollziehen könnt lege
ich mal noch einige Programmauszüge und Definitionen in aufgerufener
Reihenfolge bei.
Lesen des Wertes
1
voidEE_R_Baud(void)
2
{
3
_BAUD=eeprom_read_byte((uint8_t*)EE_BAUD_2);
4
return;
5
}
6
7
#define EE_BAUD_2 0x00F
Schreibnen des Wertes
1
if(rxd[0]=='2')
2
{
3
Write_BAUD((int)rxd[1]);
4
}
5
6
voidWrite_BAUD(charValue)
7
{
8
ee_write_BAUD(Value);
9
}
10
11
voidee_write_BAUD(uint8_tBAUD)
12
{
13
eeprom_write_byte((uint8_t*)EE_BAUD_2,BAUD);
14
}
Weiterhin nochmal das 2 Logs für euch sowie im Bildanhang ein ScreenShot
Wo initialisierst du dann den UART? Der Programmteil scheint ja das
Problem zu sein, ist aber in den Schnipseln nicht vorhanden.
Noch ein Tipp. Wenn du das EEPROM beim erstmaligen Programmieren mit
sinnvollem Kram vorbesetzen willst, kannst du das so machen:
Matthias S. schrieb:> Wo initialisierst du dann den UART? Der Programmteil scheint ja das> Problem zu sein, ist aber in den Schnipseln nicht vorhanden.
du meinst diese Zeilen?
1
voiduart(boolfast)// doppelte Bautrate
2
{
3
unsignedcharx=0x00;
4
if(!(fast)){
5
UBRRL=(TAKT/(16ul*UBAUD))-1;// Baudrate mit TAKt und BAUD
6
UBRRH=0;
7
}
8
else{
9
UBRRL=(TAKT/(8ul*UBAUD))-1;// Baudrate mit TAKt und BAUD
10
UBRRH=0;
11
}
12
UCSRA|=(1<<U2X);// U2X einfache / Doppelte Bautrate * 16/8 je nach vorauswahl
13
UCSRB|=(1<<TXEN)|(1<<RXEN);// Sender und Empfänger ein
Nun da ich diese im Kern auf dem Buch:
*Mikrocomputertechnik mit Controllern der ATMEL AVR-RISC-Familie*
habe und nur nach meinen Bedürfnissen umgeschrieben habe glaube ich
nicht, das da der Fehler ist, lasse mir aber gerne das Gegenteil zeigen.
Matthias S. schrieb:> Noch ein Tipp. Wenn du das EEPROM beim erstmaligen Programmieren mit> sinnvollem Kram vorbesetzen willst, kannst du das so machen:>
> Damit wird ein *.eep File erzeugt, was du beim erstmaligen Schreiben des> MC ins EEPROM programmieren kannst.
Danke für den Tip.
Das ist etwas, was ich schon lange gesucht habe.
Aber wird etwas Aufwand werden, um dies richtig einzubauen, da ich
Cast-Probleme auf mich zukommen sehen werde. (uint8_t *) und (uint8_t)
Ich wuerde erst mal die verschiedenen Teile trennen und einzeln testen.
Also senden und empfangen, und EEPROM lesen und schreiben.
Also UART von Konstanten initilisieren, Konstanten senden und mit dem PC
empfangen.
UART ab dem EEPROM initialisieren und ab dem EEPROM lesen und per UART
senden.
Mit dem PC senden, mit dem UART emfangen, mit dem UART zuruecksenden,
und mit dem PC empfangen.
Mit dem PC senden, mit dem UART emfangen, ins EEPROM schreiben, per
Programmer auslesen und kontrollieren.
>umgeschrieben habe glaube ich>nicht, das da der Fehler ist,
UCSRA |= (1 << U2X); // U2X einfache / doppelte Baudrate
U2X wird in der Funktion immer gesetzt, egal ob "fast" oder nicht.
Maik G. schrieb:>> uint8_t EE_BAUD_2 __attribute__((section(".eeprom")))= 3;>> > Damit wird ein *.eep File erzeugt, was du beim erstmaligen Schreiben des>> MC ins EEPROM programmieren kannst.>> Danke für den Tip.> Das ist etwas, was ich schon lange gesucht habe.> Aber wird etwas Aufwand werden, um dies richtig einzubauen, da ich> Cast-Probleme auf mich zukommen sehen werde. (uint8_t *) und (uint8_t)
Lesen tue ich die EEPROM Zelle dann mit
1
UBAUD=eeprom_read_byte(&EE_BAUD_2);
2
// und schreiben mit
3
cli();
4
eeprom_busy_wait();
5
eeprom_write_byte(&EE_BAUD_2,UBAUD);
6
(sei);
Übrigens haben einige wenige AVR Probleme mit Adresse 0 des EEPROM.
Weils bei mir nicht auf jedes bisschen Platz im EEPROM ankommt, setze
ich auf Adresse 0 meistens einen dummy, um dieses Problem zu vermeiden.
торфкопф schrieb:> Ich wuerde erst mal die verschiedenen Teile trennen und einzeln testen.> Also senden und empfangen, und EEPROM lesen und schreiben.>> Also UART von Konstanten initilisieren, Konstanten senden und mit dem PC> empfangen.> UART ab dem EEPROM initialisieren und ab dem EEPROM lesen und per UART> senden.> Mit dem PC senden, mit dem UART emfangen, mit dem UART zuruecksenden,> und mit dem PC empfangen.>> Mit dem PC senden, mit dem UART emfangen, ins EEPROM schreiben, per> Programmer auslesen und kontrollieren.
Dies war genau das, wie ich an Anfang vorgegangen bin.
Allstepbystep.
mache ich bei Lazarus nicht anders.
Funktion schreiben, Testen und versuchen alle Bugs bewusst zu finden.
auf Konsolen-ebene geht es zwar auch mit mehreren Debug- und Infozeilen
aber wenn da schon im Vorfeld möglicherweise der Wurm drin ist helfen
diese auch nicht.
Bin halt erst durch die Anpassungen darauf aufmerksam geworden, das da
was schief läuft
holger schrieb:>>umgeschrieben habe glaube ich>>nicht, das da der Fehler ist,>> UCSRA |= (1 << U2X); // U2X einfache / doppelte Baudrate>> U2X wird in der Funktion immer gesetzt, egal ob "fast" oder nicht.
Goldener Hinweiß auf diese Zeile.
Gerade in der Literatur noch mal belesen und der Klassiker
Matthias S. schrieb:> Maik G. schrieb:>>> uint8_t EE_BAUD_2 __attribute__((section(".eeprom")))= 3;>>> > Damit wird ein *.eep File erzeugt, was du beim erstmaligen Schreiben des>>> MC ins EEPROM programmieren kannst.>>>> Danke für den Tip.>> Das ist etwas, was ich schon lange gesucht habe.>> Aber wird etwas Aufwand werden, um dies richtig einzubauen, da ich>> Cast-Probleme auf mich zukommen sehen werde. (uint8_t *) und (uint8_t)>> Lesen tue ich die EEPROM Zelle dann mit>
1
>UBAUD=eeprom_read_byte(&EE_BAUD_2);
2
>// und schreiben mit
3
>cli();
4
>eeprom_busy_wait();
5
>eeprom_write_byte(&EE_BAUD_2,UBAUD);
6
>(sei);
7
>
Interrupt manipulieren willst du mir damit sagen.
Matthias S. schrieb:> Übrigens haben einige wenige AVR Probleme mit Adresse 0 des EEPROM.> Weils bei mir nicht auf jedes bisschen Platz im EEPROM ankommt, setze> ich auf Adresse 0 meistens einen dummy, um dieses Problem zu vermeiden.
also empfiehlst du mir, da erst am der EEPROM 0x01 werte zu schreiben?
Nach dieser Info macht es sinn und da habe am ende nochmal 12 Bit frei
bekommen.
Schade, das gerade diese Erfahrungswerte nicht in jeder Litereatur
angemerkt werden. Aber dafür sind gerade die Informationen von euch so
wichtig für jemanden, der in gewissen Punkten Quasi Neuling ist.
Maik G. schrieb:> Interrupt manipulieren willst du mir damit sagen.
Auch, und das Übergeben der Adresse mit &.
Maik G. schrieb:> also empfiehlst du mir, da erst am der EEPROM 0x01 werte zu schreiben?
Schaden tut es jedenfalls nicht. Hatte selbst bei moderneren AVR ab und
zu mal Probleme mit Adresse 0.
Habe mir gerade mal eine *.eep via Bless erstellt.
in der ersten sind die Werte wie ich diese gerne im EEPROM hätte
1
:01000000FF2017010100001
2
:00000001FF
und im 2ten, wie diese mir von Code:Blocks geliefert werden.
1
:10000000FF5D020001070001000200000000014244
2
:0100100003EC
3
:00000001FF
Nun die Große Frage...
Welche von beiden ist die, welche ich schreiben sollte?
Ich würde aus dem bauch sagen. die erste.
Dies die dazugehörige Definition im ganzen-
Maik G. schrieb:> Dies die dazugehörige Definition im ganzen-> uint8_t EE_Dummy EEMEM = 0xff;> uint8_t EE_SN_Fuse EEMEM = 0x5D;> uint8_t EE_SN_Year_1 EEMEM = 2;> uint8_t EE_SN_Year_2 EEMEM = 0;> uint8_t EE_SN_Year_3 EEMEM = 1;> uint8_t EE_SN_Year_4 EEMEM = 7;
....
Wenn du die alle in EEMEM definierst, landen sie auch alle im EEPROM.
Code:Blocks macht also nur, was du vorgegeben hast. Wenn du also jede
Zahl des Datums als ein Byte definierst, bleibt das auch so. Du suchst
ein Format wie 'Packed BCD', das ist aber nicht so mein Ding. Da gibts
hier Leute, die das besser können. Ich würde fürs Jahr einfach ein
uint16_t nehmen und das als word ins EEPROM schreiben. Für Monat und Tag
je ein Byte und die Lfd. Nummer wieder als uint16_t (wenn das reicht).
Hi
Hast Du diese eep-Datei Mal gebrannt?
Denke, da kommen genau die Werte raus, Die Du wünscht.
Denke weiter, daß die eep-Datei auch in dem Intel-Hex-Format (Prpfsumme
ect.pp.) vorliegt.
MfG
Matthias S. schrieb:> Maik G. schrieb:>> Dies die dazugehörige Definition im ganzen->> uint8_t EE_Dummy EEMEM = 0xff;>> uint8_t EE_SN_Fuse EEMEM = 0x5D;>> uint8_t EE_SN_Year_1 EEMEM = 2;>> uint8_t EE_SN_Year_2 EEMEM = 0;>> uint8_t EE_SN_Year_3 EEMEM = 1;>> uint8_t EE_SN_Year_4 EEMEM = 7;> ....>> Wenn du die alle in EEMEM definierst, landen sie auch alle im EEPROM.> Code:Blocks macht also nur, was du vorgegeben hast. Wenn du also jede> Zahl des Datums als ein Byte definierst, bleibt das auch so. Du suchst> ein Format wie 'Packed BCD', das ist aber nicht so mein Ding. Da gibts> hier Leute, die das besser können. Ich würde fürs Jahr einfach ein> uint16_t nehmen und das als word ins EEPROM schreiben. Für Monat und Tag> je ein Byte und die Lfd. Nummer wieder als uint16_t (wenn das reicht).
das mit den uint16t war mein erster Gedanke, den ich aber wieder sehr
schnell verworfen habe, da ich Probleme hatte diese dann zu übergeben,
und die sollen auch so im EEPROM landen. wobei EE_BAUD_2 die wichtigste
ist.
ggf. ändere ich die Position.
unabhängig davon stört mich ja nur die Verwaltung der automatischen
Baudeinstellung, aber da werd ich mir mit 4 LEDs Abhilfe schaffen, hätte
ich eher mal drauf kommen sollen.
posti schrieb:> Hi>> Hast Du diese eep-Datei Mal gebrannt?> Denke, da kommen genau die Werte raus, Die Du wünscht.
Der Post entstand genau aus diesem Grund, da ich eine geschrieben hatte.
Welche Info möglicherweise noch wichtig wäre.
Verwende einen Atmega16 mit 8MHz.
Maik G. schrieb:> da ich Probleme hatte diese dann zu übergeben,> und die sollen auch so im EEPROM landen.
Öh, wie jetzt - Probleme? Es gibt z.B. die Funktionen
eeprom_write_word() und eeprom_read_word(), die mit uint16_t genauso
klarkommen wie ihre entsprechenden Kumpels für Bytes.
Habe mir das Ganze nochmal durch den Kopf gehen lassen und bin vorerst
zu dem Entschluss gekommen, das ich die Bautrate erstmal nur Manuell
eintrage und somit mit 19200 BAUD bei 8MHz arbeite, wodurch sich meine
UART nun von
1
voiduart(boolfast)// doppelte Bautrate
2
{
3
UBAUD=9600;// Akuelle Übertragungsrate
4
unsignedcharx=0x00;
5
if((!)fast){
6
UBRRL=(TAKT/(16ul*UBAUD))-1;// Baudrate mit TAKt und BAUD
7
UBRRH=0;
8
UCSRA|=(0<<U2X);// U2X eindache Bautrate * 16
9
}
10
else{
11
UBRRL=(TAKT/(8ul*UBAUD))-1;// Baudrate mit TAKt und BAUD
12
UBRRH=0;
13
UCSRA|=(1<<U2X);// U2X Doppelte Bautrate * 8
14
}
15
UCSRB|=(1<<TXEN)|(1<<RXEN);// Sender und Empfänger ein
geändert hat.
zum einem habe ich da denn Vorteil, das ich selber durch meine Verdrehte
Logik nicht durcheinander komme und ich kann es noch besser lesen als
vorher.
Weiterhin habe ich auch den Eindruck, das sich meine Software an der
*.eep verschluckt.
1
:03000000FF5D039E
2
:00000001FF
Wie ich darauf komme?
Habe mir mal eine Kontrolle eingebaut
Wie erkenntlich ist will ich eine LED blinken lassen. Da ich bei 250ms
und 1000ms nicht wirklich viel sehe habe ich diese je 3 mal angesetzt,
was das Programm jedoch unnötig aufbläht.
Den rest des EEPROM schreibe ich dann wie gewünscht über meine Externe
Software.
Gerade mal wieder den Kopfzermartert, weil ich mich gewundert habe,
wieso ich meine eep nicht auf den Chip bekomme.
dabei waren die Lösungen da so sibmle, das wohl Niemand daran gedacht
hat mal die FuseBits ins Auge zu fassen...
Naja. nun kann ich 100 pro und ohne größere Probleme weiterarbeiten
hoffe ich doch mal...