-         

Ergebnis 1 bis 8 von 8

Thema: getsUSART auf mega168 läuft nicht [gelöst, nicht lesenswert]

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554

    getsUSART auf mega168 läuft nicht [gelöst, nicht lesenswert]

    Anzeige

    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
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Code:
    #define MYUBRR ((unsigned int)((unsigned long) F_CPU/16/BAUD-1))
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554
    Hallo Georg-Johann,

    vielen Dank für die schnelle Antwort. Leider hat´s das nicht gebracht - die Ausgabe bleibt stehen nach der ersten Zeile (wie vorher):
    Platine m168D/20 bzw. Flex168
    m168D_10x15.c 23mai08 0022 + m168D-libs-10x11.h
    - - -
    mecho Isvs1 Ipwmsrv
    - - -
    Freies Messen ca. Sekundentakt, 120 => 0
    AR 120 29 0
    Aber danke für Deine Mühe
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    Code:
           for (i = 0; 2; i++)


    Gruß

    Jens

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554
    Hallo Jens, danke ich habs geändert (ich mach ziemlich viel Fehler und nenne die Anfängerfehler), war erst verwundert, aber ich hatte ja nach Fehlern gefragt - und der Schock-smiley war deutlich! Hmmm, aber auch ein
    i = <=2;
    hilft nicht. Ich kann ja nicht mal EIN Zeichen empfangen:

    sagt die Ausgabe am Terminal
    Platine m168D/20 bzw. Flex168
    m168D_10x15.c 23mai08 0022 + m168D-libs-10x11.h
    - - -
    mecho Isvs1 Ipwmsrv
    - - -
    Freies Messen ca. Sekundentakt, 120 => 0
    AR 120 29 0
    Aufruf getchar folgt
    ... und es folgt eben GARNIX, obwohl ich mehrere Zeichen an den Controller gesandt hatte. Dabei hatte ich folgenden Aufruf im main:
    Code:
    ...
      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
                        
        sendUSART ("\tAufruf getchar folgt\r\n");
            
        k = getchar();
            	
        sendUSART ("\tAufruf getchar ist erfolgt\r\n");
    Und ich hab das gerade eben nochmal geprüft - der code, siehe oben bei Initialisierung, stimmt mit dem Schnippsel im doc 2545 überein
    Und einen Vergleich mit der entsprechenden Function "uart_getc()" bei pfleury übersteigt meine C-Kenntnisse.
    Ciao sagt der JoeamBerg

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    sorry für die kurze Antwort. Ich nenne so etwas bei mir dann zu spät, zu müde, blind ...
    So hat jeder seine Ausreden
    So jetzt im ernst, kannst du einen Hardwarefehler ausschließen? Du hast doch sicher einen MAX 232 zwischen Controller und PC. Wenn du den Controller vom MAX trennst und dafür eine Brücke einsetzt, solltest du beim Senden vom PC aus dein Echo empfangen.
    Mit einer LED am Controller kannst du den Punkt finden, an dem er hängen bleibt. Einfach eine Anweisung zum Einschalten der LED durch den Code schupsen. Irgendwann sollte sie dann ja nicht mehr an gehen.

    Gruß

    Jens

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554
    Hallo Jens,

    Zitat Zitat von McJenso
    ... sorry für die kurze Antwort...
    Um alles in der Welt - ich bitte Dich. Ich hatte es doch schon verstanden. Und ich bin froh um Deine Antworten, siehe gleich.
    Zitat Zitat von McJenso
    ... kannst du einen Hardwarefehler ausschließen? ... MAX 232 zwischen Controller und PC ... Brücke ... Echo ... LED am Controller ...
    Nun, ich hatte die Diagnostik etwas abgewandelt. Mit Kanonen auf ... Wolln mal so sagen, der, nein die Fehler sind behoben, bitte nicht weiterlesen.

    1. Es fehlte EINE Lötverbindung von der RS232 zum MAX 232. Die wurde nach einem Test am Controllerpin und MAX232-Pin beim "Empfangen" anhand des Oszilloskopbildchens festgestellt (und weils kein DSO ist, hatte ich 600 Baud gewählt ...). Kein Wunder, dass frühere Versuche so danebengingen . . . .
    2. Dann testete ich ja eingangs mit Eingabe der Zeichenfolge abc321xy. Den ausgeblendeten String "321" wandelte ich in die unsigned integer "Ipwmsrv" . . . und wunderte mich, dass dauernd 65 rauskam .

    Aber jetzt läufts:
    Code:
    Platine m168D/20 bzw. Flex168
    m168D_10x15.c  23mai08 2008 + m168D-libs-10x11.h
    	-	-	-
    	       mecho   Isvs1   Ipwmsrv
    	-	-	-
    	 Freies Messen ca. Sekundentakt, 120 => 0
    	AR 	120	29	0	
    	Aufruf getsUSART folgt
    	Aufruf getsUSART ist erfolgt
    aBc128x
    128
    	AR 	120	31	128	
    	Aufruf getsUSART folgt
    	Aufruf getsUSART ist erfolgt
    aBc128x
    128
    	AR 	120	33	128	
    	Aufruf getsUSART folgt
    Und nun muss ich bei meinem Alter überlegen, ob das noch Anfängerfehler sind oder beginnende Demenz.

    DANKE Jens, danke Georg-Johann
    Ciao sagt der JoeamBerg

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Zitat Zitat von oberallgeier
    bitte nicht weiterlesen.
    Kommt gar nicht in Frage

    Gruß Sternthaler
    Lieber Asuro programieren als arbeiten gehen.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •