Forum: Mikrocontroller und Digitale Elektronik Hex File mit Bootloader => UART geht nicht


von J@N (Gast)


Lesenswert?

Hallo,

ich habe ein Projekt mit einem Arduino Mini Pro für das mir die Pins 
ausgegangen sind. Ich Programmiere die uC eigentlich immer über AVR 
Studio und mit STK 500 ISP Programmer. So habe ich mit Atmel angefangen 
und dabei bin ich geblieben. Die Arduius habe ich mir immer nur als 
billige Hardware gekauft und trotzdem wie gehabt geflasht. Nun da ich 
ISP jetzt abschalten muss, musste ich mit der Programmierung über UART 
befassen. Dazu habe ich erstmal mit dem Arduino Studio einen Bootloader 
mittels STK500 geflasht. Dann habe ich mit AVRDude ein mit dem AVR 
Studio Erzeugtes HEX File geflashed.

avrdude -p ATMEGA328P -c arduino -P COM2  -U 
flash:w:"E:\Dropbox\Projekte\Cocktailomat\Relais\UART_Relais_16x\Debug\M 
y  Project.hex":r

(der Befehl wurde von einem AVRDudu GUI erzeugt)

Eigentlich sollte der Controller mit meiner Software nun auf einen UART 
Befehl 0xA0 mit 0xA1 antworten. Das tat er nicht. Ich hab das Programm 
geändert, dass er immer 0xA1 alle 500ms sendet. Ich empfange andere 
Zeichen, als wenn die Baudrate nicht passt.

Wenn das Programm mit dem STK 500 und AVR Studio Flashe geht es. Ich 
Flashe eigentlich genau das selbe Kompilat. Wobei ich beim AVR Studio 
die .elf auswähle und im AVRDude die .Hex. In der Elf stehen aber doch 
glaube ich nur Zusatzinformationen, die das STK500 Braucht. Der müsste 
doch trotzdem die Hex reinladen.

Der Booloader ist doch nur nach dem Power Up Aktiv. Der dürfte mir die 
UART Schnittstelle doch auch nicht Umbiegen oder?

von Einer K. (Gast)


Lesenswert?

Fuses?

von J@N (Gast)


Lesenswert?

Hab ich mir mit dem stk500 angeschaut. Sie ändern sich nicht.

Hab gesehen das ich die isp pins einfach anders verwenden könnte ohne 
die Füße dafür abzuschalten. Mich würde es aber trotzdem mal 
interessieren warum das mit dem bootloader nicht hin haut.

von Einer K. (Gast)


Lesenswert?

J@N schrieb:
> Hab ich mir mit dem stk500 angeschaut. Sie ändern sich nicht.
---
Irgendwas hast du falsch gemacht, oder dein Pro Mini ist kaputt.
Denn sonst würde es funktionieren.

ISP/SPI brauchst du nicht per Fuse abzuschalten, nur einfach nicht 
nutzen, dann sind die Pins frei(genug).

Mein Vorschlag:
Stecke den Pro Mini per STK500 an die ArduinoIDE
Pro Mini auswählen (MHz beachten)
"Bootloader brennen" drücken

Dabei werden auch die Fuses gesetzt.

von S. Landolt (Gast)


Lesenswert?

Vielleicht liegt es ja auch am Programm selbst, wie sieht das denn aus 
(Stichwort Ver-Oderung bei der Initialisierung)?

von Joachim B. (jar)


Lesenswert?

Arduino Fanboy D. schrieb:
> Mein Vorschlag:
> Stecke den Pro Mini per STK500 an die ArduinoIDE
> Pro Mini auswählen (MHz beachten)
> "Bootloader brennen" drücken

meiner wäre Bootloader vom neuen nano optiboot nutzen, ggffs. den 
Bootloader anpassen F_CPU 8 MHz für 3,3V Betrieb und/oder die 
uploadrate, Optiboot 115k klemmt bei mir ab und an ich habe einen 
weiteren Menüpunkt hinzugefügt
habe jetzt für die Arduino IDE 4 Menüpunkte

