www.mikrocontroller.net

Forum: Compiler & IDEs probleme mit receive and Transmit data 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: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Funktion
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;
  }


solltest du noch mal überdenken.
* Was soll die Schleife denn da drinnen machen?
* Wie kann es sein, dass c überschrieben wird? c enthält
  doch das auszugebende Zeichen.
* Dem USART einfach ein Zeichen nach dem anderen hineinzustopfen
  ohne vorher abzufragen, ob der zur Ausgabe bereit ist, wird
  wohl nicht so toll funktionieren.

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

Bewertung
0 lesenswert
nicht lesenswert
Noch was:
Ich sehe grade du planst für das Senden und das Empfangen
den gleichen Buffer zu benutzen.

Keine gute Idee!
Senden und Empfangen sollten unabhängig voneinander funktionieren
können. Es kann ja wohl nicht sein, dass dein µC Daten
fehlerhaft empfängt, nur weil zufällig grade eine Ausgabe
läuft.

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

Bewertung
0 lesenswert
nicht lesenswert
und btw. Warum gibt's den Thread doppelt ? --> 
Beitrag "Re: Uart Transmit und receive via ein Puffer"

? Jörg

Autor: new kommen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die schleife soll die daten im puffer abholen und sie im hyperterminal 
senden. für die abfrage habe ich so versucht:


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];
while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
    {
    }

  UDR=c;
    }

  bxoff=0;
  return;
  }

aber es ging auc nicht.

die sache mit ein puffer habe so gewollt weil ich will nur ein klein 
test machen. und wenn es functionniert kann ich leicht 2 puffer 
verwendet

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

Bewertung
0 lesenswert
nicht lesenswert
new kommen wrote:
> die schleife soll die daten im puffer abholen und sie im hyperterminal
> senden. für die abfrage habe ich so versucht:
>

Das wird so nie was.
1. ist es nicht die Aufgabe von uart_putdata irgendwelche
Daten aus einem Buffer abzuholen, sondern es ist die Aufgabe
der Funktion 1 Byte auszugeben. Welches Byte sie ausgeben
soll, das bekommt die Funktion als Argument übergeben.

2. Überschreibst du dir ständig die globalen Variablen

Wenn du dir also das Zeichen, welches als Argument übergeben
bekommst überschreibst, dann wird dieses Zeichen danach nicht
mehr zur Verfügung stehen.
void uart_putdata(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR=c;
}

Wenn du jetzt einen Buffer einbauen möchtest, der das Zeichen
aufnimmt, weil die UART noch nicht sendebereit ist, dann ist
das eine völlig andere Geschichte.

Vor allen Dingen brauchst du dann eine Interruptsteuerung oder
einen sonstigen Mechanismus (Timer), der dafür sorgt, dass in
regelmässigen Abständen nachgesehen wird, ob die UART jetzt
sendebereit ist. Mit einem Interrupt geht das besonders elegant,
weil dir dann die UART selber mitteilt, dass sie jetzt sende-
bereit wäre, und das Programm das nächste Zeichen in das UDR
stopfen könnte.

Die put Funktion würde dann in etwa so aussehen
void uart_putdata(unsigned char c)
{
  cli();      /* damit nicht während dieser Abarbeitung ein
                 UART Interrupt zuschlägt. Ansonsten wird
                 das ziemlich kompliziert, dafür zu sorgen
                 dass globale Variablen nicht ihren Wert
                 ändern
              */

  if( UCSRA & (1<<UDRE) ) {     /* die UART ist sendebereit, daher
                                   wird das Zeichen sofort gesendet
                                */
    UDR = c;
  }
  else {                        /* die UART ist noch mit dem Senden
                                   eines anderen Zeichens beschäftigt
                                   -> das Zeichen im Ausgabepuffer parken
                                */
    buff[g_idx] = c;
    g_idx++;
                                /* die geparkten Zeichen werden später
                                   in der Interrupt Funktion ausgegeben
                                   die aufgerufen wird, wenn die UART
                                   wieder sendebereit ist
                                */

    ... Die Interruptsteuerung der UART aktivieren ...
  }

  sei();
}

Dazu musst du dir aber die Interrupt Steuerung der UART mal zu Gemüte
führen.

Autor: new kommen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bitte wie kann ich das machen? gibst mir bitte wenn möglich ein bsp von 
empfangen und senden mit puffer und mit benutzung von interrupt. schickt 
mir nicht zu den peter fleury lib weil ich habe schon mit den versucht 
aber es auch nicht functionniert. ich bitte deine verständniss
MFG
jean

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

Bewertung
0 lesenswert
nicht lesenswert
new kommen wrote:
> bitte wie kann ich das machen? gibst mir bitte wenn möglich ein bsp von
> empfangen und senden mit puffer und mit benutzung von interrupt.

Du wirst nicht umhin kommen, dir die entsprechenden Abschnitte
im Datenblatt deines Prozessors anzuschauen, dir mal ein paar
kleine Testprogramme zu schreiben um das auszuprobieren und
dann deine Funktionen zu machen.

Das hat den Vorteil, dass du dann auch verstehst was da eigentlich
abgeht.

Das haben vor dir 1000-de Programmierer so gemacht und das werden
auch nach dir 1000-e Programmierer tun. So ist nun mal das Los
aller derjenigen die sich 'Programmierer' schimpfen: Am Anfang
geht viel Zeit mit dem Studium von Handbüchern, Datenblättern etc.
drauf.

Autor: new kommen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Karl für die Hinweise. ich versucht mal wie du gesagt hast und 
wenn ich noch probleme habe melde ich mich wieder
MFG
Jean

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.