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.
Ich hab mal den kompletten Code ( ohne include Dateien ) gepostet.Code:/* * 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(); } } }
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 ).







Zitieren

Lesezeichen