Forum: Mikrocontroller und Digitale Elektronik UART mit ATMega644 liest falsche Daten ein


von Tobias (Gast)


Lesenswert?

Hallo,
ich habe folgendes Minimalbeispiel gemacht um nur den UART des ATMega644 
zu testen. Der Interrupt wird ausgelöst, aber er empfängt kein Byte 170. 
Mit einem ATMega32 in der identischen Schaltung funktioniert es 
einwandfrei. Der Logicanalyzer bestätigt auch dass Bytes 170 ankommen, 
aber der ATMega644 erkennt es nicht. Die Frage ist natürlich wo der Code 
noch falsch ist. Was habe ich übersehn? Bin schon drei Tage dabei das 
irgendwie zum laufen zu kriegen, aber ich komm einfach nicht dahinter.
1
#include <avr/interrupt.h>
2
#define F_CPU 14745600L 
3
#include <util/delay.h>
4
#define BAUD 115200L
5
6
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)      //clever runde
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //reale Baudrate
8
9
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)      //Fehler in Promille
10
11
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
12
#error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
13
#endif
14
15
#define HOME_ADDR 2
16
17
volatile uint8_t FlagProcessRXByte = 0;
18
volatile uint8_t RXB;
19
20
21
ISR (USART0_RX_vect) {
22
  RXB = UDR0;
23
  FlagProcessRXByte = 1;
24
  PORTA ^= (1<< PA3);
25
}
26
27
void ProcessRXByte(void){
28
  if (RXB == 170) PORTA ^= (1<< PA4);
29
}
30
31
32
33
int main(void)
34
{
35
  _delay_ms(300);
36
  // Ausgänge definieren
37
  DDRA = (1<<PA2) | (1<<PA3) | (1<<PA4); //LED's User-Taste1 Home, Enter
38
  DDRC = (1<<PC2) | (1<<PC4);  // LED Usr-Taste3, LED Usr-Taste2
39
  DDRD = (1<<PD1) | (1<<PD3) | (1<<PD4) | (1<<PD7); //TX an MAX, externer Signalgeber, DE/RE von MAX, OC2 für internen Summer
40
  //Pullups der Tasterausgänge aktivieren
41
  PORTA = (1<<PA1) | (1<<PA5) | (1<<PA6);  // Enter, Usr1, Home
42
  PORTB = (1<<PB1);
43
  PORTC = (1<<PC1) | (1<<PC3);  // Usr3, Usr2
44
45
  UBRR0H = UBRR_VAL >> 8;
46
  UBRR0L = UBRR_VAL & 0xFF;
47
   
48
  UCSR0A = 0;
49
  UCSR0B = (1<<RXEN0)|(1<<TXEN0)| (1 << RXCIE0);      //UART TX einschalten
50
  UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);      //8 data, 2 stop bits
51
52
  _delay_ms(100);
53
  sei();  
54
  
55
  while (1)
56
  {
57
    if (FlagProcessRXByte == 1){
58
      FlagProcessRXByte = 0;
59
      ProcessRXByte();   
60
    }
61
  }
62
63
  return 0;                     
64
}

von Christopher G. (cbg)


Lesenswert?

Tobias schrieb:
> Mit einem ATMega32 in der identischen Schaltung funktioniert es
> einwandfrei.

Ich überfliege gleich mal den Code aber das riecht schon nach:
a) falscher Quarz oder
b) richtiger Quarz aber falsche Fusebit Einstellungen

Edit: Code schaut ansich in Ordnung aus. Die Delays sind zwar sinnlos 
und die Aufgabe von ProcessRXByte() kann man gleich in der RXC0 ISR 
erledigen aber Fehler konnte ich jetzt keinen entdecken. Ich penn aber 
auch gleich ein :)

von Tobias (Gast)


Angehängte Dateien:

Lesenswert?

danke schonmal,

aber das es sich um Hardware-Fehler handelt schließe ich aus, da die 
selbe Schaltung mit einem ATMega32 funktioniert.

Die Fuses sind wie auf dem angehängten Bild eingestellt.

von Tobias (Gast)


Lesenswert?

kann es sein dass der ATMega644 elektrische Unterschiede hat zum 
ATMega32? Dass er beim USART evtl einen anderen Threshold für High hat. 
Irgendworan muss es ja liegen.

von Karl H. (kbuchegg)


Lesenswert?

Hast du eine Möglichkeit, dir anzeigen zu lassen, was du anstelle der 
0xAA empfängst?

Hast du ausprobiert, was passiert, wenn du vom µC weg sendest. Empfängt 
ein angeschlossenes Terminal dann richtig?
Wenn nicht, wäre das ein Indiz dafür, dass mit der Baudrate/Taktfrequenz 
noch irgendetwas nicht stimmt.

von Bastler (Gast)


Lesenswert?

Verwendest du das selbe *.HEX?
Du compilierst schon neu mit entsprechendem Controller!?

von Tobias (Gast)


Lesenswert?

nein, ich kompilier natürlich schon extra für den 644.

Das empfangene Byte ansehen, sowie senden ist in der Schaltung beides 
ziemlich aufwendig. Wird also etwas dauern bis ich da mehr sagen kann, 
wenn es etwas gibt was ich vorher ausprobieren kann würde ich das gerne 
tun.

von Christopher G. (cbg)


Lesenswert?

Tobias schrieb:
> Das empfangene Byte ansehen, sowie senden ist in der Schaltung beides
> ziemlich aufwendig.

Poste mal Schaltplan und Board.

von Tobias (Gast)


Angehängte Dateien:

Lesenswert?

hier der Schaltplan

von Tobias (Gast)


Lesenswert?