new Bootloader full MEM low UPLOAD
new Bootloader full MEM high UPLOAD
new Bootloader old MEM high UPLOAD
old Bootloader low MEM low UPLOAD

von Bernd K. (prof7bit)


Lesenswert?

J@N schrieb:
> Hab ich mir mit dem stk500 angeschaut. Sie ändern sich nicht.

Dann hast Du was übersehen. Die Fuses werden anders gesetzt worden sein 
wenn die Baudrate im einen Fall richtig und im andern Fall falsch war, 
das ist die naheliegendste Ursache.

Oder Du initialisierst in Deiner Anwendung den UART unvollständig, 
verlässt Dich auf Defaultwerte ab Reset aber der Bootloader hat sie 
geändert, daher ein unterschiedliches Verhalten wenn er aus dem Reset 
kommt vs wenn er aus dem Booloader kommt, das wäre die nächste 
Möglichkeit die mir einfällt. Also setze nicht nur einzelne Bits indem 
Du sie mit dem existierenden (aber leider unbekannten!) Zustand 
veroderst sondern schreibe alle Register mit komplett neuen eigenen 
Werten frisch.

Das Verodern oder Verunden mit dem vorherigen Zustand beim 
Initialisieren eines Gerätes ist sowieso eine Unsitte die manchmal von 
Anfängern propagiert wird und die man sich schnellstens abgewöhnen 
sollte. Das macht man nur wenn man den vorherigen Zustand genau kennt 
oder wenn Teile des selben Registers von verschiedenen Treibern 
verwendet werden die sich nicht gegenseitig auf die Füße treten sollen 
und das kommt beim AVR eher weniger oft vor.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Joachim B. schrieb:
> meiner wäre ....
Ja, wäre auch auch wohl machbar und u.U. sinnvoll ...

Aber bitte erst damit experimentieren, wenn die Grundfunktion 
hergestellt ist. Denn erst dann weiß man, dass alles tut, und von der 
Basis ab, ist genug Raum für eigene Varianten.

von J@N (Gast)


Lesenswert?

Danke euch allen für den Input.

Wenn ich den Bootloader mit Arduino Studio Flashe, ist der 8 MHz 3,3V 
328P ausgewählt. Das passt. Beim Flashen kommen folgende Meldungen:

avrdude: WARNING: invalid value for unused bits in fuse "lock", should 
be set to 1 according to datasheet
This behaviour is deprecated and will result in an error in future 
version
You probably want to use 0xff instead of 0x3f (double check with your 
datasheet first).
avrdude: WARNING: invalid value for unused bits in fuse "lock", should 
be set to 1 according to datasheet
This behaviour is deprecated and will result in an error in future 
version
You probably want to use 0xcf instead of 0x0f (double check with your 
datasheet first).

Die Fuses sind: (Nach dem Flashen des Bootloaders)

Extended: 0xFD
High : 0xDA
Low: 0xFF

Lockbits: 0xCF

Meldung 1 muss ja die Low Fuses betreffen weil er sagt ob ich mir sicher 
bin das ich 0xFF nutzen will.

Da müsste ich dann CKDIV8 und CKOUT stztzen um auf 0x0F zu kommen. Ich 
will aber die Frequenz nicht teilen

0x0F kann bei bei den Lockbits gar nicht einstellen zumindest nicht mit 
den Drop Down Feldern aus dem AtmelStudio. Könnte es einfach rein 
schreiben aber wer weiß was dann passiert.

void USART_init()
{
  UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);  //UART 
Senden/Empfangen einschalten;Interrupt enable
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);         // Asynchron 9N1, kein Parity
  //Baudrate einstellen
  UBRR0H = UBRR_VAL >> 8;
  UBRR0L = UBRR_VAL & 0xFF;
}

UART wird vollständig initialisiert

von Einer K. (Gast)


Lesenswert?

Irgendwie witzig...
AVRdude sagt explizit, dass eins der Lockbits nicht richtig konfiguriert 
ist, und du findest/suchst dann bei den Low Fuses.

