mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Uart Transmit und receive via ein Puffer


Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe ein problem mit dem puffer verwaltung. mein programm soll daten 
via ein puffer empfangen und die daten werden im Puffer abgeholt und im 
bildschirm (Hyperterminal)gesendet. ich habe schon das programm ohne 
verwaltung des puffer geschrieben und es functionniert prima aber mit 
dem puffer habe ich einige probleme. es functionniert nicht so richtig 
mein programm sendt immer daas selbe zeichen unendlich obwohl ich 
mehrere zeichen im puffer gesendet habe. untern ist meine Quellecode 
kannt jemand durchschaut und mir sagen wo kann das problem sein
MFG
jean


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


  /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE


/*Size of the circular Transmit buffer, must be power of 2*/
 #ifndef UART_TX_BUFFER_SIZE
 #define UART_TX_BUFFER_SIZE 32
 #endif


// CHECK F_CPU WITH HARDWARE OSZILLATOR SETTING !!!!
#define F_CPU 1000000UL
#define UART_BAUD 9600

/*
 *  module global variables
 */
int g_idx;
int MAX_BUFFER_SIZE;
MAX_BUFFER_SIZE=UART_TX_BUFFER_SIZE;
unsigned char Buf[UART_TX_BUFFER_SIZE];
int bxoff = 0;
unsigned char c;

void uart_init(void);
unsigned int uart_getdata(void);
//unsigned char uart_getc(void);
void uart_putdata(unsigned char c);
//int uart_putc(unsigned char c);
void uart_puts (char *s);

int main(void)
{
   unsigned char c;



   uart_init();

   uart_puts("hello world!\r\n\r\n");

   while(1)
   {
      // Poll
      c = uart_getdata();


      // Echo
      uart_putdata(c);
   }

   return 0;
}

void uart_init(void)

/******************************************************************
 Function: Uart_init()
 Purpose: Initialise UART and set baudrate
 Input: baudrate
 Returns: none
 ******************************************************************/

{


  UCSRB |= (1<<TXEN) |(1<<RXEN);  // tx/rx enable
    UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1

#if F_CPU < 2000000UL && defined(U2X)
    UCSRA |= (1<<U2X);   /* improve baud rate error by using 2x clk */
    UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
    UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
}



void uart_putdata(unsigned char c)
{
    int n;
  n = g_idx;

    g_idx = 0;

    for ( g_idx=0; g_idx < n; g_idx++ ){

    c = Buf[g_idx];
  UDR=c;
    }

  bxoff=0;
  return;
  }



void uart_puts (char *s)


/**********************************************************************
 Function: Uart_puts()
 Purpose: Transmit string to UART
 Input: String to be transmitted
 Returns: none
 **********************************************************************/

{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putdata(*s);
        s++;
    }
}



unsigned int uart_getdata(void)
{
  if (bxoff == 0)
 {
    for ( g_idx=0; g_idx < MAX_BUFFER_SIZE; g_idx++ ){
    c=UDR;
   if (c == '\r'){
   return;
   }
   else
   Buf[g_idx]=c;
   }

  bxoff=1;
    return;
   }
 }

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

Bewertung
0 lesenswert
nicht lesenswert
Probier mal
//...
 while(1)
   {
      // Poll
      uart_getdata();


      // Echo
      uart_puts(Buf);
   }
Und schau dir nochmal an wie die Funktion uart_getdata() funktioniert 
und was die zurückgibt (Ein Tip: nichts sinnvolles ;) )
Außerdem gibts hier eine wunderbare uart-lib bei jump.to/fleury , da 
muss du das Rad nicht unbedingt neuerfinden.

hth. Jörg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du benutzt g_idx gleichzeitig (bzw. in zwei nacheinander aufgerufenen 
Funktionen) als Zählschleife und als globalen Pufferindex.

Wie kannst du sicher sein, dass es dabei den richtigen Wert (globalen 
Pufferindex) behält?

Welchen Wert sollte g_idx annehmen, wenn der Puffer ausgegeben wurde?

Was passiert, wenn in UDR in der Funktion uart_getdata keine Daten 
enthält? Bzw. warum enthält die entsprechende Funktion im Tutorial eine 
while()-Schleife?

Warum enthält die Sendefunktion im Tutorial eine while-Schleife vor dem 
Füllen des UDR?

Du versuchst mit bxoff einen Schalter zu realisieren, um zu Verhindern, 
dass der Puffer geichzeitig gefüllt und entleert wird. Das beisst sich, 
wenn du später vom Pollingbetrieb zum Interruptbetrieb wechselst. Du 
solltest frühzeitig ZWEI Pufferindicies verwenden - einen Leseindex und 
einen Schreibindex. Und du könntest dir im Weiteren Gedanken machen, wie 
du einen Überlauf/Zurüecksetzen am Pufferende realisierst.

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.