Forum: Mikrocontroller und Digitale Elektronik Problem mit ATMega32 UART RX


von Armin W. (coder2010)


Lesenswert?

Hallo,

Wieso wenn ich einen Text über 8 Zeichenlänge an Mega32 schicke bekomme 
ich nur 7 Zeichen zurück?
Wo liegt der Fehler, der Code ist Unten zu sehen, vielleicht kann mir 
jemand helfen.


#define F_CPU     16000000UL
#define false     0
#define true     1
#define uchar     unsigned char
#define uint     unsigned int


#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <math.h>
#include <avr/sleep.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>

//==============================================================
//Sendefunktionen
//==============================================================
void usart_putc(uint8_t byte){
//Ein Byte senden
while(!(UCSRA&(1<<UDRE)));//warten auf Datenregister empty
UDR=byte;
}
//--------------------------------------------------------------
void usart_puts(char *s)
//Einen String mit Endmarke 0 senden
{

    while (*s!=0) {
        usart_putc(*s);
    s++;
    }
    usart_putc(0); //Endmarke 0 übertragen!
}


//**** UART-Funktionen mit Interrupt ****
#define PUFFER_GROESSE 100   //Puffergröße in Byte

volatile unsigned char puffer[PUFFER_GROESSE];
volatile uint8_t lesezeiger;
volatile uint8_t schreibzeiger;

//====================================================================== 
=
//Serielle Schnittstelle mit 8 Bit, no parity, 1 Stoppbit 
initialisieren
//Den Datenempfang erledigt eine Interrupt-Service-Routine.
//====================================================================== 
=
void usart_init_intr(uint16_t baud){
  const uint32_t fosz=F_CPU;
  uint16_t baud_wert, ui1;

  lesezeiger=0;
  schreibzeiger=0;

  //Baudrate einstellen
  baud_wert=fosz/(baud*16L)-1;
  UBRRH=(uint8_t)(baud_wert>>8);
  UBRRL=(uint8_t)baud_wert;

  //8N1 Daten
  UCSRC =(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
  //Empfangen und Senden und Empfangsinterrupt aktivieren
  UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);

  for(ui1=0;ui1<PUFFER_GROESSE;ui1++)
  {
    puffer[ui1]=0;
  }
}

//=============================================================
// Interrupt-Service-Routine
//=============================================================
ISR (USART_RXC_vect){
puffer[schreibzeiger]=UDR;

usart_putc(puffer[schreibzeiger]); usart_putc('\r');

schreibzeiger++;
if(schreibzeiger >= PUFFER_GROESSE) schreibzeiger=0;
}
//=============================================================
//Funktionen für den interrupt-gesteuerten Datenempfang
//=============================================================
uint8_t usart_byte_avail_intr(void){
_delay_ms(10);
if(schreibzeiger!=lesezeiger)
return 1;
else return 0;
}

//--------------------------------------------------------------
char usart_getc_intr(void)
{
  char datenbyte=0;

  if(schreibzeiger!=lesezeiger)
   {
     datenbyte=puffer[lesezeiger];
     lesezeiger++;
     if(lesezeiger >= PUFFER_GROESSE) lesezeiger=0;
   }
  return datenbyte;
}




// *************************************   MAIN-Funktion
int main( void )
{
  // char  cBuffer[100];

  // JTAG-Bit setzen um es abzuschalten
  MCUCSR |= (1<<JTD);    // Setze JTAG-Bit auf 1
  MCUCSR |= (1<<JTD);    // Setze JTAG-Bit auf 1
  _delay_ms(100);

  DDRD= 0xff;
  PORTD=0;

  PORTD |= (1<<PD5);

  usart_init_intr(19200);
  sei();
  while(1)
  {
  }

  return(0);
}

von Stefan E. (sternst)


Lesenswert?

Für jedes Zeichen, das du im Interrupt empfängst, schickst du im selben 
Interrupt 2 Zeichen zurück. Da Senden und Empfangen mit der selben 
Geschwindigkeit funktionieren, gehen dir dann irgendwann Zeichen flöten, 
wenn sie zu dicht aufeinander eintreffen.

von Armin W. (coder2010)


Lesenswert?

Danke Stefan,

Ich arbeite momentan an einem Problem mit dem Auslesen des Ringpuffers, 
beim Leseversuch geht Mega32 irgendwie in einer Dauerschleife.
Siehe:
Beitrag "Bitte um HIlfe bei ATMega32_Code für UART RX"

Vielleicht kannst du mir da helfen, ich wäre dir sehr dankbar.

Gruß
Armin

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.