so, nachdem ich jetzt nochmal Zeit hatte ein paar Sachen auszuprobieren:

Das Problem ist ja dass das Byte 170 nicht erkannt wird.
Bei einem Testprogramm das nur das Byte 170 sendet, kommt das bei einem 
Empfänger auch so an. Sprich am Takt von µC/Bus kann es nicht liegen.
Wenn ich nun das Byte 170 an den ATMega644 sende und dieser sendet das 
empfangene Byte zurück, dann kommt 192 an.

In Binar:
170:  10101010
192:  11000000

also auch nicht invertiert oder ähnliches. Und es kommt auch konstant 
die 192 zurück.

von slowslow (Gast)


Lesenswert?

Der Kondensator Cmax ist rechter Unsinn. Auch wenn diese Hardware in der 
anderen Schaltung funktioniert, so ist sie doch recht schrottig.

Für den Fall, daß der Ausgang des Max hochohmig ist, ist kein Pegel für 
den RX-Eingang definiert. Häng lieber einen Pull-Up-Widerstand rein.

von spess53 (Gast)


Lesenswert?

Hi

>  PORTA ^= (1<< PA3);
> if (RXB == 170) PORTA ^= (1<< PA4);

Wozu? Da hängt lt. deinem Schaltplan nichts dran.

MfG Spess

von Tobias (Gast)


Lesenswert?

an den beiden Pins hängen bloss 2 "Debug"-LEDs dran.

Cmax ist zugegebenermaßen unkonventionell, hat aber Probleme gelöst. 
Ohne den hatte ich des öfteren Resets des µC und hier im Forum habe ich 
von gleichen Problemen gelesen mit eben diesem Lösungsvorschlag.

von ... (Gast)


Lesenswert?

Die standardloesung fuer diesen Fall ist einen freien Pin zu nehmen und 
bei jeden gelesenen Byte diesen Pin zu pulsen. Mit einem Scope kann man 
dann genau sehen, was laeuft.

von spess53 (Gast)


Lesenswert?

Hi

>Ohne den hatte ich des öfteren Resets des µC und hier im Forum habe ich
>von gleichen Problemen gelesen mit eben diesem Lösungsvorschlag.

Das ist nur ein herumdoktern an Symptomen. Ein passender 
Abblockkondensator am Max ist mit Sicherheit hilfreicher. MAXIM gibt 
einen Wert von 3,1µ an.

MfG Spess

von AVRuser (Gast)


Lesenswert?

Hallo,

ein Abblock-Kerko am MAX-IC zwischen VCC und GND direkt am IC ist 
anzuraten (im Schaltplan sehe ich keinen) ...  (Ich nehme meist 100nF.)
Womöglich ist dann Cmax überflüssig. Ich habe bei RS485 bisher noch nie 
irgendeinen Kondensator an RxD gebraucht.

spess53 schrieb:
> MAXIM gibt (für den Abblock-C) einen Wert von 3,1µ an.

Woher hast du diese Information? Im Datenblatt finde ich nichts dazu ...

Ich schalte immer den internen Pull-Up für diesen Pin ein.
Das Einschalten dieses Pull-Ups an RxD beugt Störungen bei offenem 
RxD-Pin vor, wenn der Empfänger im MAX-IC nicht aktiv ist; es hält den 
Pin auf (inaktivem) High-Level.

Tobias schrieb:
> an den beiden Pins hängen bloss 2 "Debug"-LEDs dran.

Hoffentlich mit den notwendigen Vorwiderständen (das wird leider öfter 
fälschlicherweise nicht gemacht), sonst handelt man sich ohne sie wieder 
neue Probleme ein ...

von spess53 (Gast)


Lesenswert?

Hi

>Woher hast du diese Information? Im Datenblatt finde ich nichts dazu ...

http://www.maxim-ic.com/app-notes/index.mvp/id/367

MfG Spess

von AVRuser (Gast)


Lesenswert?

@ spess53:

Danke, die AN kannte ich noch nicht. Aber bisher hatte ich mit meinen 
100nF-Kerkos (noch?) keine Probleme.

von spess53 (Gast)


Lesenswert?

Hi

>Danke, die AN kannte ich noch nicht.

Ich bis heute auch nicht.

MfG Spess

von Tobias (Gast)


Lesenswert?

ich hab Cmax jetzt mal ausgelötet und den Entstörkondensator zwischen 
Vcc und GND beim MAX eingelötet, aber kriege immer noch gleichermaßen 
falsche Bytes.

von Tobias (Gast)


Lesenswert?

ich hab jetzt mal Kanal A und B vorm Max ans Oszi angeschlossen und 
voneinander abgezogen. Die Flanken sind schön steil, aber bei z.B. dem 
Byte 170 (binär 10101010) wechselt der Pegel schön von 5V zu -5V wieder 
zu 5V etc, aber mitten im Byte ist er 2 Bits lang auf 0V. Warum...noch 
nicht die geringste Idee.
Dieser 0V Pegel ist auch bei jedem anderem Byte enthalten.
Leider kann ich keinen Screenshot davon machen.

Normal würde ich ja vermuten dass der Sender das "verbricht", allerdings 
funktioniert die Übertragung mit dem ATMega32 ja einwandfrei.

Auch ist dieser 0V Pegel während der Zeit in der keine Übertragung statt 
findet vorhanden. Sollte da normalerweise nicht eine Different von 5V 
oder -5V sein? (Der Sender ist übrigens eine SPS die auch Pullup und 
PullDown Widerstände verwendet.)

von UndSieWissenNichtWasSieProgrammieren (Gast)


Lesenswert?

Das sind deine beiden Stopbits.

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.