www.mikrocontroller.net

Forum: Compiler & IDEs UART Receive Transmit Via ein Puffer und behandlung mit Inte


Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich versuche eine Receive Transmit programm zu schreiben mit Puffer 
Vervaltung und es soll mit Interrupt behandeln werden. die daten sollen 
von der Tastatur eingegeben und in einem Puffer speichern und danach von 
dem Puffer abgeholt und im bildschirm gesendet. bei dem compilierung 
meines programm gibt es einigen Fehlern um diesen fehler zu korrigieren 
komme ich nicht klar.ich bitte ihre hilfe.
anbei ist meine code und untern sind die Fehler
N.B: ich benutze Die Mega 16 als Mikrocontroller
Ich danke Ihnen voraus
Jean

/**************************************************************
*                                                              *
*                         UART.c                                *
*                                                              *
***************************************************************/

/* Include-Dateien
   -----------------*/


#include <avr/io.h>
#include <avr/interrupt.h>

/* UCR - UART Control Register: Bit Definitionen
   -----------------------------------------------------------*/
#define     RXCIE    0x80    // Bit 7
#define     TXCIE    0x40    // Bit 6
#define     UDRIE    0x20    // Bit 5
#define     RXEN     0x10    // Bit 4
#define     TXEN     0x08    // Bit 3
#define     CHR9     0x04    // Bit 2
#define     RXB8     0x02    // Bit 1
#define     TXB8     0x01    // Bit 0

/* USR - UART Status Register: Bit Definitionen
    ---------------------------------------------------------*/
#define     RXC     0x80    // Bit 7
#define     TXC     0x40    // Bit 6
#define     UDRE    0x20    // Bit 5
#define     FE      0x10    // Bit 4
#define     OVR     0x08    // Bit 3

/* UBRR - UART Baudrate Register: Baud Definitionen fuer 4MHz
    ---------------------------------------------------------*/
#define     BAUD_1200     208
#define     BAUD_2400     103
#define     BAUD_9600     25
#define     BAUD_19200    12

/* UART Daten-Puffer Definitionen
    ------------------------------*/
#define BUFFER_SIZE     8     // Modulo 2 Groesse: nur 2,4,8,16,32 Bytes
#define BUFFER_MASK     (BUFFER_SIZE-1)

/* Allgemeine typ-Definitionen
    -----------------------------------------------------------*/
typedef enum{ FALSE=0, TRUE=1} Boolean_t ;

typedef struct{ unsigned char UartData[ BUFFER_SIZE ];
                unsigned char NumberOfBytes;
                unsigned char UartStatus; } Uart_t;

/* Static Variables
   -------------------*/
static unsigned char                RxBuf[ BUFFER_SIZE ];
static volatile unsigned char       RxProducer;  // Empfang: Int-Service ist der Producer
static volatile unsigned char       RxConsumer;  // Empfang: Hauptprogramm ist Consumer
static unsigned char                TxBuf[ BUFFER_SIZE ];
static volatile unsigned char       TxProducer;  // Senden: Hauptprogramm ist der Producer
static volatile unsigned char       TxConsumer;  // Senden: Int-Service ist Consumer

/* Funktion-Prototypen
   ----------------------------*/
void InitUart( unsigned char baudrate );
Boolean_t ReceiveData( Uart_t * Data );
Boolean_t TransmitData( Uart_t * Data );
void Delay( void );

/* Input Pins, Port B:               sfrb PINB    = 0x16;
   Data Direction Register, Port B:  sfrb DDRB    = 0x17;
   Data Register, Port B:            sfrb PORTB   = 0x18; */
void Delay( void )  // warte zeit
{
  unsigned int i= 0x7FFF;
  while(--i);
}


/* Main - ein einfaches Anwendungsbeispiel fuer UART und Timer
   -------------------------------------------------------------*/