OK, darum muss man sich nicht kümmern, denn es funktioniert so, und die 
Arduino Truppe wird irgendwann den Core reparieren, so dass die Meldung 
nicht mehr kommt.
...

J@N schrieb:
> UART wird vollständig initialisiert

Auch witzig...
Du hast vermutlich ein Baudrate Problem, und hältst die Generierung der 
Baudrate geheim....

J@N schrieb:
> Arduino Studio
Was ist das?
Wohl die die Arduino IDE...
Denn ein Arduino Studio gibt es nicht.

Oder meinst du das Atmel Studio mit der Arduino Erweiterung?

J@N schrieb:
> Wenn ich den Bootloader mit Arduino Studio Flashe, ist der 8 MHz 3,3V
> 328P ausgewählt. Das passt.
Das kannst nur du wissen!
Ist das wirklich ein Pro Mini mit 8MHz Quarz/Resonator?

von J@N (Gast)


Lesenswert?

Ja ok mit den Fuses hab ich mich nicht viel beschäftigt. Aber was mich 
an der Meldung wundert. Er schreibt "Lock" und gibt mir zwei 
verschiedene Werte, die angeblich drin stehen und die rein sollten. Ich 
aber nur 1 Byte für Lock Bits. Die Werte von denen er schreibt, dass sie 
angeblich drin stehen, finde ich in den Low Fuses wieder.

Wenn ich den Code mit dem AtmelStudio Flashe, ohne Bootloader drauf 
klappt es. Daher ist da kein Fehler im Code. Es kam lediglich die Frage 
auf, ob ich vielleicht ein Register nicht vollständig überschreibe und 
vom Bootloader alte Werte drin stehen, die nicht drin stehen wenn ich 
ohne Bootloader Flashe. Daher nur der Auszug.

Wenn ich die High Fuse Bits ändere (Bootloader Size), dann schreibt das 
Arduinostudio sie zurück. Also die Fuses setzt er wohl so wie er sie 
braucht. Jetzt bekomme ich es irgendwie gar nicht mehr hin, dass der 
Controller was sendet wenn ich mit Avrdude Flashe. Wenn ich den 
Booloader drauf habe und mit Atmel Studio Flashe ohne vorher zu löschen, 
dann sendet der übrigens auch nichts. Ich muss vorher ein Erase machen. 
Springt der Atmega irgendwie in eine falsche Startroutine oder so?

von Einer K. (Gast)


Lesenswert?

Ich wiederhole:
1. Es gibt kein Arduino Studio
2. Teste mit der Arduino IDE
2.a. Bootloader brennen
2.b. Programm aus der Arduino IDE per USB Seriel Adapter hochladen
2.c. Serielle Kommunikation mit deiner Anwendung.


Dann weißt du, ob mit dem Pro Mini was nicht stimmt, oder mit deinem 
Kram.

von S. Landolt (Gast)


Lesenswert?

> UART wird vollständig initialisiert

Das stimmt nicht, es fehlt UCSR0A.U2X0.
Ob das irgendeine Bedeutung hat, muss/kann unser Arduino-Spezialist 
beantworten, ich selbst kenne diesen Bootloader nicht.

von S. Landolt (Gast)


Lesenswert?

PS:
> Daher nur der Auszug.

Warum die Mühe mit dem Auszug, ein Programm, das
> immer 0xA1 alle 500ms sendet
kann ja kaum viel größer sein?

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> Ob das irgendeine Bedeutung hat, muss/kann unser Arduino-Spezialist
> beantworten, ich selbst kenne diesen Bootloader nicht.

Ich leider auch nicht so gut....
Noch nie in den Quellcode dieses Bootloaders geschaut.
War noch nicht nötig, und es gibt einige verschiedene in der Arduino 
Welt...

Aber ich würde mir die UART Register, im Arduino Code, vor 
Serial.begin(9600) anschauen/speichern, und einmal danach.
Dann weiß ich, wie der Bootloader die UART hinterlässt, und wie die 
Serial Klasse ihn einstellt.

Das kann man dann schön mit der Doku im ATMega328p Datenblatt 
vergleichen.
Und auf Plausibilität prüfen.

