PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] USART Problem beim ATMEGA88 A ( STUDIO 7 )



wkrug
06.03.2019, 09:16
Hallo,
Ich hab ein Problem mit dem USART an einem ATMEGA 88A.
Wenn Ich mit dem PC Daten mit 115200/8/N/1 mittels 5V USB Serial Adapter an die Schaltung sende werden die Bytes einwandfrei erkannt und an den PC per Softwareloop zurück gesendet.
Hänge Ich an den selben Port des ATMEGA 88 die eigentliche Zielschaltung mit einem ATXMEGA32U4 empfängt der USART nur "Mist" und gibt diesen dann auch so an den PC weiter.
ATXMEGA out -> in ATMEGA88 out -> in PC.
Verbinde Ich nun die Verbindungsstelle des ATXMEGA zum ATMEGA88 den 5V USB Adapter kommen die Daten aus dem XMEGA32 einwandfrei im Terminalprogramm an.
Es sieht also so aus, als ob der USART Empfänger im ATMEGA 88A das serielle Signal vom ATXMEGA nicht richtig erkennt.
Hatte schon mal einer von Euch ein ähnliches Problem?
Ich hab es auch schon mit Pullup und Pulldown Widerständen an der Verbindungsstelle versucht - Ohne Erfolg.
Die Schnittstellengeschwindigkeit sollte bei beiden Controllern stimmen.
Dazu hab ich den USART des ATMEGA 88 fortlaufend den Buchstaben "U" senden lassen.
Die Periodendauer mit 17,35µS ( + Messtoleranz ) mit dem Oszilloskop kommt hin und mit dem PC funktionierts ja auch.

/*
* OLED_SH1106.c
* Version 1.0
* Created: 05.03.2019 19:15:47
* Author : ############
*/

#define F_CPU 7372800

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <string.h>
//#include <stdlib.h>

#include "ssd1306xled.c"


//USART Section
#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)
#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)

// USART Receiver buffer
#define RX_BUFFER_SIZE 250
volatile uint8_t rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
volatile uint8_t rx_wr_index = 0,rx_rd_index = 0;
#else
volatile uint16_t rx_wr_index = 0,rx_rd_index = 0;
#endif

volatile uint8_t message_buffer[30];
volatile uint8_t message_pointer = 0;
volatile uint8_t readout_pointer = 0;

ISR (USART_RX_vect)
{
uint8_t status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index++] = data; //Daten Puffern
if(rx_wr_index >= RX_BUFFER_SIZE){rx_wr_index = 0;} //
if((UCSR0A & (1<<UDRE0)) > 0) //Lokales echo
{
UDR0 = data;
}
}
}

/*
Die Idee ist nur Strings über die serielle Schnittstelle an diesen Display Controller zu senden.
Das kann der AVR Quasi nebenbei erledigen.
Hier wird dann der ankommende String in Daten für das Display umgewandelt.
Datenformat
Byte 1 = X - Position
Byte 2 = Y - Position
Byte 3 = Datenart 0x00 = Bildschirm leeren; 0x01 = kleiner Font; 0x02 = großer Font
0x10 Bild 1; 0x11 Bild 2 usw.
Byte 4....Ende ASCII Daten oder leer
Byte X länge - 1 = CR \r
letztes Byte = LF \n
Somit ist auch Kompatibilität zur PC Schnittstelle gegeben
*/
void show_display (void)
{
uint8_t i = 0, ASCII_count = 0, x_pos = 0, y_pos = 0, type = 0;
char zeile [27];

x_pos = message_buffer[0];
y_pos = message_buffer[1];
type = message_buffer[2];

switch (type)
{
case 0:
ssd1306_clear();
break;

case 1:
i = 3;
ASCII_count = 0;
while(message_buffer[i] != '\r')
{
zeile[ASCII_count++] = message_buffer[i++]; //Nachricht auslesen und in Zeilenpuffer einlesen
}

zeile[ASCII_count]=0; //Stringende setzen
ssd1306_setpos(x_pos,y_pos);
ssd1306_string_font6x8(zeile);
break;

case 2:
i = 3;
ASCII_count = 0;
while (message_buffer[i] != '\r')
{
zeile[ASCII_count++] = message_buffer[i++]; //Nachricht auslesen und in Zeilenpuffer einlesen
}
zeile[ASCII_count]=0; //Stringende setzen
ssd1306_setpos(x_pos,y_pos);
ssd1306_string_font8x16xy(x_pos , y_pos , zeile);
break;

case 0x10:
ssd1306_draw_bmp(x_pos , y_pos , 127 , y_pos + 4 , 0);
break;

case 0x11:
ssd1306_draw_bmp(x_pos , y_pos , 127 , y_pos + 4 , 1);
break;

case 0x12:
ssd1306_draw_bmp(x_pos , y_pos , 127 , y_pos + 4 , 2);
break;

case 0x13:
ssd1306_draw_bmp(x_pos , y_pos , 127 , y_pos + 4 , 3);
break;


}

}