void C_task main( void )
{
    Uart_t UartData;

    DDRB  = 0xFF ; // Konfiguriert Port B als Ausgang
    PORTB = 0xAA;

    InitUart( BAUD_9600 );     // Baudrate = 9600 Baud bei 4MHz Quarz
    _SEI();                      // Freigabe aller Interrupts => Enable UART Interrupts

    for( ;; )                  // Endlos-Schleife
    {
        if( ReceiveData( & UartData ) )
        {
          TransmitData( & UartData );     // Echo der empfangenen Bytes
        }

        PORTB++; // Nur zum Testen Led schalten
        Delay(); // damit das Programm nicht nur die UART Daten abfragt
    }
}

/* Initialisierung der UART
    ------------------------------*/
void InitUart( unsigned char baudrate )
{
    UBRR = baudrate;               // Baudrate setzen

                                  // Freigabe der UART Interrupts
    UCR =  TXEN | RXEN | RXCIE;   // ==> Senden/Empfangen/Empf.INT

    RxConsumer     = 0;            // Ruecksetzen der Puffer-Index
    RxProducer     = 0;
    TxConsumer     = 0;
    TxProducer     = 0;
}

/*  Empfangs-Interrupt Handler
    --------------------------- */
interrupt [UART_RX_vect] void UartRxIntHandler( void )
{
    unsigned char data;

    data = UDR;                 // Lesen der Empfangsdaten
    RxBuf[RxProducer] = data;   // Empfangenes Byte in Puffer ablegen
    RxProducer++;               // Bufferindex setzen
    RxProducer &=BUFFER_MASK;   // Index begrenzen und evtl. auf Puffer-Anfang

    if (RxProducer == RxConsumer )
    {
        // Fehler! Ueberlauf Empfangspuffer
    }
    if( data =='\r') Wenn return Taste gedruckt
    {
     RxProducer == RxConsumer ; // Überlauf simulieren
     // UCR=~RXCIE; //oder der   interrupt disable
    }

}

/*  Sende-Interrupt Handler
    --------------------------- */
interrupt [UART_UDRE_vect] void UART_TX_interrupt( void )
{
    // Test ob noch nicht fertig mit Senden
    if ( TxConsumer != TxProducer  ) // Nein, weiter machen mit senden
    {
        ++TxConsumer;               // Pufferindex aktualisieren
        TxConsumer &=BUFFER_MASK;   // Index begrenzen und evtl. auf Puffer-Anfang
        UDR = TxBuf[TxConsumer];    // Uebergabe eines Bytes
     }
        else  // fertig ,senden beenden
    {
        UCR &= ~UDRIE; // Disable UDRE interrupt
    }
}


/* UART Empfangsfunktion
   --------------------- */
Boolean_t ReceiveData( Uart_t * Data )
{
    unsigned char i=0;

    // Schleife zur Uebergabe der empfangenen Daten
    while (( RxConsumer != RxProducer ) && ( i < BUFFER_SIZE ) )
    {
       Data->UartData[i++] = RxBuf[RxConsumer++];

       RxConsumer &=BUFFER_MASK;   // Consumer-Index begrenzen und evtl. auf Puffer-Anfang
    }

    Data->NumberOfBytes = i ;

    if( i ) return TRUE ;
     else return FALSE ;
}

/* Sendefunktion
   --------------------- */
Boolean_t TransmitData( Uart_t * Data )
{
    unsigned char i=0;

    while (( i < Data->NumberOfBytes ) && ( i < BUFFER_SIZE ) )// Uebergabe Sendendaten
    {
       TxBuf[TxProducer++] = Data->UartData[i++] ;

       TxProducer &=BUFFER_MASK;   // Producer-Index begrenzen und evtl. auf Puffer-Anfang
    }

    UDR = TxBuf[TxConsumer];        // Senden Anstossen
    ++TxConsumer;
    TxConsumer &=BUFFER_MASK;   // Consumer-Index begrenzen

    UCR |=  UDRIE ;
    Data->NumberOfBytes = 0;
    return TRUE ;
}

Die Fehler:


uartpuffer.c:81: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before 'main'
uartpuffer.c:120: error: '__vector_9' undeclared here (not in a 
function)
uartpuffer.c:120: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'void'
uartpuffer.c:143: error: '__vector_10' undeclared here (not in a 
function)
uartpuffer.c:143: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'void'
make.exe: *** [uartpuffer.o] Error 1

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der erste Fehler wird von dem unbekannten Ausdruck "C_task" ausgelöst. 
Der Rest ist wahrscheinlich ähnlich.

