Forum: Mikrocontroller und Digitale Elektronik RS485 Probleme zwischen Mikrocontroller und PC


von Marcel D. (diablokiller999)


Angehängte Dateien:

Lesenswert?

Hi Leute!
Ich habe ein sehr nerviges Problem zwischen meinem Mikrocontroller ( 
EFM32 TG110F32 ) und meinem PC. Ziel ist es, einen Bootloader zu 
schreiben, nur leider funktioniert die Übertragung nicht.

Auf dem PC habe ich kein kleines Programm, welches eine .bin Datei 
öffnen, je 8 Byte ausliest und zum Controller sendet. Dieser empfängt 
das Paket mit Prüfsumme und gibt entsprechend Rückmeldung, ob die 
Checksumme korrekt ist. Auf die Antwort folgt das nächste Paket. 
Zwischen den Paketen schläft der Controller und wird per USART-Interrupt 
geweckt.

An sich keine schwere Sache, nur scheint mal ein Paket auf der einen 
oder anderen Seite nicht an zu kommen oder falsche Pakete?

Wie auch immer, mit Debuggern auf beiden Seiten klappt das 
Ping-Pong-Spiel der Pakete im Regelfall ( aber auch nicht immer ), ich 
finde einfach den Fehler nicht, ist es ein Logik-Problem das mir alles 
verhagelt?

Ich habe ja die Befürchtung, dass mein RS485->USB-Adapter mit dazwischen 
funkt, anders kann ich mir das Verhalten nicht erklären. Mit einer 
Baudrate von mageren 9600 kommt es zum gleichen Ergebnis. Ein 
verschicken der Pakete mit HTerm funktioniert übrigens tadellos ( mit 
deaktiviertem CRC ). Somit denke ich, es liegt wohl eher an der 
PC-Seite. Habe euch die Sources mal in den Anhang getan, eventuell könnt 
ihr ja etwas finden oder mir den entscheidenden Tipp geben. Seit 4 Tagen 
hänge ich schon am selben Problem, es ist zum verrückt werden -.-'

von Björn P. (bjrn_g)


Lesenswert?

Wie macht sich denn die teilweise nicht funktionierende Kommunikation 
bemerkbar?
Springen Bits oder fehlen Bytes?
Schonmal den EFM32 mit nem Debugger benutzt und einen Fehler gefunden?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Marcel D. schrieb:
> Zwischen den Paketen schläft der Controller und wird per USART-Interrupt
> geweckt.

Das Schlafen würde ich mal testweise unterlassen. Wie lange dauert es, 
bis der µC aus dem Schlaf heraus wieder komplett arbeitsfähig ist? Ich 
weiß zumindest, dass bei AVRs je nach "Tiefe" des Schlafs schon eine 
gewisse Zeit vergehen kann.

von Marcel D. (diablokiller999)


Lesenswert?

Björn G. schrieb:
> Wie macht sich denn die teilweise nicht funktionierende Kommunikation
> bemerkbar?
> Springen Bits oder fehlen Bytes?
> Schonmal den EFM32 mit nem Debugger benutzt und einen Fehler gefunden?

Die macht sich bemerkbar in dem einfach nicht mehr aufgewacht wird bzw. 
die While-Schleife auf der PC-Seite nicht verlassen wird. Da der 
Interrupt auf dem µC schon beim ersten Bit springt, muss das Problem 
wohl auf der PC-Seite sein. Es scheint als würde er manchmal willkürlich 
Daten empfangen und aus der Schleife raus springen oder keine Antwort 
empfangen und in der Schleife bleiben. Die Implementierung am Controller 
sollte so funktionieren wie sie ist, habe damit das Hauptprogramm 
geschrieben, welches der Bootloader schreiben soll. Dort funktioniert 
alles einwandfrei, auch von der PC-Seite aus.

Das Schlafen ist übrigens kein Problem, laut Datenblatt ist der 
Controller aus EM1 sofort wieder da. Erst in den darunter liegenden Modi 
benötigt er wake-up-time.

von Kay I. (imperator)


Lesenswert?

Hallo Marcel,

