-         

Ergebnis 1 bis 6 von 6

Thema: falsche Übertragung bei der Kommunikation über serielle Schnittstelle/UART

  1. #1

    falsche Übertragung bei der Kommunikation über serielle Schnittstelle/UART

    Anzeige

    Hallo ,

    ich bin neu hier und es ist auch mein erstes Microcontroller-Projekt. Ich versuche euch mein Problem so genau wie möglich zu schreiben und auch alle Daten dazu:

    Der controller ist ein atmega32 auf einem AVR-Board. Habe versucht mit der UART Library von Peter Fleury werte ein- und wiederauszugeben. Das Flashen des Beispielprogramms "test_UART" mit AVRStudio hat auch funktioniert und ich habe versucht mit hterm und putty eine serielle Verbindung aufzubauen.
    Es ist möglich mit putty werte einzugeben, aber das Problem beginnt schon damit, dass nur bestimmte Tasten "richtig" funktionieren. Bei z.B. der "F"-Taste wird auch ein "f" eingegeben, aber z.B. die "Q"-Taste löscht einfach das letzte Zeichen bei der Eingabe oder bei anderen Tasten erscheinen andere Zeichen in der Konsole.
    Wenn ich ein Zeichen abschicke, wird es als irgend ein Sonderzeichen zurückgegeben.

    Ich habe auch schon andere Beispiel-C-Programme aus dem Internet ausprobiert, aber das Problem ist immer das Gleiche, dass irgendwelche kryptischen Zeichen über UART ausgeben werden, anstatt der im Quellcode angegebene char.

    Wäre euch überaus dankbar, wenn ihr mir helfen könntet.

    Gruß, Tschoernes

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    Hey, willkommen im Forum.
    Also es gibt mehrere möglichkeiten warum dass nicht richtig funktioniert.
    Als erstes poste bitte deinen Code mit dem du Zeichen sendest / ausliest.
    Dann überprüfe die Fusebits. Dort muss der richtige Takt eingestellt werden. Für UART empfiehlt sich ein externer Quarz. Der interne Oszilator ist dafür zu ungenau.
    Achte auch darauf dass dort nicht das Clock divide by 8 bit gesetzt ist.

    In HTerm musst du drauf achten, dass die Baudrate stimmt, die Start/Stopbits usw.

  3. #3
    Unregistriert
    Gast
    Danke für die schnelle Antwort!
    Der Code ist der oben erwähnte Standardcode:

    Code:
    main.c
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    
    #include "uart.h"
    
    
    /* define CPU frequency in Mhz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 4000000UL
    #endif
    
    /* 9600 baud */
    #define UART_BAUD_RATE      9600      
    
    
    int main(void)
    {
        unsigned int c;
        char buffer[7];
        int  num=134;
    
        
        /*
         *  Initialize UART library, pass baudrate and AVR cpu clock
         *  with the macro 
         *  UART_BAUD_SELECT() (normal speed mode )
         *  or 
         *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
         */
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
        
        /*
         * now enable interrupt, since UART library is interrupt controlled
         */
        sei();
        
        /*
         *  Transmit string to UART
         *  The string is buffered by the UART library in a circular buffer
         *  and one character at a time is transmitted to the UART using interrupts.
         *  uart_puts() blocks if it can not write the whole string to the circular 
         *  buffer
         */
        uart_puts("String stored in SRAM\n");
        
        /*
         * Transmit string from program memory to UART
         */
        uart_puts_P("String stored in FLASH\n");
        
            
        /* 
         * Use standard avr-libc functions to convert numbers into string
         * before transmitting via UART
         */     
        itoa( num, buffer, 10);   // convert interger into string (decimal format)         
        uart_puts(buffer);        // and transmit string to UART
    
        
        /*
         * Transmit single character to UART
         */
        uart_putc('\r');
        
        for(;;)
        {
            /*
             * Get received character from ringbuffer
             * uart_getc() returns in the lower byte the received character and 
             * in the higher byte (bitmask) the last receive error
             * UART_NO_DATA is returned when no data is available.
             *
             */
            c = uart_getc();
            if ( c & UART_NO_DATA )
            {
                /* 
                 * no data available from UART 
                 */
            }
            else
            {
                /*
                 * new data available from UART
                 * check for Frame or Overrun error
                 */
                if ( c & UART_FRAME_ERROR )
                {
                    /* Framing Error detected, i.e no stop bit detected */
                    uart_puts_P("UART Frame Error: ");
                }
                if ( c & UART_OVERRUN_ERROR )
                {
                    /* 
                     * Overrun, a character already present in the UART UDR register was 
                     * not read by the interrupt handler before the next character arrived,
                     * one or more received characters have been dropped
                     */
                    uart_puts_P("UART Overrun Error: ");
                }
                if ( c & UART_BUFFER_OVERFLOW )
                {
                    /* 
                     * We are not reading the receive buffer fast enough,
                     * one or more received character have been dropped 
                     */
                    uart_puts_P("Buffer overflow error: ");
                }
                /* 
                 * send received character back
                 */
                uart_putc( (unsigned char)c );
            }
        }
        
    }
    Code:
    vorimplemntierer Code
    /*************************************************************************
    Title:    Interrupt UART library with receive/transmit circular buffers
    Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
    File:     $Id: uart.c,v 1.12 2014/01/08 21:58:12 peter Exp $
    Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
    Hardware: any AVR with built-in UART, 
    License:  GNU General Public License 
              
    DESCRIPTION:
        An interrupt is generated when the UART has finished transmitting or
        receiving a byte. The interrupt handling routines use circular buffers
        for buffering received and transmitted data.
        
        The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
        the buffer size in bytes. Note that these variables must be a 
        power of 2.
        
    USAGE:
        Refere to the header file uart.h for a description of the routines. 
        See also example test_uart.c.
    
    NOTES:
        Based on Atmel Application Note AVR306
                        
    LICENSE:
        Copyright (C) 2006 Peter Fleury
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        any later version.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
                            
    *************************************************************************/
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include "uart.h"
    
    
    /*
     *  constants and macros
     */
    
    /* size of RX/TX buffers */
    #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
    #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
    
    #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
    #error RX buffer size is not a power of 2
    #endif
    #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
    #error TX buffer size is not a power of 2
    #endif
    
    #if defined(__AVR_AT90S2313__) \
     || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
     || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
     || defined(__AVR_ATmega103__)
     /* old AVR classic or ATmega103 with one UART */
     #define AT90_UART
     #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
     #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
     #define UART0_STATUS   USR
     #define UART0_CONTROL  UCR
     #define UART0_DATA     UDR  
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
     /* old AVR classic with one UART */
     #define AT90_UART
     #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
     #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR 
     #define UART0_UDRIE    UDRIE
    #elif  defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
      || defined(__AVR_ATmega323__)
      /* ATmega with one USART */
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   USART_RXC_vect
     #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega163__)
      /* ATmega163 with one UART */
     #define ATMEGA_UART
     #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega162__) 
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   USART0_RXC_vect
     #define UART1_RECEIVE_INTERRUPT   USART1_RXC_vect
     #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
     #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
     #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
     #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #elif defined(__AVR_ATmega161__)
     /* ATmega with UART */
     #error "AVR ATmega161 currently not supported by this libaray !"
    #elif defined(__AVR_ATmega169__) 
     /* ATmega with one USART */
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \
     || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__)
     /* ATmega with one USART */
     #define ATMEGA_USART0
     #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATtiny2313__) 
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega329__) || \
          defined(__AVR_ATmega649__) || \
          defined(__AVR_ATmega325__) || \
          defined(__AVR_ATmega645__) 
      /* ATmega with one USART */
      #define ATMEGA_USART0
      #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
      #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
      #define UART0_STATUS   UCSR0A
      #define UART0_CONTROL  UCSR0B
      #define UART0_DATA     UDR0
      #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__)  || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__)
    /* ATmega with two USART */
      #define ATMEGA_USART0
      #define ATMEGA_USART1
      #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
      #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
      #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
      #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
      #define UART0_STATUS   UCSR0A
      #define UART0_CONTROL  UCSR0B
      #define UART0_DATA     UDR0
      #define UART0_UDRIE    UDRIE0
      #define UART1_STATUS   UCSR1A
      #define UART1_CONTROL  UCSR1B
      #define UART1_DATA     UDR1
      #define UART1_UDRIE    UDRIE1  
    #elif defined(__AVR_ATmega644__)
     /* ATmega with one USART */
     #define ATMEGA_USART0
     #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
     #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
     #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)
     /* AT90USBxx with one USART */
     #define AT90USB_USART
     #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect
     #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect
     #define UART0_STATUS   UCSR1A
     #define UART0_CONTROL  UCSR1B
     #define UART0_DATA     UDR1
     #define UART0_UDRIE    UDRIE1
    #else
     #error "no UART definition for MCU available"
    #endif
    
    
    /*
     *  module global variables
     */
    static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
    static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
    static volatile unsigned char UART_TxHead;
    static volatile unsigned char UART_TxTail;
    static volatile unsigned char UART_RxHead;
    static volatile unsigned char UART_RxTail;
    static volatile unsigned char UART_LastRxError;
    
    #if defined( ATMEGA_USART1 )
    static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
    static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
    static volatile unsigned char UART1_TxHead;
    static volatile unsigned char UART1_TxTail;
    static volatile unsigned char UART1_RxHead;
    static volatile unsigned char UART1_RxTail;
    static volatile unsigned char UART1_LastRxError;
    #endif
    
    
    
    ISR (UART0_RECEIVE_INTERRUPT)	
    /*************************************************************************
    Function: UART Receive Complete interrupt
    Purpose:  called when the UART has received a character
    **************************************************************************/
    {
        unsigned char tmphead;
        unsigned char data;
        unsigned char usr;
        unsigned char lastRxError;
     
     
        /* read UART status register and UART data register */ 
        usr  = UART0_STATUS;
        data = UART0_DATA;
        
        /* */
    #if defined( AT90_UART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #elif defined( ATMEGA_USART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #elif defined( ATMEGA_USART0 )
        lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
    #elif defined ( ATMEGA_UART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #elif defined( AT90USB_USART )
        lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
    #endif
            
        /* calculate buffer index */ 
        tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
        
        if ( tmphead == UART_RxTail ) {
            /* error: receive buffer overflow */
            lastRxError = UART_BUFFER_OVERFLOW >> 8;
        }else{
            /* store new index */
            UART_RxHead = tmphead;
            /* store received data in buffer */
            UART_RxBuf[tmphead] = data;
        }
        UART_LastRxError |= lastRxError;   
    }
    
    
    ISR (UART0_TRANSMIT_INTERRUPT)
    /*************************************************************************
    Function: UART Data Register Empty interrupt
    Purpose:  called when the UART is ready to transmit the next byte
    **************************************************************************/
    {
        unsigned char tmptail;
    
        
        if ( UART_TxHead != UART_TxTail) {
            /* calculate and store new buffer index */
            tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
            UART_TxTail = tmptail;
            /* get one byte from buffer and write it to UART */
            UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
        }else{
            /* tx buffer empty, disable UDRE interrupt */
            UART0_CONTROL &= ~_BV(UART0_UDRIE);
        }
    }
    
    
    /*************************************************************************
    Function: uart_init()
    Purpose:  initialize UART and set baudrate
    Input:    baudrate using macro UART_BAUD_SELECT()
    Returns:  none
    **************************************************************************/
    void uart_init(unsigned int baudrate)
    {
        UART_TxHead = 0;
        UART_TxTail = 0;
        UART_RxHead = 0;
        UART_RxTail = 0;
        
    #if defined( AT90_UART )
        /* set baud rate */
        UBRR = (unsigned char)baudrate; 
    
        /* enable UART receiver and transmmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
    
    #elif defined (ATMEGA_USART)
        /* Set baud rate */
        if ( baudrate & 0x8000 )
        {
        	 UART0_STATUS = (1<<U2X);  //Enable 2x speed 
        	 baudrate &= ~0x8000;
        }
        UBRRH = (unsigned char)(baudrate>>8);
        UBRRL = (unsigned char) baudrate;
       
        /* Enable USART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        #ifdef URSEL
        UCSRC = (1<<URSEL)|(3<<UCSZ0);
        #else
        UCSRC = (3<<UCSZ0);
        #endif 
        
    #elif defined (ATMEGA_USART0 )
        /* Set baud rate */
        if ( baudrate & 0x8000 ) 
        {
       		UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
       		baudrate &= ~0x8000;
       	}
        UBRR0H = (unsigned char)(baudrate>>8);
        UBRR0L = (unsigned char) baudrate;
    
        /* Enable USART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        #ifdef URSEL0
        UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
        #else
        UCSR0C = (3<<UCSZ00);
        #endif 
    
    #elif defined ( ATMEGA_UART )
        /* set baud rate */
        if ( baudrate & 0x8000 ) 
        {
        	UART0_STATUS = (1<<U2X);  //Enable 2x speed 
        	baudrate &= ~0x8000;
        }
        UBRRHI = (unsigned char)(baudrate>>8);
        UBRR   = (unsigned char) baudrate;
    
        /* Enable UART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    #elif defined ( AT90USB_USART )
       /* set baud rate */
        if ( baudrate & 0x8000 ) 
        {
        	UART0_STATUS = (1<<U2X1 );  //Enable 2x speed 
        	baudrate &= ~0x8000;
        }
        UBRR1H = (unsigned char)(baudrate>>8);
        UBRR1L = (unsigned char) baudrate;
    
        /* Enable UART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
    #endif
    
    }/* uart_init */
    
    
    /*************************************************************************
    Function: uart_getc()
    Purpose:  return byte from ringbuffer  
    Returns:  lower byte:  received byte from ringbuffer
              higher byte: last receive error
    **************************************************************************/
    unsigned int uart_getc(void)
    {    
        unsigned char tmptail;
        unsigned char data;
    
    
        if ( UART_RxHead == UART_RxTail ) {
            return UART_NO_DATA;   /* no data available */
        }
        
        /* calculate /store buffer index */
        tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
        UART_RxTail = tmptail; 
        
        /* get data from receive buffer */
        data = UART_RxBuf[tmptail];
        
        data = (UART_LastRxError << 8) + data;
        UART_LastRxError = 0;
        return data;
    
    }/* uart_getc */
    
    
    /*************************************************************************
    Function: uart_putc()
    Purpose:  write byte to ringbuffer for transmitting via UART
    Input:    byte to be transmitted
    Returns:  none          
    **************************************************************************/
    void uart_putc(unsigned char data)
    {
        unsigned char tmphead;
    
        
        tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
        
        while ( tmphead == UART_TxTail ){
            ;/* wait for free space in buffer */
        }
        
        UART_TxBuf[tmphead] = data;
        UART_TxHead = tmphead;
    
        /* enable UDRE interrupt */
        UART0_CONTROL    |= _BV(UART0_UDRIE);
    
    }/* uart_putc */
    
    
    /*************************************************************************
    Function: uart_puts()
    Purpose:  transmit string to UART
    Input:    string to be transmitted
    Returns:  none          
    **************************************************************************/
    void uart_puts(const char *s )
    {
        while (*s) 
          uart_putc(*s++);
    
    }/* uart_puts */
    
    
    /*************************************************************************
    Function: uart_puts_p()
    Purpose:  transmit string from program memory to UART
    Input:    program memory string to be transmitted
    Returns:  none
    **************************************************************************/
    void uart_puts_p(const char *progmem_s )
    {
        register char c;
        
        while ( (c = pgm_read_byte(progmem_s++)) ) 
          uart_putc(c);
    
    }/* uart_puts_p */
    
    
    /*
     * these functions are only for ATmegas with two USART
     */
    #if defined( ATMEGA_USART1 )
    
    ISR(UART1_RECEIVE_INTERRUPT)
    /*************************************************************************
    Function: UART1 Receive Complete interrupt
    Purpose:  called when the UART1 has received a character
    **************************************************************************/
    {
        unsigned char tmphead;
        unsigned char data;
        unsigned char usr;
        unsigned char lastRxError;
     
     
        /* read UART status register and UART data register */ 
        usr  = UART1_STATUS;
        data = UART1_DATA;
        
        /* */
        lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
            
        /* calculate buffer index */ 
        tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
        
        if ( tmphead == UART1_RxTail ) {
            /* error: receive buffer overflow */
            lastRxError = UART_BUFFER_OVERFLOW >> 8;
        }else{
            /* store new index */
            UART1_RxHead = tmphead;
            /* store received data in buffer */
            UART1_RxBuf[tmphead] = data;
        }
        UART1_LastRxError |= lastRxError;   
    }
    
    
    ISR(UART1_TRANSMIT_INTERRUPT)
    /*************************************************************************
    Function: UART1 Data Register Empty interrupt
    Purpose:  called when the UART1 is ready to transmit the next byte
    **************************************************************************/
    {
        unsigned char tmptail;
    
        
        if ( UART1_TxHead != UART1_TxTail) {
            /* calculate and store new buffer index */
            tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
            UART1_TxTail = tmptail;
            /* get one byte from buffer and write it to UART */
            UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
        }else{
            /* tx buffer empty, disable UDRE interrupt */
            UART1_CONTROL &= ~_BV(UART1_UDRIE);
        }
    }
    
    
    /*************************************************************************
    Function: UART1_init()
    Purpose:  initialize UART1 and set baudrate
    Input:    baudrate using macro UART_BAUD_SELECT()
    Returns:  none
    **************************************************************************/
    void UART1_init(unsigned int baudrate)
    {
        UART1_TxHead = 0;
        UART1_TxTail = 0;
        UART1_RxHead = 0;
        UART1_RxTail = 0;
        
    
        /* Set baud rate */
        if ( baudrate & 0x8000 ) 
        {
        	UART1_STATUS = (1<<U2X1);  //Enable 2x speed 
          baudrate &= ~0x8000;
        }
        UBRR1H = (unsigned char)(baudrate>>8);
        UBRR1L = (unsigned char) baudrate;
    
        /* Enable USART receiver and transmitter and receive complete interrupt */
        UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */   
        #ifdef URSEL1
        UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
        #else
        UCSR1C = (3<<UCSZ10);
        #endif 
    }/* uart_init */
    
    
    /*************************************************************************
    Function: UART1_getc()
    Purpose:  return byte from ringbuffer  
    Returns:  lower byte:  received byte from ringbuffer
              higher byte: last receive error
    **************************************************************************/
    unsigned int UART1_getc(void)
    {    
        unsigned char tmptail;
        unsigned char data;
    
    
        if ( UART1_RxHead == UART1_RxTail ) {
            return UART_NO_DATA;   /* no data available */
        }
        
        /* calculate /store buffer index */
        tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
        UART1_RxTail = tmptail; 
        
        /* get data from receive buffer */
        data = UART1_RxBuf[tmptail];
        
        data = (UART1_LastRxError << 8) + data;
        UART1_LastRxError = 0;
        return data;
    
    }/* UART1_getc */
    
    
    /*************************************************************************
    Function: UART1_putc()
    Purpose:  write byte to ringbuffer for transmitting via UART
    Input:    byte to be transmitted
    Returns:  none          
    **************************************************************************/
    void UART1_putc(unsigned char data)
    {
        unsigned char tmphead;
    
        
        tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
        
        while ( tmphead == UART1_TxTail ){
            ;/* wait for free space in buffer */
        }
        
        UART1_TxBuf[tmphead] = data;
        UART1_TxHead = tmphead;
    
        /* enable UDRE interrupt */
        UART1_CONTROL    |= _BV(UART1_UDRIE);
    
    }/* UART1_putc */
    
    
    /*************************************************************************
    Function: UART1_puts()
    Purpose:  transmit string to UART1
    Input:    string to be transmitted
    Returns:  none          
    **************************************************************************/
    void UART1_puts(const char *s )
    {
        while (*s) 
          UART1_putc(*s++);
    
    }/* UART1_puts */
    
    
    /*************************************************************************
    Function: UART1_puts_p()
    Purpose:  transmit string from program memory to UART1
    Input:    program memory string to be transmitted
    Returns:  none
    **************************************************************************/
    void UART1_puts_p(const char *progmem_s )
    {
        register char c;
        
        while ( (c = pgm_read_byte(progmem_s++)) ) 
          UART1_putc(c);
    
    }/* UART1_puts_p */
    
    
    #endif
    Code:
    header
    #ifndef UART_H
    #define UART_H
    /************************************************************************
    Title:    Interrupt UART library with receive/transmit circular buffers
    Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
    File:     $Id: uart.h,v 1.12 2012/11/19 19:52:27 peter Exp $
    Software: AVR-GCC 4.1, AVR Libc 1.4
    Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
    License:  GNU General Public License 
    Usage:    see Doxygen manual
    
    LICENSE:
        Copyright (C) 2006 Peter Fleury
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        any later version.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
        
    ************************************************************************/
    
    /** 
     *  @defgroup pfleury_uart UART Library
     *  @code #include <uart.h> @endcode
     * 
     *  @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers. 
     *
     *  This library can be used to transmit and receive data through the built in UART. 
     *
     *  An interrupt is generated when the UART has finished transmitting or
     *  receiving a byte. The interrupt handling routines use circular buffers
     *  for buffering received and transmitted data.
     *
     *  The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
     *  the size of the circular buffers in bytes. Note that these constants must be a power of 2.
     *  You may need to adapt this constants to your target and your application by adding 
     *  CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_RX_BUFFER_SIZE=nn to your Makefile.
     *
     *  @note Based on Atmel Application Note AVR306
     *  @author Peter Fleury pfleury@gmx.ch  http://jump.to/fleury
     */
     
    /**@{*/
    
    
    #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
    #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
    #endif
    
    
    /*
    ** constants and macros
    */
    
    /** @brief  UART Baudrate Expression
     *  @param  xtalcpu  system clock in Mhz, e.g. 4000000UL for 4Mhz          
     *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600     
     */
    #define UART_BAUD_SELECT(baudRate,xtalCpu)  (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL)
    
    /** @brief  UART Baudrate Expression for ATmega double speed mode
     *  @param  xtalcpu  system clock in Mhz, e.g. 4000000UL for 4Mhz           
     *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600     
     */
    #define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000)
    
    
    /** Size of the circular receive buffer, must be power of 2 */
    #ifndef UART_RX_BUFFER_SIZE
    #define UART_RX_BUFFER_SIZE 32
    #endif
    /** Size of the circular transmit buffer, must be power of 2 */
    #ifndef UART_TX_BUFFER_SIZE
    #define UART_TX_BUFFER_SIZE 32
    #endif
    
    /* test if the size of the circular buffers fits into SRAM */
    #if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
    #error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
    #endif
    
    /* 
    ** high byte error return code of uart_getc()
    */
    #define UART_FRAME_ERROR      0x1000              /* Framing Error by UART       */
    #define UART_OVERRUN_ERROR    0x0800              /* Overrun condition by UART   */
    #define UART_PARITY_ERROR     0x0400              /* Parity Error by UART        */ 
    #define UART_BUFFER_OVERFLOW  0x0200              /* receive ringbuffer overflow */
    #define UART_NO_DATA          0x0100              /* no receive data available   */
    
    
    /*
    ** function prototypes
    */
    
    /**
       @brief   Initialize UART and set baudrate 
       @param   baudrate Specify baudrate using macro UART_BAUD_SELECT()
       @return  none
    */
    extern void uart_init(unsigned int baudrate);
    
    
    /**
     *  @brief   Get received byte from ringbuffer
     *
     * Returns in the lower byte the received character and in the 
     * higher byte the last receive error.
     * UART_NO_DATA is returned when no data is available.
     *
     *  @param   void
     *  @return  lower byte:  received byte from ringbuffer
     *  @return  higher byte: last receive status
     *           - \b 0 successfully received data from UART
     *           - \b UART_NO_DATA           
     *             <br>no receive data available
     *           - \b UART_BUFFER_OVERFLOW   
     *             <br>Receive ringbuffer overflow.
     *             We are not reading the receive buffer fast enough, 
     *             one or more received character have been dropped 
     *           - \b UART_OVERRUN_ERROR     
     *             <br>Overrun condition by UART.
     *             A character already present in the UART UDR register was 
     *             not read by the interrupt handler before the next character arrived,
     *             one or more received characters have been dropped.
     *           - \b UART_FRAME_ERROR       
     *             <br>Framing Error by UART
     */
    extern unsigned int uart_getc(void);
    
    
    /**
     *  @brief   Put byte to ringbuffer for transmitting via UART
     *  @param   data byte to be transmitted
     *  @return  none
     */
    extern void uart_putc(unsigned char data);
    
    
    /**
     *  @brief   Put string to ringbuffer for transmitting via UART
     *
     *  The string is buffered by the UART library in a circular buffer
     *  and one character at a time is transmitted to the UART using interrupts.
     *  Blocks if it can not write the whole string into the circular buffer.
     * 
     *  @param   s string to be transmitted
     *  @return  none
     */
    extern void uart_puts(const char *s );
    
    
    /**
     * @brief    Put string from program memory to ringbuffer for transmitting via UART.
     *
     * The string is buffered by the UART library in a circular buffer
     * and one character at a time is transmitted to the UART using interrupts.
     * Blocks if it can not write the whole string into the circular buffer.
     *
     * @param    s program memory string to be transmitted
     * @return   none
     * @see      uart_puts_P
     */
    extern void uart_puts_p(const char *s );
    
    /**
     * @brief    Macro to automatically put a string constant into program memory
     */
    #define uart_puts_P(__s)       uart_puts_p(PSTR(__s))
    
    
    
    /** @brief  Initialize USART1 (only available on selected ATmegas) @see uart_init */
    extern void UART1_init(unsigned int baudrate);
    /** @brief  Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
    extern unsigned int UART1_getc(void);
    /** @brief  Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
    extern void UART1_putc(unsigned char data);
    /** @brief  Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
    extern void UART1_puts(const char *s );
    /** @brief  Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
    extern void UART1_puts_p(const char *s );
    /** @brief  Macro to automatically put a string constant into program memory */
    #define UART1_puts_P(__s)       UART1_puts_p(PSTR(__s))
    
    /**@}*/
    
    
    #endif // UART_H
    Fuse-Bits sind auf 0xC2 und 0xBF

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    Wie ich sehe verwendest du 4 MHz Tackt. Kommen die vom internen Oszillator ? Wenn ja, solltest du mal einen externen Quarz probieren.
    Weiterhin solltest du schauen ob du 1 oder 2 Stopbits hast, und wie viele Datenbits eingestellt sind.

    Was noch ein Problem sein könnte, ist die konvertierung von char nach unsigned char bzw. umgekehrt.

  5. #5
    Bin in kompletter Neuling, kannst du mir bitte kurz erklären wie ich auf den exteren Qarz umstelle bzw woran ich sehe, wie viele datenbits ich habe?

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    Zum Quarz: Du kaufst dir einen externen Quarz z.B. mit 16MHz, schließt ihn wie in einem der vielen Tutorials gezeigt an und stellst die Fusebits auf externen High-Freq Quarz um.
    Die Datenbits siehst du daran,dass du deine UART initialisierung selber schreibst, anstatt eine fertige lib zu verwenden die das Kapselt, oder indem du den code der lib liest.

    Dann siehst du diese Zeile:

    Code:
     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        #ifdef URSEL
        UCSRC = (1<<URSEL)|(3<<UCSZ0);
        #else
        UCSRC = (3<<UCSZ0);
        #endif

Ähnliche Themen

  1. Hilfe bei Kommunikation über ISP-Schnittstelle
    Von Bumbum im Forum Software, Algorithmen und KI
    Antworten: 2
    Letzter Beitrag: 21.03.2013, 17:17
  2. Antworten: 3
    Letzter Beitrag: 25.11.2012, 20:56
  3. Brauche Hilfe bei der Kommunikation zweier Atmega über UART
    Von gm4288 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 27.12.2011, 22:47
  4. Datenformat bei der Übertragung über CAN
    Von elkokiller im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 11.08.2008, 12:56
  5. Wirres Zeug mit C bei der UART übertragung von µC zu PC
    Von MaN im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 01.09.2005, 19:59

Berechtigungen

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