-
        

Ergebnis 1 bis 9 von 9

Thema: RN-Minicontrol RS232 GCC

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32

    RN-Minicontrol RS232 GCC

    Anzeige

    Hallo,
    ich habe eine RN Minicontrol und möchte ein paar Debugdaten an den Rechner schicken. Es gibt auf dem Board ja anscheinend auch schon die 3 RS232 Pins, aber bisher klappt das Senden von Signalen noch nicht.
    geht das irgendwie mit dem printf-Befehl? (ich programmiere in c)

    Denn die UART Beispiele, die ich so gefunden habe klappen nicht (hat die RN Mini überhaupt UART funktionalität?)
    Das Problem hier ist, dass der GCC Compiler einige Variablen gar nciht kennt:
    main.c:4: error: `UCSRB' undeclared (first use in this function)

    falls jemand ein kleines Beispiel hat zum senden eines Zeichens oder einer Zeichenkette über RS232, sodass man es mit nem Terminalprogramm auslesen kann, wäre ich äußerst dankbar

    Gruß, Thomas

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32
    hab die Punkte hier in einem anderen Thread gefunden:

    1. du hast RS232 Stecker (3 polig) falschruf aufgesteckt?
    ist richtig rum

    2. du hast am Terminalprogramm falschen RS232 Port gewählt?
    auch richtig eingestellt

    3. du hast am Terminalprogramm falsche Baudrate gewählt?
    kann möglich sein, wie kann ich denn die Baudrate im C Programm angeben?
    hab einfach 9600 im Terminal Programm angegeben und 8n1

    4. du hast bei Fusebits den Quarz nicht korrekt aktiviert?
    Müsste alles richtig eingestellt sein, da ich das Fertigmodul der RN Minicontrol gekauft habe

    5. du hast bei Fusebits den Taktteiler nicht ausgeschaltet (DISABLE) (gibts nicht bei allen AVR´s, aber beim Mega16?
    da ich den 168 habe stellt sich mir nun die frage, ob ich das noch machen muss, oder ob das im Fertigmodul schon gemacht wurde

    6. du hast einfach einen Aufbaufehler/Lötfehler gemacht?
    das sicher nicht

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,
    Du kannst uns auch deinen Test-Code zukommen lassen, evtl. lässt sich dann leichter erkennen woran es liegt.

    Wegen dem nicht bekanntem Register vermute ich mal, der Controllername ist nicht richtig eingestellt, kann man im Makefile bei MCU angeben.
    Dann werden mit #include <avr/io.h> auch die richtigen Namen eingebunden.

    Beim Mega168 heisst Die UART UART0, deswegen muss man das auch im Namen angeben. In diesem Fall dann UCSR0B !

    Die Baudrate muss man sich selber errechnen, anhand der CPU-Frequenz, das steht u.a. im DB, oder evtl. auch bei uns irgendwo im Wiki.
    Der errechnete Wert kommt dann ins UBRR0 (BaudRateRegister UART0)
    Auch die anzahl Stopbits, Parity usw. wird in den Registern angegeben.

    Wenn Du nicht weisst wie es um die Fusebits steht, musst du sie einfach mal auslesen, erleichtert die weitere Arbeit ungemein
    IMHO ist da an dem Mega168 noch nix umgestellt, also läuft der mit internen 1MHz.

    Interessant wäre auch noch zu wissen mit welcher Hard- und Software Du hier zu werke gehst.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32
    also der Code:
    Code:
    #include <stdlib.h>
    #include <avr/io.h>
    #include <stdio.h>
    #include <stdint.h> 
    
    #define UART_BAUD_RATE 9600  // 9600 Baud
     
    int main(void)
    {
    unsigned long x,y;
    
    UCSR0B |= (1<<TXEN0);			// UART TX einschalten
    UCSR0C |= (1<<UMSEL00)|(3<<UCSZ00);	// Asynchron 8N1 
    
    UBRR0 = F_CPU / (UART_BAUD_RATE * 16L) - 1;
    
    
       while (1) {
    	  while (!(UCSR0A & (1<<UDRE0))); /* warten bis Senden moeglich                   */
          UDR0 = 'x';                    /* schreibt das Zeichen x auf die Schnittstelle */
    	  for(x=0;x<100000;x++)y++;
    	  printf("test");				/*nur zum test*/
    	  for(x=0;x<100000;x++)y++;
       }
     
       return 0; // never reached 
    }

    Wegen dem nicht bekanntem Register vermute ich mal, der Controllername ist nicht richtig eingestellt, kann man im Makefile bei MCU angeben.
    Dann werden mit #include <avr/io.h> auch die richtigen Namen eingebunden.

    Beim Mega168 heisst Die UART UART0, deswegen muss man das auch im Namen angeben. In diesem Fall dann UCSR0B !
    hab sie nur falsch benannt, danke für den Tipp

    der AVR Programmer ist ein:
    Found programmer: Id = "AVR ISP"; type = S
    Software Version = 3.9; Hardware Version = 1.2

    Ich programmiere im Programmers Notepad und programmiere auf dem AVR mit avrDude.

    Bei dem Code oben kennt er nun alle Variablen...Programm läuft auch, aber ich empfange keine Daten im Hyperterminal...habe 8N1 eingestellt.
    die Frequenz des Boards liegt übrigens ohne ändern der Fusebits bei 8MHz standardmäßig, jedenfalls bei mir.

    Ist die Baudrate so richtig errechnet?

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32
    ich habe eine Zeile im Code mal versuchsweise geändert:
    von
    UCSR0C |= (1<<UMSEL00)|(3<<UCSZ00); // Asynchron 8N1
    auf
    UCSR0C |= (1<<UMSEL01)|(1<<UMSEL00)|(3<<UCSZ00)|(3<<UCSZ01); // Asynchron 8N1

    und nun kommt schonmal was an im hyperterminal.
    aber es sind irgendwie nur leerzeichen, die ausgegeben werden. Welche Option könnten denn dafür schon wieder verantwortlich sein?

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Printf ist normalerweise nicht gedacht um beim Controller über UART etwas auszugeben, es gibt da günstigere Möglichkeiten, dazu bitte im Wiki suchen.

    Wenns unbedingt printf sein soll, gibts hier etwas:
    http://www.roboternetz.de/phpBB2/zei...=214155#214155

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32
    hm, also ich empfange irgendwie mist und habe bisher keine Ahnung woran das liegt. Das RN-Wiki und das AVR Tutorial ahben mir auch nciht so richtig weiter helfen können.

    wenn ich mit UART folgende Zeichenkette abschicke:
    ABBCCCCDDDDDDDDEEEEEEEEEEEEEEEE

    dann kommt folgendes im Terminalprogramm an:
    00 18 18 1E 1E 1E 1E 60 60 60 60 60 60 60 60 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 00

    vom Prinzip siehts ja gar nciht so schlecht aus, da die Anzahl der gleichen Zeichen stimmt...aber alle Zeichen sind irgendwie "verschoben"

    woran kann das liegen?
    Die Baudrate ist ja anscheinend schonmal richtig eingestellt[/url]


    der Code dazu:
    Code:
    #include <stdlib.h>
    #include <avr/io.h>
    #include <stdio.h>
    #include <stdint.h> 
    
    #define BAUDRATE 9600
    
    void uart_init(){
        uint16_t ubrr0 = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
         
        UBRR0H = (uint8_t) (ubrr0>>8);
        UBRR0L = (uint8_t) (ubrr0);
       
        // UART Receiver und Transmitter anschalten
        // Data mode 8N1, asynchron
        UCSR0B = (1 << RXEN0) | (1 << TXEN0);
        UCSR0C = (1 << UMSEL00) |(1 << UMSEL01) | (1 << UCSZ01) | (1 << UCSZ00);
    
        // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
        do{
            uint8_t dummy;
            (void) (dummy = UDR0);
        }
        while (UCSR0A & (1 << RXC0));
    }
    
    uart_putc (const uint8_t c){
        // Warten, bis UDR bereit ist für einen neuen Wert
        while (!(UCSR0A & (1 << UDRE0)));
    	
        // UDR schreiben startet die Übertragung      
        UDR0 = c;
    
        return 1;
    }
    
    void uart_puts (const char *s){
        do{
            uart_putc (*s);
        }
        while (*s++);
    }
    
    int main(void){
       unsigned long x,y;
       int z=0;
       uart_init();
       while (1) {
          uart_puts ("ABBCCCCDDDDDDDDEEEEEEEEEEEEEEEE");
    	  for(x=0;x<1000000;x++)y++;
       }
       return 0; // never reached 
    }
    ich vermute, dass ich die Bits für den 8N1 Modus nciht richtig eingestellt habe. Die Zeile sieht so aus:
    UCSR0C = (1 << UMSEL00) |(1 << UMSEL01) | (1 << UCSZ01) | (1 << UCSZ00);

    eigentlich stand im Tutorial statt UMSEL00 und UMSEL01 ein URSEL...gabs aber bei mir nicht, daher hatte ichs mal umbenannt in eine Variable, die sich so ähnlich angehört hat. Fehler hier?

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hi,

    Das URSEL Bit muß beim mega168 nicht gesetzt werden.
    Eigentlich müßte es so gehen:

    Code:
    UCSR0C =  (1 << UCSZ01) | (1 << UCSZ00);
    Gruß m.a.r.v.i.n

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    28.08.2004
    Beiträge
    32
    Habs mal probiert und es kommt leider genau so ein Zeichenmüll an.

    In einem anderem Thread steht, dass der Atmega noch intern mit 8MHz läuft und so ist es auch bei mir,wie es scheint.

    ich habe dann mit avrdude die fusebits folgendermaßen verändert:
    avrdude -p atmega168 -P com1 -c AVR910 -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0xF9:m

    beim übertragen vom efuse gibts zwar nen Fehler (kann nur 0x01 gesetzt werden), aber hat ja nicht sonderlich viel mit der Frequenz zutun. Die anderen werden laut Programm richtig gesetzt.

    allerdings läuft der atmega168 immer noch mit 8MHz
    Die Fusebits stimmen doch aber so, oder nicht?
    (hier hab ich mir die zusammengeklickt)

Berechtigungen

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