hast Du die Möglicheit, in die RS485-Kommunikation eine Art Sniffer zu 
hängen und so mal mitzuschneiden, was denn da tatsächlich auf dem Bus 
passiert?
So ist es schon mal leichter, en Fehler auf PC oder uC einzugrenzen. 
Weiterhin glaube ich nichts blind, was in Datenblättern behauptet wird, 
da ich schon zu oft Bugs im Prozessor hatte, die noch nicht mal im 
Errata standen.

von Marcel D. (diablokiller999)


Lesenswert?

Kay Imperator schrieb:
> Hallo Marcel,
>
> hast Du die Möglicheit, in die RS485-Kommunikation eine Art Sniffer zu
> hängen und so mal mitzuschneiden, was denn da tatsächlich auf dem Bus
> passiert?

Könnte n LogicAnalyzer an den Bus packen und schauen was so läuft.
Müsste ich morgen mal ausprobieren wie gut das so klappt.

Ich denke wie gesagt aber nicht, dass mir der EnergyMode dazwischen 
funkt, die Abfrage des Busses ist Interrupt gesteuert und bedarf keiner 
weiteren Aktivität außer bei einem Signal das Register zu leeren. 
Außerdem funktioniert es, wie gesagt, in einem anderen Programm 
einwandfrei und das sogar mit 3,5MBaud/s ( statt wie jetzt mit 1MBaud/s 
).
Schauen was der LogicAnalyzer so bringt...

von Kay I. (imperator)


Lesenswert?

Man könnte noch versuchen, ein paar Test-Byte zu Fuß zu schicken, 
während der uC schläft und auf seine Daten wartet ...
z.B. mit einem irgend einem Serial-Terminal und dann sehen, wie der uC 
reagiert.

Wäre z.B. mit diesem Tool recht komfortabel:
http://www.heise.de/download/hterm.html

von Peter D. (peda)


Lesenswert?

Marcel D. schrieb:
> Zwischen den Paketen schläft der Controller und wird per USART-Interrupt
> geweckt.

Ich mache das immer grundsätzlich so, daß ich zuerst nur die Funktion 
implementiere.
Und erst, wenn alles einwandfrei läuft, überlege ich, ob Stromsparen 
einen Effekt haben könnte und füge es dann hinzu.

von johnny (Gast)


Lesenswert?

Hallo,
wie groß ist denn deine .bin?
Wo wird sie gespeichert?
Kann die der Controller sie überhaupt speichern/ablegen?

Fragen über Fragen :)

MfG

von Marcel D. (diablokiller999)


Lesenswert?

Habe nun anscheinend den Fehler gefunden, mein PC-Programm schickte ab 
und an ein paar Nullen zuviel mit auf den Weg, was meinen Controller 
durcheinander brachte. Bin nun auf die Boost-API umgestiegen, diese 
erledigt den Job doch weitaus besser und alles läuft nun einwandfrei bis 
auf das Springen zur Zieladresse. Versuche es gerade mit diesen 
Funktionen
1
void BOOT_jump(uint32_t sp, uint32_t pc)
2
{
3
  (void) sp;
4
  (void) pc;
5
  /* Set new MSP, PSP based on SP (r0)*/
6
  __asm("msr msp, r0");
7
  __asm("msr psp, r0");
8
9
  /* Jump to PC (r1)*/
10
  __asm("mov pc, r1");
11
}
12
13
void BOOT_boot(void)
14
{
15
  uint32_t pc, sp;
16
17
  uint32_t *bootAddress = (uint32_t *)(0x4000 + 0x0100);
18
19
  /* Set new vector table */
20
  SCB->VTOR = (uint32_t)bootAddress;
21
22
  /* Read new SP and PC from vector table */
23
  sp = bootAddress[0];
24
  pc = bootAddress[1];
25
26
  /* Do a jump by loading the PC and SP into the CPU registers */
27
  BOOT_jump(sp, pc);
28
}

Leider springt er mir immer wieder nur an den Anfang des Programms 
zurück, nicht an meine neue FW. Habe das andere Programm mit einer 
abgeänderten Linker-File gefüttert, damit diese erst ab Adresse 0x4000 
anfängt.
1
MEMORY
2
{
3
  FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 16384
4
  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 4096
5
}
Hab ich da was übersehen? >_>

@Jonny:
- Bin ist 11KB groß
- Ja, er kann sie speichern
- Wird ab Adresse 0x4000 bis 0x6890 gespeichert :)

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.