//Copy Data from serial Buffer to command buffer
void serial_parser(void)
{
while(rx_wr_index != rx_rd_index)
{
message_buffer[message_pointer]=rx_buffer[rx_rd_index++];
if(rx_rd_index >= RX_BUFFER_SIZE){rx_rd_index = 0;}
if((message_buffer[message_pointer] == '\n') && (message_buffer[message_pointer-1] == '\r'))
{
show_display();
message_pointer = 0;
}
else
{
message_pointer++;
if(message_pointer > 29){message_pointer = 0;} //Überlauf vermeiden!
}
}
}

//Startup Display
void startup (void)
{
ssd1306_clear();
message_buffer[0] = 0;
message_buffer[1] = 2;
message_buffer[2] = 2;
message_buffer[3]= ' ';
message_buffer[4]= ' ';
message_buffer[5]= ' ';
message_buffer[6]= ' ';
message_buffer[7]= '*';
message_buffer[8]= 'M';
message_buffer[9]= 'i';
message_buffer[10]= 'D';
message_buffer[11]= 'i';
message_buffer[12]= '*';
message_buffer[13]= ' ';
message_buffer[14]= ' ';
message_buffer[15]= ' ';
message_buffer[16]= ' ';
message_buffer[17]= '\r';
message_buffer[18]= '\n';
show_display();

message_buffer[0] = 0;
message_buffer[1] = 5;
message_buffer[2] = 2;
message_buffer[3]= ' ';
message_buffer[4]= ' ';
message_buffer[5]= ' ';
message_buffer[6]= '*';
message_buffer[7]= 'M';
message_buffer[8]= 'a';
message_buffer[9]= 's';
message_buffer[10]= 't';
message_buffer[11]= 'e';
message_buffer[12]= 'r';
message_buffer[13]= '*';
message_buffer[14]= ' ';
message_buffer[15]= '\r';
message_buffer[16]= '\n';
show_display();
_delay_ms(1000);
ssd1306_clear();
}


int main(void)
{
// Crystal Oscillator division factor: 1
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);

// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=0 Bit2=1 Bit1=0 Bit0=1
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (1<<PORTB2) | (0<<PORTB1) | (1<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);

/*
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART0 Mode: Asynchronous
// USART Baud Rate: 38400
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x0C;
*/

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 115200 (Double Speed Mode)
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (1<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x07;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

/* SPI disabled here, Included in Display Routine
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 1843,200 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
SPSR=(0<<SPI2X);
*/


// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

sei();

ssd1306_init();
ssd1306_clear();
startup();
message_pointer=0;

while (1)
{
if(rx_wr_index != rx_rd_index)
{
serial_parser();
}
}
}


Ich hab mal den kompletten Code ( ohne include Dateien ) gepostet.
Die serielle Schnittstellenbearbeitung findet im Prinzip der USART_RX_vect Routine statt.
Dort ist auch der Softwareloop integriert.

Ich bin im Augenblick ziemlich ratlos und weiss nicht, was Ich noch versuchen soll.

Übrigens beide Controller hängen an der selben 3,3V Stromversorgung ( Labornetzteil ).

