PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Timeout für das Einlesen von Zeichen via RS232



Ritchie
29.03.2013, 11:27
Hallo Zusammen,

die folgende Routine hat den Hacken, das wenn man sie aufruf und keine Zeichen kommen, das man ewig wartet.

Da ich mein Program in diesem Programmteil sequiell abarbeiten lassen will, wäre ein Timeout sehr gut.

Routine aus der RN-Code Schnipsel


static inline uint8_t uart_getc_wait (void)
{ // Warten, bis etwas empfangen wird
while (!(UCSRA & (1 << RXC)))
;
return UDR; // Das empfangene Zeichen zurückliefern
}


Hat jemand eine Idee, wie der Compiler eine gute Timeoutzeit berechnen kann, oder wie macht Ihr das in diesem Fall.

Gruss R.

Che Guevara
29.03.2013, 13:33
Hi,

wie wärs, wenn du einfach vor der While-Schleife noch eine Abfrage machst, ob überhaupt Daten anliegen? Das geht natürlich nur, wenn du einen Buffer hast.
Oder du machst das via Timer, der nach x ms einen Interrupt auslöst, ein Flag setzt und du überprüfst dann in der While-Schleife, ob das Flag gesetzt ist und verlässt sie dann.

Gruß
Chris

robo_tom_24
29.03.2013, 14:28
Oder du machst es gleich nur mit Interrupts? (USART0_RX_vect)

Ritchie
29.03.2013, 15:15
Daran habe ich auch bereits gedacht.

Da kann der Processor wenigstens noch was vernünftiges in der Zwischenzeit machen.

Derzeit scheint mir aber mein CMPS nicht wirklich zu antworten, wenn ich das in den Griff bekommen habe,
werde ich auf Interrupt umstellen. Das ist meines erachtens die sauberste Lösung.

Gruss R.

radbruch
29.03.2013, 15:25
So vielleicht:

static inline uint8_t uart_getc_wait (void)
{ // Warten, bis etwas empfangen wird
int timeout=0;
while (!(UCSRA & (1 << RXC)) && (timeout++ < 10000));

if(timeout < 10000) return UDR; // Das empfangene Zeichen zurückliefern
else return 0; // timeout aufgetreten
}

Ritchie
29.03.2013, 17:21
Hi,

ich verzweifle langsam.

Irgendwie will mir der Kompass nicht richtig antworten.

Hier die verwendeten Routinen


void RS232_Init(uint32_t iBaurate)
{
/*
** Enable TXEN and RXEN in register UCSRB
*/
UCSRB |= (1 << TXEN);
UCSRB |= (1 << RXEN);
/*
** Set transmission type, Asynchron 8Bit None Parity 2 Stop bit
*/
UCSRC = (1 << URSEL)|(1<< USBS)| (1<<UCSZ0) | (1<<UCSZ1);

/*
** Set baud rate
*/
UBRRH = ((SYSCLOCK / (iBaurate * 16L) - 1)>>8);
UBRRL = (SYSCLOCK / (iBaurate * 16L) - 1);
}

/************************************************** *****
Function: RS232_PutByte
Purpose: Send to the UART a data byte
Input Parameter: the byte
Return Value: None
Value = 0
************************************************** *****/
void RS232_PutByte (uint8_t Byte)
{
/*
** Wait until previous character is sent
*/
while (!(UCSRA & (1<<UDRE)));
/*
** Send byte to UART
*/
UDR = Byte;

return;
}

/************************************************** *****
Function: RS232_GetByte
Purpose: Get from the UART a byte
Input Parameter: None
Return Value: The UART byte
************************************************** *****/
int8_t RS232_GetByte (unsigned char *Pointer)
{
int8_t iState;


m_Timeout=0;
/*
** Wait until byte is available
*/

while (!(UCSRA &(1<<RXC)) && m_Timeout<10)
{
Delay_ms(10);
m_Timeout++;
}

if (m_Timeout < 10)
{
*Pointer=UDR;
iState=true;
}
else
{
*Pointer=0;
iState =false;
}
/*
** Get and return the byte from UART
*/
return iState;
}


Das Hauptprogramm ruft dann die Sache so auf:
Testweise habe ich den Code auf die Versionsnummer (nur ein Byte lesen geändert.



RS232_PutByte(0x11); // Send command get angle high, angle low (0-3600), pitch (+/- 0-85), roll (+/- 0-85)
Delay_ms(100);
iCounter=0;
iRs232State=true;
// while ( iCounter < 1 && iRs232State == true)
// {
iRs232State=RS232_GetByte(&(m_RS232_Buffer[iCounter]));
Delay_ms(10);
iCounter++;
// }

if (iRs232State == true)
CLEAR_BIT(PORTD,OUTPUT_DIAGNOSE_BIT1); //
else
CLEAR_BIT(PORTD,OUTPUT_DIAGNOSE_BIT0); //



Die Routine gibt immer false zurueck. Den Timeout habe ich auch schon mal sehr hoch gesetzt.
Der Wert für die Baudrate ist 103 und laut Tabelle korrekt.

Bit1 wird nie gesetzt sondern immer Bit 0. (testausgänge)

Gruss R.

- - - Aktualisiert - - -

Trau keiner Hardware,
welche Du selber verdrahtet hast.

Fehler in der Verdrahtung. Jetzt geht es.