Versucht du mit AVR-GCC oder WinAVR eine Source (z.B. aus den Atmel 
Application Notes) zu übersetzen, die für einen anderen C-Compiler 
(IAR?) geschrieben ist?

http://www.avrfreaks.net/index.php?name=PNphpBB2&f...
http://www.avrfreaks.net/wiki/index.php/Documentat...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> interrupt [UART_RX_vect] void UartRxIntHandler( void )
Das sieht mir doch stark nach CodeVision-Syntax aus. Ist jedenfalls kein 
WINAVR und funktioniert vermutlich deshalb auch nicht... Du solltest Dir 
in der AVR-libc-Doku und/oder im AVR-GCC-Tutorial die Syntax von 
solchen Sachen mal ansehen.

Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja ich compiliere mit Winn Avr weil mit IAR komme ich nicht klar.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jean wrote:
> ja ich compiliere mit Winn Avr weil mit IAR komme ich nicht klar.
Aha, also IAR und kein CodeVision... Dann musst Du aber auch Dein 
Programm der WINAVR-Syntax anpassen. Die ganzen Interrupt-Sachen sind 
nicht Standard und deshalb bei jedem Compiler anders implementiert.

Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn jemand dieses programm in der plateform von AVR übersetzen kann es 
wird mir sehr helfen ich bitte Ihnen

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ..wenn jemand dieses programm in der plateform von AVR übersetzen kann...
Warum? Solche Sachen wurden schon für den AVR-GCC gemacht, z.B. von 
Peter Fleury ( http://jump.to/fleury bei "AVR  Software" )

hth. Jörg

Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die bibliothek von Fleury habe ich gesehen und versucht mal mit dem zu 
arbeiten aber es hat nicht functionniert deswegen bin ich im forum 
gekommen um hilfe zu suchen. Bitte jörg wenn du mein Programm für den 
AVR-GCC übersetzen kann, hilfe mir bitte

jean

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau Dir doch bitte einfach mal die WINAVR-Syntax für Interrupt-Handler 
an. Das ist (bis auf möglicherweise ein paar Kleinigkeiten) eigentlich 
das einzige, was noch angepasst werden muss. Und Du wirst vermutlich mit 
der Delay-Funktion Probleme bekommen, weil ein optimierender Compiler 
die leere while-Schleife möglicherweise wegoptimiert.

Es bringt überhaupt nichts, wenn Du versuchst, (vermutlich) 
zusammenkopierten Code, den Du überhaupt nicht verstehst, auf ein 
anderes System zu übertragen, das Du wahrscheinlich noch weniger 
verstehst, als dasjenige, mit dem Du nach Deinen Angaben schon nicht 
klarkommst. IAR ist ein kommerzielles Programm mit Support und 
ausgefeilter Doku. Wenn es damit schon nicht klappt, was willst Du dann 
mit einem Open-Source-Projekt wie AVR-GCC anfangen? Versuche bitte 
wenigstens, das ganze zu verstehen. Und wenn Du es im Ansatz verstanden 
hast, dann wirst Du auch die notwendigen Änderungen selbst vornehmen 
können.

Autor: MNR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal davon abgesehen, das die Lib von Peter Fleury im Allgemeinen ganz 
wunderbar funktioniert...

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei der "Fleury-Lib" ist ein Testprogramm "test_uart.c" und eine 
ziemlich gute Doku (u.a. als .chm, in englisch) dabei. Du musst nur:
a) die Datei "uart.c" zu deinem Projekt hinzufügen
b) die Datei "uart.h" in der Main-Datei include'n
c) Aus der Datei test_uart.c alles abschreiben und anpassen, was mit du 
für den uart brauchst
Wenn's sein muss, kannst du noch "UART_RX_BUFFER_SIZE" ändern.

hth. Jörg
ps.: falls die englische Doku das Problem darstellt, frag hier nach

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.