Anzeige:
Ergebnis 1 bis 5 von 5

Thema: AtMega8 und UART-Problem

  1. #1
    Registrierter Benutzer
    Registriert seit
    Dec 2007
    Beiträge
    147

    AtMega8 und UART-Problem

    Hallo Leute,

    ich will in die Welt der Microcontroller einsteigen und so habe ich diese Seite gefunden:
    http://derjulian.net/mikrocontroller
    Ich hab mir also die besagte Schaltung zusammengebaut, inklusive externem Quarz (8Mhz) und der Transistorschaltung zum Invertieren der Pins.

    Als Testcode habe ich mir das hier zusammenkopiert:
    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    #define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
    #define UART_BAUD_RATE      2400
    #define UART_BUFFER            10
    uint8_t uart_buffer[UART_BUFFER];
    int8_t  uart_count  = 0         ;
    uint8_t uart_getc(void)
    { /* output next char in cache
    */
        if (uart_count == 0) return 0;
        return uart_buffer[--uart_count];
    }
    ISR(SIG_UART_RECV)
    { /* INTERRUPT: receive char from UART and save it the buffer
    */
        if (uart_count < UART_BUFFER) uart_buffer[uart_count++] = UDR;
    }
    inline void uart_init(uint8_t tx, uint8_t rx)
    { /* initializes UART communication;
       * tx: sending should be activated
       * rx: receiving should be activated
       */
        uint16_t baudrate;
        // Baud-Rate setzen
        baudrate = UART_BAUD_RATE/2;
        UBRRH    = (uint8_t) (UART_UBRR_CALC(baudrate,F_CPU)>>8);
        UBRRL    = (uint8_t) UART_UBRR_CALC(baudrate,F_CPU);
        // Ggf. TX und RX anschalten
        UCSRA |= (1<<U2X);
        UCSRB |= (1<<RXCIE);
        if(tx) UCSRB |= (1<<TXEN);
        if(rx) UCSRB |= (1<<RXEN);
        sei();
        pause(1);
    }
    void uart_putc(uint8_t c)
    { /* send one char per UART
       */
        while (!(UCSRA & (1<<UDRE)));
        UDR = c;
    }
    void uart_puts(uint8_t *data)
    { /* send string per UART
       */
        while(*data)
        {
            uart_putc(*data);
            data++;
        }
    }
    void uart_puti(uint16_t data)
    { /* send integer per UART
       */
        uint8_t buffer[7];
        uart_puts(utoa(data, buffer, 10));
    }
    void uart_putf(float data)
    { /* send float per UART
         BUG: unnötige Leerzeichen am Anfang?
       */
        uint8_t buffer[7];
        uart_puts(dtostrf(data, 6, 2, buffer));
    }
    int main(void)
    {
        DDRB |= (1 << PB1); 
        PORTB &= ~(1 << PB1); 
    
       uart_init(1, 1);
       uart_puts("Hello World!\n");
    }
    Das ganze compiliert er schonmal nicht durch, er hat ein Problem mit pause(1):
    undefined reference to 'pause'
    Davor noch ein paar Warnings.
    Schmeiße ich das pause raus compiliert er durch, wobei die warnings bleiben.

    Nun schreibe ich die hex auf den uC, die LED leuchtet auch wie gewollt, allerdings bekomme ich nichts auf der Seriellen Konsole, tail -f /dev/ttyS0 gibt mir nichts aus.
    Am Windows-Netbook hab ich einen RS232-USB Converter. Schließe ich es da an und öffne den Hyperterminal, stelle 2400Bauds ein, bei 8 Datenbits, keine Parität, Stoppbits: 1, und Flusssteuerung Hardware, dort bekomme ich auch nichts.

    Woran kanns liegen?

    grüße
    dennis

  2. #2
    Registrierter Benutzer Avatar von derRichard
    Registriert seit
    Nov 2001
    Beiträge
    5.061
    Zitat Zitat von jimmy0815 Beitrag anzeigen
    Das ganze compiliert er schonmal nicht durch, er hat ein Problem mit pause(1):

    Davor noch ein paar Warnings.
    Schmeiße ich das pause raus compiliert er durch, wobei die warnings bleiben.
    kann es sein, dass du eine zu alte oder andere avrlibc verwendest?

    hth,
    //richard
    There are two factions of CS, the ones that hate computers, and the ones that hate science.

  3. #3
    Registrierter Benutzer
    Registriert seit
    Dec 2007
    Beiträge
    147
    zu alt kann eigentlich nicht sein, avrstudio und programmers notepad auf meinem win-netbook wo ich auch programmiere ist ganz frisch. Die Libc Version ist 1.6.7.
    Da einige Quelltexte von der Website mit dem Copyright 2006 versehen sind, weiß ich nicht in wiefern der Quellcode noch gepflegt wird.
    Aber was kann ich machen?

  4. #4
    Registrierter Benutzer
    Registriert seit
    Dec 2007
    Beiträge
    147
    Ich habe noch was anderes probiert:

    main.c:
    Code:
    #include <avr/interrupt.h>
    #include "uart.h"
    
    #define BAUDRATE 38400UL //Definition als unsigned long, sonst gibt es Fehler in der Berechnung
    
    void uart_init()
    {
        uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
     
        UBRRH = (uint8_t) (ubrr>>8);
        UBRRL = (uint8_t) (ubrr);
     
        // UART Receiver und Transmitter anschalten 
        // Data mode 8N1, asynchron 
        UCSRB = (1 << RXEN) | (1 << TXEN);
        UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
    
        // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) 
        do
        {
            UDR;
        }
        while (UCSRA & (1 << RXC));
    }
    
    // Einen 0-terminierten String übertragen. 
    void uart_puts (const char *s)
    {
        do
        {
            uart_putc (*s);
        }
        while (*s++);
    }
    
    // Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will 
    // Windows: "rn" 
    // Linux  : "n" 
    // MacOS  : "r" 
    #define CR "\r\n"
    
    char text[] = "Hallo Welt." CR;
    
    int main()
    {
        uart_init();
        sei();   // Wird nur gebraucht bei der Interrupt-Version 
    
        uart_puts (text);
        uart_puts ("Hallo Welt!" CR);
    
        return 0;
    }
    uart.h:
    Code:
    #ifndef _UART_H_
    #define _UART_H_
    
    #include <avr/io.h>
    
    extern void uart_init();
    
    static inline int
    uart_putc (const uint8_t c)
    {
        // Warten, bis UDR bereit ist für einen neuen Wert 
        while (!(UCSRA & (1 << UDRE)))
            ;
    
        // UDR Schreiben startet die Übertragung 
        UDR = c;
    
        return 1;
    }
    
    static inline uint8_t
    uart_getc_wait()
    {
        // Warten, bis etwas empfangen wird 
        while (!(UCSRA & (1 << RXC)))
            ;
    
        // Das empfangene Zeichen zurückliefern 
        return UDR;
    }
    
    static inline int
    uart_getc_nowait()
    {
        // Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst 
        return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
    }
    
    #endif /* _UART_H_  */
    Hier compiliert er voll durch, nur ein paar warnings:
    In file included from main.c:2:
    uart.h:6: warning: function declaration isn't a prototype
    uart.h:23: warning: function declaration isn't a prototype
    uart.h:34: warning: function declaration isn't a prototype
    main.c:7: warning: function declaration isn't a prototype
    main.c:45: warning: function declaration isn't a prototype
    Auf den externen Quarz (im Makefile definiert) schalte ich per
    Code:
    uisp -dlpt=0x378 -dprog=dapa --wr_fuse_l=0xee
    Ich hoffe das ist richtig?

    Auf dem Terminal bekomme ich rein gar nichts...

    Wenn ich jetz mit dem Multimeter dran gehe bekomme ich auf dem TXD/RXD pin des Controllers etwa 5V (bei beiden).
    An den Pins der Transen für die Invertierung bekomme ich beim RXD 6V für den USB-RS232Wandler und etwa 10V für direkte RS232, am TXD, also der wo eigentlich was raus soll, bekomme ich nur 0,02V raus.
    Das ist ja nicht ganz richtig, oder?
    Demnach würde ich vermuten dass die Transe kaputt ist? Kann das durch vertauschen der Drähte vom PC kommen?

    grüße
    dennis

    edit:
    hm...hat sich irgendwie gelöst...das ganze funktioniert jetzt. Ich weiß nicht wieso, aber ich bekomm auf dem Terminal jetzt mein "hallo Welt"
    Geändert von jimmy0815 (06.04.10 um 20:58 Uhr)

  5. #5
    Hardwarefreak Avatar von E S
    Registriert seit
    Jun 2003
    Ort
    Raum Bonn
    Beiträge
    1.251
    Hi,

    es heißt übrigens TRANSISTOR, nicht Transvestit!!!

    Benutze den MAX232 oder wenn Du keine Lust hast die vielen Kondensatoren verdrahten zu müssen den MAX233 (ist aber schwächer).
    Das ist ein Pegelwandler der aus RS232 TTL echte RS232 macht. Die Ladungspumpen für +/-10V sind im Chip eingebaut, die notwendige invertierung der Logikpegel wird auch im Chip erledigt.

    Gruß
    Elmar
    Was in C nicht geht muß gelötet werden!

Ähnliche Themen

  1. Kernel 2.6.13 auf Notebook (Problem mit ACPI)
    Von YaY im Forum Kompilieren von Kernel und Sourcen
    Antworten: 6
    Letzter Beitrag: 28.09.05, 12:39
  2. Treiberproblem führt zu DSL problem
    Von sirefour im Forum Anbindung an die Aussenwelt
    Antworten: 5
    Letzter Beitrag: 26.05.03, 20:19
  3. Seltsames Problem mit XFree86 4.0.1
    Von niggo im Forum X-Konfiguration
    Antworten: 4
    Letzter Beitrag: 22.01.02, 22:59
  4. Upload-Ping-Router Problem !!
    Von MidnightRambler im Forum System installieren und konfigurieren
    Antworten: 0
    Letzter Beitrag: 20.01.02, 19:16
  5. Problem mit SuSE Linux 7.3 Pro und SuSEfirewall2
    Von outi im Forum Linux als Server
    Antworten: 1
    Letzter Beitrag: 15.12.01, 18:52

Lesezeichen

Berechtigungen

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