J@N schrieb:
> Die Werte von denen er schreibt, dass sie
> angeblich drin stehen, finde ich in den Low Fuses wieder.
Aus (Küchen)psychologischer Sicht ist das ein großes Problem....
Du suchst an einer Stelle, die deiner Idee entspringt und folgst nicht 
der Meldung des Programms.
Das ist nicht gut!
Und es ist auch nicht gut, dass du jetzt NOCHMAL begründest, warum du 
das tust. Damit verhinderst du wirksam, die Einsicht.

Und wie S. Landolt bemerkte, hast du nicht alle Register der UART frisch 
initialisiert, trotz Ansage. Hier hat eine falsche/unvollständige 
Annahme das Nachlesen im Datenblatt verhindert.

Das zieht sich wie ein roter Faden durch deine Postings.
Fehlendes Wissen wird durch Annahmen/Fantasie ersetzt, und als Wahrheit 
behandelt.
Ja, wir Menschen können trotz unvollständigem Wissen agieren. Das ist in 
Notlagen recht praktisch, da es schnelle Reaktionen erlaubt. Auch im 
sozialen Umfeld kann man das tun, denn da besteht die Chance, dass die 
jeweiligen Sozialpartner das kompensieren. In Sachen EDV funktioniert 
das allerdings eher nicht. Man muss schon eine Kompetenzstufe von 3, 
eher 4, erreicht haben um, auf diesem Gebiet, recht zuverlässig intuitiv 
handeln zu können.

von J@N (Gast)


Lesenswert?

Ich habe nur Code Auszüge gepostet, weil das Programm wesentlich größer 
ist. Nach dem Init kommen ein Haufen andere Funktionen, die zur Zeit 
nicht aufgerufen werden, weil ich sie in der Schleife auskommentiert 
habe und dort nur das _delay_ms(500) und das USART0_Send_Byte() 
aufgerufen habe.

Ob das ne Bedeutung hat wenn man das UCSRA.U2X nicht initialisiert? 
Klar! Es verdoppelt die Baudrate. Und genau dort war der Fehler. Ich 
habe das UCSRA nicht beschrieben, weil ich fälschlicherweise angenommen 
habe, dass ich es nur zum Lesen brauche. Daher hab ich genau den Teil 
gepostet obwohl ich mir eigentlich sicher war es richtig gemacht zu 
haben. Zum Glück hat es  S. Landolt aufmerksam gelesen und als Bernd K. 
mich auf die Idee brachte dort zu suchen, war mir eigentlich klar, dass 
der Fehler dort auch am Wahrscheinlichsten ist.

Seltsamer Weise geht jetzt mein AVRDudeGUI nicht, was ich zuerst 
verwendet habe. Damit habe ich bei meinen Versuchen gestern dem 
Controller gar nichts mehr entlocken können. Mit AVRDUDESS 2.6 geht es 
aber. Ich habe meinen Code nochmal ohne UCSRA = 0; generiert. Dann 
empfange ich falsche Daten. Mit UCSRA = 0; im Code läuft es dann. Das 
Gute ist, den Fehler werde ich bestimmt nicht nochmal machen :D.

von S. Landolt (Gast)


Lesenswert?

> den Fehler werde ich bestimmt nicht nochmal machen

Es werden viele weitere folgen, und da lohnt es sich, die Vorgehensweise 
zu überdenken:

> Programm wesentlich größer ... Haufen andere Funktionen...auskommentiert

Da verliert man den Überblick, und wenn man sich derart festgefahren hat 
wie hier, reduziert man das Programm auf ein Minimum; so war z.B. in der 
'USART_init' noch immer der Receive-Interrupt freigegeben, obwohl nur 
gesendet werden sollte.
  Dieses Minimum kann man dann auch den Helfern hier vorstellen/zumuten; 
und nicht das, von dem man selbst glaubt, es sei relevant (Watzlawicks 
'Verlorener Schlüssel').


am Rande:
> UCSR0C = (1<<USBS0)|(3<<UCSZ00); // Asynchron 9N1, kein Parity
9N1? Ich sehe 8N2.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.