Forum: Mikrocontroller und Digitale Elektronik LIN Sync Break Erkennung


von Frederik K. (n0ll4k)


Lesenswert?

Hallo, ich habe folgendes Problem:

ich habe hier einen ATmega168 mit einem ATA6624 und versuche eine LIN 
Kommunikation aufzubauen.

Als Master dient ein Lipowsky Baby-LIN-RM auf welchem momentan der 
Master und der Slave emuliert werden.

Zunächst würde ich erstmal gerne eine gescheite SyncBreak und SyncField 
Erkennung programmieren. Allerdings habe ich einige Probleme mit dem 
SyncBreak.
Ich versuche selbiges über den Framing Error des UART abzufragen und 
darauf zu reagieren. Zum Debuggen habe ich erstmal 2 LEDs drangehängt. 
Eine soll aufleuchten wenn der Receive Interrupt ausgelöst wurde und die 
zweite wenn ein SyncBreak erkannt wurde. Was allerdings nicht passiert. 
Interessehalber habe ich mal anstatt den Framing Error abzufragen 
versucht auf ein 0x00 Byte zu reagieren und siehe da er springt in die 
Schleife rein.

Die Baudraten sind beide 19.2kBaud und die Systemfrequenz des ATmega ist 
8MHz über den internen RC-Oszilator.

Hat jemand eine Idee woran das liegen könnte?

Hier noch der Quellcode.
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
#define F_CPU 8000000UL     /*  8MHz Systemtakt  */
6
#define USART_BAUDRATE 19200UL
7
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
8
  
9
10
volatile uint8_t ReceivedByte;
11
12
int main( void ){
13
  
14
  DDRD |= ( 1<<DDD4) | ( 1<<DDD6 ) | ( 1<<DDD7 );
15
  PORTD |= ( 1<<PD4 );
16
17
  UCSR0B |= (1 << RXEN0) | (1 << TXEN0); //Empfangen und Senden einschalten
18
  UCSR0B |= (1 << RXCIE0); //Empfangsinterrupt einschalten
19
  UCSR0C |=  (1 << UCSZ00) | (1 << UCSZ01); //8-Bit Kommunikation
20
  
21
  //Berechneten Baudraten Prescaler in die Entsprechenden Register schreiben
22
  UBRR0L = BAUD_PRESCALE;  //Niedere 8-Bit schreiben
23
  UBRR0H = (BAUD_PRESCALE >> 8); //Hoehere 8-Bit schreiben
24
25
  sei();
26
  
27
  while(1){
28
29
  }
30
31
  return 0;
32
}
33
34
ISR(USART_RX_vect){
35
36
  PORTD |= ( 1<<PD7 );  
37
38
  //if (UDR0 == 0x00){ //Frame Error durch SyncBreak hervorgerufen
39
  if (FE0 == 1){
40
    ReceivedByte = UDR0;
41
    
42
    PORTD |= ( 1<<PD6 );
43
  }
44
}

von mp (Gast)


Lesenswert?

ist schon tausendmal  gepostet worden:
der interne RC ist ungeeignet für asynchrone Übertragung da viel zu 
ungenau.
-> externen Takt benutzen

Ich mache dasselbe mit einem ATMEGA168 und externem Quarz, das 
funktioniert so einwandfrei.

von Frederik K. (n0ll4k)


Lesenswert?

Laut Atmel soll das ganze als LIN Slave auch ohne funktionieren von 
daher bin ich mal davon ausgegangen das es auch so ist. Aber gut, jetzt 
muss ich nur nochmal schauen wo ich die SMD Kondensatoren für das 
Development Board herbekomme.

von Frederik K. (n0ll4k)


Lesenswert?

So falls es nochmal jemanden interessieren sollte.

Ich hab mich nun an der AppNote von Atmel orientiert und für die 
SyncBreak Erkennung auf die entsprechende Zeit heruntergesetzt um ein 
"korrektes" 0x00 Byte zu erkennen. Nachdem dies erkannt wurde wird die 
Baudrate wieder hochgesetzt und die Verarbeitung des Frames kann nun mit 
der korrekten Baudrate starten.

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.