Holomino
06.03.2019, 09:48
Masseschleife gebaut (GND von beiden UARTS verbunden + gleiche Versorgung) oder Masseproblem zwischen den Boards (mal'n Oszi drangehalten)?
Vergessen, den BrownOut auf unter 3,3V zu fusen (Verkabelung vom Netzteil zu den Boards sternförmig)?
Welcher "Mist" kommt denn am PC an?

oberallgeier
06.03.2019, 10:03
.. ein Problem mit dem USART an einem ATMEGA 88A ..Meine Probleme mit unpassenden UARTS sind (waren ?) zahllos. Irgendwann hatte ich dann entweder standardmässig oder fallweise diese Routine eingebunden und verwendet :
// ================================================== =========================== =
// == Auslesen der UBBR0-Werte und Ausgabe auf UART
// ================================================== =========================== =
void UBBR0tst ( void ) // UBBR auslesen und auf UART ausgeben <main
{ //
u16 bdv, iword; // Bauddivider und iword für Anzeige auf UART
// - - - - - - - - - - - - - - - -
// Testweise Ausgabe des UBBR0 vorbereiten
// Rechenformel : ( (u16)(F_CPU / BAUD / 16 - 0.5) )
// bdv = (u16)(F_CPU / 115200 / 16 );
// In main: = (u16)(F_CPU / BAUD / 16 - 0.5 );
bdv = (u16)(F_CPU / BAUD / 16 - 0.5 );
iword = uniq ( bdv, (bdv >>8));

// Hier anschließend - - - f Datenaustausch

uputs0 ("\r\tUBRR0 Rechnung: "); uputs0u ( iword ); // Anzeige UBRR0
wms ( 1000);

iword = uniq ( UBRR0L, UBRR0H );
uputs0 ("\t => Register ~L/H: "); uputs0u ( iword ); // Anzeige UBRR0
//
return; // Ende void UBBR0tst ( void )
}
// ================================================== =========================== =

Damit hatte ich dann Tipp-, Bibliotheks-, Rundungs- und sonstige -fehler oder so entdecken können. Sieht am Terminal, nach Reset oder Kaltstart der Platine, so aus (die Farbe rot ist rein"getürkt"):


NaCo x50 5 Mar 2019 13:20
uart0_64 256 kBd, Datenuebertrgg ebenso
Datenformat je 3 Bytes [ENQ][Sensora][Sensorb]
Übertragung ca 1 x je 3 Bytes / sek

UBRR0 Rechnung: 4 => Register ~L/H: 4

?Addr I²C-Dev 0xE0-0xFE; NoDev =: '-'
I²Cdevaddr aktiv 224 0xE0
I²Cdevaddr aktiv 226 0xE2
-------------- I²C_look Ende @ Addr.: 254 / 0xFE

#> ~r1n~/Tst1prsc: 1 Messung pro Sekunde
¼.¼.¯.¼.¼.½.!.¼.½.¼.¼.¼.¼.¼.¼.¼.¼.¼.¼.

Ne ausführlicher Anmerkung, so kurz nach dem Frühstück, geht grad nicht . . . ;-)

