Schönen Abend,

warum sollte denn meine eigene USART-Leseroutine laufen, wenn´s viele andere nicht tun? Ich wollte das selbst schreiben, weil ich bei einer fertigen Lib eben nix lernen kann. Jetzt sitze ich wieder einmal ziemlich lang dran, und es geht und geht nicht.

Bitte kann mir jemand helfen?

Mega168, 20 MHz, sendUSART läuft bei 57600 Baud einwandfrei. Bei der gleichen Konfiguration (aber auch bei z.B. 9600 Bd) kann ich keine Daten an den Controller senden.

Aufgabe:
1) Sende vom Controller an das Terminal einige Zeilen, u.a. mit Mess- und Steuerwerten.
2) Lies mit dem Controller den vom Terminal kommenden String aBc322xy ein, extrahiere die drei Ziffern und weise die Zahl der Variablen Ipwmsrv zu, die bei der Anzeige der nächsten Zeile mit Messwerten ans Terminal gesendet wird.

Lösung:
1) Läuft (seit langem, störungsfrei)
2) Läuft nicht.

Initialisierung des USART und Sende- bzw. Leseroutinen
Code:
/* ============================================================================== */
/*	Initialisiere USART0 mit vorgegebener Baudrate		Neu am 07jan2008
	Zum Senden von Zeichen im Hauptprogramm entweder        nach doc2545, S179
	char irgendwas[] = "meintext";
	sendUSART(irgendwas);		oder direkt
	sendUSART("meinText");		verwenden.				  */
void init_USART0( unsigned int ubrr ) 
{ 					// Set baud rate
    UBRR0H  =  (unsigned char)(ubrr>>8); 
    UBRR0L  =  (unsigned char)ubrr;	// Enable receiver and transmitter
    UCSR0B  =  (1<<RXEN0)|(1<<TXEN0); 	// Set frame format: 8data, 2stop bit
    UCSR0C |=  (1<<UCSZ01)|(1<<UCSZ00);	// 8 Data, (async: UMSELnx empty, doc S193)
			//  no parity weil UPMn1:0 empty, 1 Stop, weil UPMn1:0 empty
}
/* ============================================================================== */
void sendchar(unsigned char c)          // ... vgl. code sample in doc2545, S 180
{                                       // Wait for empty transmit buffer
   while(!(UCSR0A & (1<<UDRE0)))        //Warten, bis Senden möglich ist 
   {  } 
   UDR0 = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle 
} 
/* ============================================================================== */
void sendUSART(char *s)          //   *s funktiniert wie eine Art Array - auch bei 
        // einem String werden die Zeichen (char) einzeln ausgelesen - und auf die
        // Sendeschnittstelle übertragen 
{ 
   while(*s) 
   { 
   sendchar(*s); 
   s++; 
   } 
} 
/* ============================================================================== */
/* ===  Hole Daten vom USART0  ========================   Neu am 22mai2008
   ===  vgl. dazu doc2545 und AVR-Gcc-Tutorial....  ===================           */
char getchar(void)                      // ... vgl. code sample in doc2545, S 183
{                                       // Wait for data to be received
   while(!(UCSR0A & (1<<RXC0)))         //Warten, bis Empfang möglich ist 
   { }                                  // Get and return received data from buffer
   return UDR0;                         //hole das Zeichen vom Puffer und return
} 
/* ============================================================================== */
void getsUSART(char* Buffer, uint8_t MaxLen)
{
  uint8_t NextChar;
  uint8_t StringLen = 0;
 
  NextChar = getchar();         // Warte auf und empfange das nächste Zeichen
                                  // Sammle solange Zeichen, bis:
                                  // * entweder das String Ende Zeichen kam
                                  // * oder das aufnehmende Array voll ist
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
    *Buffer++ = NextChar;
    StringLen++;
    NextChar = getchar();
  }                               // Noch ein '\0' anhängen um einen Standard
                                  // C-String daraus zu machen
  *Buffer = '\0';
}
/* ============================================================================== */
Das GAnze wird vom main aus aufgerufen:
Code:
// div. zur Dokumentation, Deklarationen, Includes ...

