Forum: Mikrocontroller und Digitale Elektronik UART kann Daten nicht einlesen


von Tim (Gast)


Lesenswert?

Hallo ich habe ein Problem mit dem einlesen von rs232 Signalen.
der Quelltext der die Daten einlesen soll geht nur bis
while (!(UCSRA & (1<<RXC)));
und dann nicht weiter. Obwohl ich die Daten über den MAX 232 pin13 rein 
und pin12 auf meine atmega16 gebe.
Könnte es sein das die Pegeländerungen am mc nicht großgenug sind?

1
uint8_t uart_getc(void);
2
void initusart ();
3
void uart_gets( char* Buffer, uint8_t MaxLen );
4
unsigned char adresse[15];
5
unsigned char adresse1[15];
6
unsigned char freigabe[15];
7
unsigned char messwerte[15];
8
//********************  main   *********************
9
int daten(void)
10
{
11
  char strBuffer[256];
12
  DDRB = 0xff;
13
  initusart ();   
14
    
15
  uart_gets( &strBuffer[0], 255 );  
16
  
17
}
18
/************************ Zeichen empfangen *******************/
19
uint8_t uart_getc(void)
20
{
21
    while (!(UCSRA & (1<<RXC)));   // warten bis Zeichen verfuegbar    
22
    //PORTB = UDR;
23
//*****************  BYTE1  **************************
24
  adresse1[1] = UDR;
25
  adresse1[1] = adresse1[1] & 0b00010000;  
26
  if (adresse1[1] == 0b00010000) 
27
    {
28
    freigabe[1] = 2;    
29
    messwerte[1] = UDR;  
30
    }
31
    
32
//*****************  BYTE14  **************************
33
  adresse1[14] = UDR;
34
  adresse1[14] = adresse1[14] & 0b11100000;
35
  if (adresse1[14] == 0b11100000)
36
    {
37
    freigabe[14] = 2;
38
    messwerte[14] = UDR;
39
    }
40
return UDR;                   
41
}
42
43
44
45
46
//********Zeichen sammeln und zum String zusammen setzen*********
47
void uart_gets( char* Buffer, uint8_t MaxLen )
48
{
49
  uint8_t NextChar;
50
  uint8_t StringLen = 0;
51
 
52
  NextChar = uart_getc();         
53
   
54
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) 
55
  {
56
    *Buffer++ = NextChar;
57
    StringLen++;
58
    NextChar = uart_getc();
59
  }
60
}
61
62
63
64
65
//***************UART Initialisieren********************
66
void initusart ()
67
{
68
  
69
    
70
  UBRRH = ubrr_value >> 8;
71
    UBRRL = ubrr_value & 0xFF;
72
  UCSRB = (1<<RXEN)|(1<<TXEN);// UART RX einschalten                 
73
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
74
}

von Keniff (Martin S.) (Gast)


Lesenswert?

hey tim,

würd dir ja gern helfen, nur steh ich glaub vor einem ähnlichen problem.
versuche einen sensor über µC-->max232-->rs422 zu betreiben.
ich weiss, dass der pc die befehle empfängt, nur beim anschluss an den 
sensor tut sich nichts. hab auch überlegt, obs an der zu geringen 
spannung liegt, die der max232 mit seinen ca 8,7V abwirft?!
hab gelesen, dass der pc solche niedrigen signale noch versteht. nur was 
ist mit andren gerätschaften?
wer cool wenn jemand mehr weiss!
gruß martin

von Christian (Gast)


Lesenswert?

An der Spannung wirds nicht liegen, die EIA-232 ist abwärtskompatibel 
bis +-5V..
Stoppbits und alle anderen Parameter richtig initialisiert? Mal mitm 
Oszi oder Logicanalyser geschaut was sich da tut?

von Jean P. (fubu1000)


Lesenswert?

Hallo,
nur um das vorab zu klären. Wenns denn wirklich bei while (!(UCSRA & 
(1<<RXC))); hängen bleibt. An welchem Pin der Seriellen ist den Pin13 
und an welchem Pin vom Atmega Pin12 ?
Welchen Quarz benutzt du , wo ist ubrrvalue definiert, mit welchem 
Terminal-Programm un welchen Einstellungen sendest du ?
Gruß

von Keniff (Martin S.) (Gast)


Lesenswert?

hey,

also ubrr value wird über F_CPU berechnet. also über den internen quarz. 
die frequenz steht bei 8MHz.
die übertragung läuft normal über 9600,8,N,1. sie geht/ging ja bis jetz 
auch immer ob senden oder empfangen zum pc. nur jetzt beim sensor bekomm 
ich keine antwort. kanns vllt auch am timing liegen?
sry, hab kein oszi griffbereit.
gruß

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Tim wrote:

> Hallo ich habe ein Problem mit dem einlesen von rs232 Signalen.
> der Quelltext der die Daten einlesen soll geht nur bis
> while (!(UCSRA & (1<<RXC)));
> und dann nicht weiter. Obwohl ich die Daten über den MAX 232 pin13 rein
> und pin12 auf meine atmega16 gebe.
> Könnte es sein das die Pegeländerungen am mc nicht großgenug sind?
>
> plus ...Codefetzen...

Das ist kein vollständiges Programm.

Mindestens main() und die Includes fehlen.
Seitens der UART fehlt die Einstellung der Baudrate.

> uint8_t uart_getc(void)

Du liest hier bis zu fünfmal UDR direkt aus, und nur vor dem ersten Mal 
wartest du ob überhaupt ein Zeichen vorhanden ist. Deshalb ist unklar, 
was die Funktion zurückliefert.