Nachtrag:
Warum das Ganze? Es gehört natürlich die Berechnung des Baudratenfehlers (https://dl.dropbox.com/s/j2q2waj81c7wwhr/Baudraten-xls.jpg?dl=0) dazu - Vorsicht: manche Schritte ganzzahlig rechnen. Die Abweichung (klick (https://dl.dropbox.com/s/6kay0csvvxfel56/UART%2Bdie-rote-Liniekl.jpg?dl=0)) kann erheblich sein, mit meinem neuen "Scope" sieht man wie deutlich (https://dl.dropbox.com/s/1rmgoigvr4bo7xl/8N1-Logic_20Feb2019kl.jpg?dl=0) :-/ so etwas sein kann. Und die Empfindlichkeit auf unterschiedlich große Baudratenabweichungen sind bei unterschiedlichen Empfängern (und Baudraten) eben verschieden.

wkrug
06.03.2019, 12:14
Masseschleife gebaut (GND von beiden UARTS verbunden + gleiche Versorgung) oder Masseproblem zwischen den Boards (mal'n Oszi drangehalten)?
Stimmt, da hatte ich schon mal Probleme.
Ich werd da mal ein Laptop mit Akkubetrieb ranhängen und gucken ob es da geht.
Da komm Ich aber erst heute Abend dazu!
Die Verkabelung zu den Controllern ist Sternförmig, allerdings noch auf einem Breadboard.
Der ATMEGA 88 ist aber incl. Peripherie schon auf einer Platine.


Vergessen, den BrownOut auf unter 3,3V zu fusen (Verkabelung vom Netzteil zu den Boards sternförmig)?
Welcher "Mist" kommt denn am PC an?
Brownout ist auf unter 3,3V eingestellt.
Der ATXMEGA sendet ASCII Zeichen.
Auf dem PC ( mit Putty ) kommen immer irgendwelche Zeichen an.
Manchmal undefinierbare, manchmal ASCII Zeichen, allerdings nicht die gesendeten.
Wie gesagt, wenn Ich mich an die Verbindungsstelle zwischen den Controller anschalte scheinen die gesendeten Daten vom XMEGA in Ordnung zu sein.


Und die Empfindlichkeit auf unterschiedlich große Baudratenabweichungen sind bei unterschiedlichen Empfängern (und Baudraten) eben verschieden.
Darum auch der Quarz mit dem krummen Wert.
Denn mit dem geht es bei 115200 genau auf = Abweichung 0,0%.
Hab auch schon die 2 möglichen Einstellungen einmal mit 2x und einmal ohne ausprobiert.
Auch der XMEGA Läuft mit 115200 auch, laut Berechnung, mit 0,0% Abweichung beim internen 32MHz Generator.

wkrug
07.03.2019, 10:56
Hab soeben den Test mit dem Laptop im Batteriebetrieb durchgeführt.
Am Ergebnis hat sich nichts geändert.
Nach wie vor werden nach dem MEGA 88 nur kryptische Zeichen ausgegeben.
Nun hab Ich irgendwie keine Idee mehr.

Ceos
07.03.2019, 11:13
justiere die baudraten mal minimal, stell den baudgen mal um 1 nach oben oder unten ob das hilft, vielleicht hast du nur timing artefakte

Holomino
07.03.2019, 11:21
Hmm, wenn es an der Baudrate liegen würde, wäre das Ergebnis bei konstantem "U" (0x55) eher systematisch.

Bist Du sicher, dass beide Controller rundlaufen? Kannst Du z.B. durch einen kontinuierlich hochlaufenden Zähler auf dem Display oder eine blinkende LED sicherstellen, dass nicht ein Partner durch ne elektrische Störung komplett aussteigt?

Gnom67
07.03.2019, 13:57
Hast du es mal generell mit geringeren Baudraten probiert? Was passiert bei 9600 Baud?
Vielleicht ist deine ISR zu umfangreich, um schnell genug abgearbeitet zu werden.
Vielleicht ist der Atmega auch zu langsam... Mit welchem Takt (Quartz) läuft er ? Ist der Clock-Divider ausgeschaltet? Und wieso hast du diesen krummen Wert F_CPU 7372800?
Wieso benutzt du keinen 16 MHz-Quartz mit Divider 1 und F_CPU 16000000?

Ceos
07.03.2019, 14:02
wäre das Ergebnis bei konstantem "U" (0x55) eher systematisch.
Jein ... du denkst heir an einer erkennbare Schwebung oder ein Muster, aber mit hinreichend viel Zufall und Parametern wird eine schöne Schwebung/Muster auch zum RNG

Daher der Vorschlag es mal damit zu probieren :) (vergiss nicht auch ein verpasstes stopp-bit kann zu lustigen Daten im DATA Register führen obwohl im Status Register alle roten Lämpchen leuchten)

Ein weiterer Vorschlag wäre es Fehlerbehandlung einzubauen, also das Statusregister zu prüfen und weiterzuleiten. Vielleicht ergibt sich dann mehr Einsicht.


Abweichung 0,0%

Wir reden hier zwar von Atmega zu Atxmega, aber ich kann aus meinem Job heraus sagen, dass manchmal zu viel genauigkeit auch Grenzwertprobleme verursacht ... in unserem Fall ein Device und ein Master, bei dem das Device sich zu exakt ans minimale Timing hält und der Master, schon aus Toleranzgründen für zu lange Bytes, deswegen manchmal ein Byte schlicht verpasst (okay das ist ein Problem mit der Protokollspezifikation die eine Schnittmenge von 0uS, statt weniger uS Toleranz-Pause beim Timminig hat aber ein schönes Beispiel für Grenzwertprobleme)

Holomino
07.03.2019, 16:11
Dann wäre der Test denkbar schlecht gewählt. Wenn Du alle 100ms ein Byte sendest, kommt es zu keiner Schwebung, da das Startbyte keine Zweideutigkeit zulässt.
Wenn ich die Baudrate teste, fange ich eigentlich auch mit ner 0 als Testbyte an und schaue, ob's nen Frame Error gibt (Stopbit nicht erkannt, Baudrate (beim Sender) zu langsam) oder ob der empfangene Wert systematisch <>0 ist (Baudrate zu schnell).

wkrug
07.03.2019, 19:30
justiere die baudraten mal minimal, stell den baudgen mal um 1 nach oben oder unten ob das hilft, vielleicht hast du nur timing artefakte
Hab am ATXMEGA mal die nächst niedrigere und dann die nächst höhere Einstellung probiert - Beides Erfolglos.
Der Fehler bleibt!

EDIT!
Hab jetzt beide Controller auf 9600BAUD umgeflashed nun geht es auch mit dem PC nicht mehr.
Ich hab immer mehr den Verdacht der USART des Controllers hat ne Macke!
Ich werd morgen mal nen ATMEGA 328 rein löten.


Und wieso hast du diesen krummen Wert F_CPU 7372800?
Der Controller läuft mit 3,3V der ATMEGA88 ist da nur bis max 10MHz spezifiziert.
Der krumme Quarz Wert kommt daher, weil ich nur damit gerade Teiler für die standard Baudraten her bekomme.
Die Schaltung arbeitet als reines Display interface.
Die seriellen Daten sollen nur auf einem 128x64 Display angezeigt werden.

wkrug
08.03.2019, 10:48
Mal zum Update.
Auch mit dem ATMEGA 328P läuft es nicht.
Ich hab dann den Stützkondensator der Display Platine von 10µF auf 100µF erhöht -> Kein Effekt.
Da das ohnehin nur ein Test war, hab Ich die Geschwindigkeit des X-MEGA USART auf MiDi konforme 31250 Baud eingestellt.
Mein MiDi Interface erkennt jetzt auch die Daten.
Ich kann also jetzt weiter testen.

Ich schiebe das mit den Problemen vorerst mal auf meine grottige Verkabelung ( Breadboard ).
Wenn's was neues gibt, poste Ich noch mal.

Vorerst mal Danke an alle für die guten Tipps!

Klebwax
08.03.2019, 15:18
Ich schiebe das mit den Problemen vorerst mal auf meine grottige Verkabelung ( Breadboard ).
Wenn's was neues gibt, poste Ich noch mal.

Das läßt sich mit einem Scope doch beliebig leicht überprüfen. Einbrüche in der Versorgung, die man mit 100µ statt 10µ ausgleichen könnte, kann man einfach sehen. Ob die Signale überhaupt vernünftig sind und nicht ein Verdrahtungsfehler bzw. Massefehler vorliegt ebenfalls. Und die reale Baudrate kann man auch messen. Man schickt z.B. 0x55 und misst die Zeit für ein Bit. Mit einem 10$ LA kann man auch die automatische Baudrateerkennung nutzen. Ich rechne nie irgendwelche Teiler genau aus, ich schätze nur ab und stelle mir mit Debugger und LA den gewünschten Wert ein. In fünf Minuten ist das Problem auch ohne funktionierende Gegenstelle gelöst.

MfG Klebwax

wkrug
08.03.2019, 19:02
Das läßt sich mit einem Scope doch beliebig leicht überprüfen.
Ja, hab Ich auch gemacht und dabei festgestellt, das auf der RxD Leitung des ATMEGA 88 eine Art "Echo" zu sehen ist.
= Impulse, die nach GND hin ausschlagen, ohne aber ganz nach GND zu gehen und das, obwohl dann gerade kein Input Signal anliegt.
Die Quelle konnte Ich aber leider nicht ausfindig machen.
Das passierte aber nur mit 9600Baud vom PC aus.
Die Signale vom ATXMEGA32 sahen dagegen mit dem Oszi immer sauber aus.
Das PC Interface hat dort auch die richtigen Pegel angezeigt.



In fünf Minuten ist das Problem auch ohne funktionierende Gegenstelle gelöst.
Wenn es sich um einen "normalen" Fehler handelt hast Du sicher recht.
Mein Oszi kann auch Periodendauern und Frequenzen messen und auch das kommt zeitmässig hin.

Ich hab ja jetzt erstmal eine funktionierende Lösung.
Ich kann die Schaltung, wenn das Breadboard wieder frei ist, dort noch mal aufbauen und gucken ob sich der Fehler dort auch zeigt.
Zur Zeit ist ja das Display und der ATMEGA 88 eine verbaute Huckepack Einheit.

EDIT!
Hab jetzt noch mal den ATMEGA 88 direkt mit dem 5V USART Adapter des PC verbunden, damit funktioniert alles wie geplant.
Wie gesagt Ich hab hier meine " grottige " Verkabelung in Verdacht.