#define MCU = AVR_ATmega168

//   Mit Quarz 20 Mhz-CPU 
#define F_CPU  20000000 
#define BAUD   57600 
#define MYUBRR (unsigned int)(F_CPU/16/BAUD-1)	  //nach doc2545, S 179

// - - - diverse Subroutinen - - - - - - - - - - - - -

int main(void) 
{
        
char wortadc[10], instrng[10], izahl[4];
  uint8_t i;

// verschiedene Initialisierungen (Ports, Timer etc).

    init_USART0(MYUBRR);  //USART0 initialisieren mit wählbarer Baudrate (s.o.)

// - - - verschiedene Aktionen - - - - - - - - - - - 

// ================================================================================
//  Vierter Testabschnitt Abstandserkennung mit SFH5110-36 / SFH415
//      modifiziert aus Rev x20b => x21, siehe oben
//  Aufgabe: Ausgabe der PWM-Ansteuerung bei der der 5110 schaltet auf USART

  uint8_t mecho = 50;           //, nz = 0;
  uint16_t istaus=0;		//  uint16_t istaus=0, inix=0;
        
sendUSART("\t Freies Messen ca. Sekundentakt, 120 => 0\r\n");    // Meldung ausgeben

for (;;)
{      
  mecho  = ReDiM();
        
    waitms(1000);       //
       
  sendUSART("\tAR \t");	      // Ausgabezeile eröffnen
  utoa(mecho, wortadc, 10);   //aktuellen Rampensteuerwert ...
  sendUSART(wortadc);         //  ... ausgeben
  sendUSART("\t");            // Tabulator senden
          
  utoa(Isvs1, wortadc, 10);   //aktuellen Servosteuerwert ...
  sendUSART(wortadc);         //  ... ausgeben
  sendUSART("\t");            // Tabulator senden
          
  utoa(Ipwmsrv, wortadc, 10);   //aktuellen Servosteuerwert ...
  sendUSART(wortadc);         //  ... ausgeben
  sendUSART("\t");            // Tabulator senden
          
  sendUSART("\r\n");	      // Zeilenabschluss ausgeben
                    
// Hier testweise einen String mit 8 (0 .. 7) Zeichen einlesen.
// Die Zeichen 3-5 enthalten einen Zahlenwert in ASCII. Dieser Wert wird nach
//      dem Einlesen der Variablen Ipwmsrv zugewiesen und beim nächsten
//      Mal angezeigt.
/*
        
  getsUSART(instrng, 8);
         
        for (i = 0; 2; i++)
	{
	izahl[i] = instrng[i+3];
	}
        izahl[3] = '\0';

        Ipwmsrv  = atoi(izahl);
*/
// ######## Hier testweise einen String mit 6 (0 .. 5) Zeichen einlesen. Ende

  mecho   = 0;
  istaus  = 0;
          
}           
// =====  Ende des vierten Testabschnittes   ======================================
... und wenn getsUSART aktiviert wird, dann hängt der Controller nach der ersten Zeile Messwertausgabe. Ohne getsUSART läuft die Ausgabe und läuft und läuft, siehe folgende Ausgabe (Tabs werden nicht angezeigt):
Platine m168D/20 bzw. Flex168
m168D_10x15.c 22mai08 2223 + m168D-libs-10x01/2.h
- - -
mecho Isvs1 Ipwmsrv
- - -
Freies Messen ca. Sekundentakt, 120 => 0
AR 120 29 0
AR 120 31 0
AR 120 33 0
AR 120 35 0
AR 120 37 0
AR 120 17 0
AR 120 19 0
Bitte findet jemand einen Fehler oder mehrere? Danke im Voraus