Woher weisst du dass das Programm in dem while() steckt? Ich sehe keine 
Debuganzeige in deinem Programm.

Auch ohne Oszi kannst du debuggen:

- LED an freiem Pin vor while an, in while aus nach while an.
- Low-Current LED als Spion an der PC-TXD => MAX232-R1-In Leitung
- Low-Current LED als Spion an der MAX232-R1-Out => ATmega12-RXD Leitung

Die beiden LED-Spione sollten beim Empfangen schön sichtbar flackern, 
wenn du mit niedrigen Baudraten debuggst.

Keniff wrote:

> also ubrr value wird über F_CPU berechnet. also über den internen quarz.
> die frequenz steht bei 8MHz.

Es gibt keinen internen Quarz beim ATmega16. Da ist nur ein Oszillator. 
Der ist für 9600 Baud im allgemeinen zu ungenau. Ein ständiges Thema 
beim Thema UART. Warum beachtet das keiner und fällt deswegen auf die 
Schnauze? Lernen durch Schmerz?

von STK500-Besitzer (Gast)


Lesenswert?

>Warum beachtet das keiner und fällt deswegen auf die
>Schnauze?

Weil viele den Unterschied zwischen Quarz- und RC-Oszillator nicht 
kennen oder einfach ignorieren.

>Lernen durch Schmerz?

Mancher steht drauf...

von Keniff (Martin S.) (Gast)


Lesenswert?

@ stefan:

hey,
ich benutz auch nicht den atmega16 sondern den 128er.
der funktionierte bis jetzt immer prima bei 9600,8,N,1 - auch ohne 
schmerzen ,-)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Wenn es keine Probleme gibt, ist es ja gut.

Möglicherweise ist die Fehlergrenze bei der Übertragung PC => AVR gerade 
nicht und beim Sensor => AVR gerade doch überschritten. Das könnte man 
mit Problemen beim "Timing" bezeichnen.

Es ist allerdings verdächtig, dass garnix kommt. Bei Abweichungen in 
der Baudrate kommen meistens noch verstümmelte Zeichen, die man als 
Rohtext im Terminalprogramm sehen kann.

Bist du sicher bei der Verdrahtung? Der Sendepin des Sensors muss 
grundsätzlich auf den Empfangspin des AVR.

Was dazwischen gehört ist von den Pegeln abhängig. Sind es RS232 Pegel, 
gehört sowas wie ein MAX232 dazwischen. Sind es TTL Pegel kann man 
direkt verbinden.

Erwartet der Sensor einen Handshake per Hard- oder Software? Erwartet 
der Sensor eine Textfolge als Aufforderung zum Senden? Funktioniert der 
Sensor am PC?

Gerade beim 128er noch eine Falle: Hast du an die Kompatibility-Fuse 
gedacht, wenn du die zweite Schnittstelle betreibst?

von Keniff (Martin S.) (Gast)


Lesenswert?

hey

cool, danke für die ausführliche antwort!

also verdrahtung passt. da bin ich mir eigentlich sicher ,-)

dazwischen hängt ein MAX232 zum wandel von TTL auf RS232-pegel un ein 
wandler von rs232 auf 422
aber das wurde alles schon mit pc-->sensor, pc-->µC und und und 
getestet.

der sensor erwartet en paket mit 9600,8,N,1  , ohne hard oder software- 
handshake. zumnidest nicht die üblichen

das paket soll so aussehn:
[STX][Command][Data][ETX][CHECK]

das macht es auch(habs ja auf em terminal programm laufen lassen, da 
kommts korrekt an).
der sensor an den pc angeschlossen funktioniert auf diese weise 
einwandfrei!?

wenn du das M103C-fuse meinst, das is nicht gesetzt!

gruß martin

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Keniff (Martin S.) wrote:

> der sensor erwartet en paket mit 9600,8,N,1  , ohne hard oder software-
> handshake. zumnidest nicht die üblichen
>
> das paket soll so aussehn:
> [STX][Command][Data][ETX][CHECK]
>
> das macht es auch(habs ja auf em terminal programm laufen lassen, da
> kommts korrekt an).
> der sensor an den pc angeschlossen funktioniert auf diese weise
> einwandfrei!?

Letztens hatte wir hier im Forum einen ähnlichen Fall. Der Unterschied 
zwischen PC (Terminalprogramm) und µC Programm war damals, dass das 
Terminalprogramm implizit immer ein Zeilenende (RETURN, CR) mitgesendet 
hat und die selbstgeschriebene Routine nicht.

Also wenn dein Sensor auch zeilenorientiert arbeitet, vermisst er 
vielleicht bei der µC => Sensor Kommunikation das Zeilenende!

STX, ETX kenne ich als ANSI Steuerzeichen, das ominöse CHECK könnte eine 
Prüfsumme sein, dann macht für mich ein Zeilenende (CR, LF oder CR+LF) 
hinterher durchaus Sinn.

Die Fuse war nur eine unwahrscheinliche Idee. Wenn dein Programm mit 
Unterprogrammen funktioniert ohne abzustürzen, ist diese Fuse eh richtig 
gesetzt.

von Keniff (Martin S.) (Gast)


Lesenswert?

hey,

also ein endzeichen fehlt denke ich nicht.
hab das ganze schon in der selben art für visual C++ am pc programmiert. 
also pc-->sensor. da lief es einwandfrei mit den paketen und der 
einfachen übertragung per comm-schnittstelle.

die prüfsumme is ne XOR verknüpfung zwischen command xor data xor etx. 
das steht alles im datenblatt.

werd mir nomma andre receive funktionen anschaun. denk da oder beim 
timing liegt irgendwo der hund begraben.

aber danke vielmals

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.