www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART gibt zu viele Zeichen aus


Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ich bin gerade dabei ein kleines Programm zu schreiben welches einfach 
nur das über UART empfangene Byte wieder zurückschickt. Das ist mein 
erstes C Projekt, hab davor aber schon in ASM programmiert und versteh 
eig alles. Das Problem ist jetzt, wenn ich eine "1" sende, bekomm ich 
eine "1" zurück, hintendran aber noch 5-10 andere Zeichen, die immer 
anders sind und keinen Sinn ergeben. Z.B. sende ich "1" und bekomme 
"1MÞÞß" zurück.. was läuft da falsch?
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>

#define F_CPU 16000000L
#define BAUD 9600L
#define UBRR_VAL ((F_CPU/(BAUD*16))-1)

void UART_init()
{
   UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
    UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
   
int main (void) {
      
    DDRC = 0xFF;
   
   UART_init();   

    sei();

   bytecount=1;


   while(1)
   ;
}

SIGNAL(SIG_UART_RECV)
{
    unsigned char buffer;

    buffer = UDR;

    while ( !( UCSRA & (1<<UDRE)) )
        ;
    UDR = buffer;
} 

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Dominik (Gast)

>nur das über UART empfangene Byte wieder zurückschickt. Das ist mein

Mach es so, ohne diverse Änderungen

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

MfG
Falk

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
mein Ziel ist nicht dass das programm später mal ein Byte empfängt und 
wieder zurückschickt.. Ich hab das nur als Test geplant und wie ich sehe 
funtkioniert das nicht. Ich hab den Code schon fast 1:1 aus dem Inet 
übernommen, mit dem selben ergebnis. Hat jemand ne Idee?

Autor: Daniel Goßmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Evtl.
#define F_CPU 16000000L
 als UL deklarieren?

Gruß
Daniel

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht denn die Hardware aus - evtl. fängt da etwas an zu schwingen

Gruss Otto

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soo.. ich war mal wieder etwas dumm.. passiert mir irgwie öfters.. Ich 
hatte vergessen die 5V vom Max232 anzuschließen. Jetzt kommt genau das 
zum PC zurück was kommen soll.. Nächstes Problem ist aber schon da. Ich 
hab eine variable, die bis 80 zählen muss, aber komischerweiße bricht 
sie bei 75 ab und fängt bei 0 oder irgendeiner anderen Zahl an. Ich find 
den Fehler aber irgendwie nicht. Kann mir einer von euch helfen?
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

//#define F_CPU 16000000
#define BAUD 19200L
#define UBRR_VAL ((F_CPU/(BAUD*16))-1)

uint8_t spalten[16][5];
uint8_t bytecount;

void schieb ()
{  
  PORTC|=(1<<PC2);
  PORTC&=~(1<<PC2);
  return;
}
void setdata ()
{
  PORTC|=(1<<PC1);
  PORTC&=~(1<<PC1);
  return;
}
void clrreg()
{
  PORTC = 0x00;

  
  uint8_t i;
  for (i=1; i <= 56; ++i)
  {
    schieb();
  }
  setdata();
  return;
}
void UART_init()
{
  UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
    UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
void UART_send(unsigned char c)
{
  while ( !( UCSRA & (1<<UDRE)) )
        ;
  UDR = c;
  return;
}  
int main (void) {
      
    DDRC = 0xFF;
  
  UART_init();
  clrreg();   

    sei();

  bytecount=1;


  while(1)
  ;
}

ISR(USART_RXC_vect)
{
    uint8_t data;

    data = UDR;

  if(bytecount<=5)
  {
    spalten[1][bytecount] = data;
  }
  else if((bytecount>5) && (bytecount<=10))
  {
    spalten[2][bytecount-5] = data;
  }
  else if((bytecount>10) && (bytecount<=15))
  {
    spalten[3][bytecount-10] = data;
  }
  else if((bytecount>15) && (bytecount<=20))
  {
    spalten[4][bytecount-15] = data;
  }
  else if((bytecount>20) && (bytecount<=25))
  {
    spalten[5][bytecount-20] = data;
  }
  else if((bytecount>25) && (bytecount<=30))
  {
    spalten[6][bytecount-25] = data;
  }
  else if((bytecount>30) && (bytecount<=35))
  {
    spalten[7][bytecount-30] = data;
  }
  else if((bytecount>35) && (bytecount<=40))
  {
    spalten[8][bytecount-35] = data;
  }
  else if((bytecount>40) && (bytecount<=45))
  {
    spalten[9][bytecount-40] = data;
  }
  else if((bytecount>45) && (bytecount<=50))
  {
    spalten[10][bytecount-45] = data;
  }
  else if((bytecount>50) && (bytecount<=55))
  {
    spalten[11][bytecount-50] = data;
  }
  else if((bytecount>55) && (bytecount<=60))
  {
    spalten[12][bytecount-55] = data;
  }
  else if((bytecount>60) && (bytecount<=65))
  {
    spalten[13][bytecount-60] = data;
  }
  else if((bytecount>65) && (bytecount<=70))
  {
    spalten[14][bytecount-65] = data;
  }
  else if((bytecount>70) && (bytecount<=75))
  {
    spalten[15][bytecount-70] = data;
  }
  else if((bytecount>75) && (bytecount<=80))
  {
    spalten[16][bytecount-75] = data;
  }
  
  if (bytecount>=80)
  {                          
    bytecount = 0;
    UART_send('F');
  }
  UART_send(bytecount);
  bytecount++;
  return;
}

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soo.. hab auch den Fehler gefunden.. eher gesagt mein Vater.. Problem 
war ein Speicherüberlauf.. Spalte ist als Array [16][5] definiert und da 
das ja bei 0 anfängt bin ich eins zu weit und der hat dafür mein 
bytecount gekillt.. Jetzt funktioniert das.. Danke an alle!

Autor: David Madl (md2k7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das, was du in der ISR machst, lässt sich wesentlich eleganter lösen. 
Ein Beispiel:
ISR(USART_RXC_vect)
{
  uint8_t data = UDR;

  spalten[bytecount / 5][bytecount % 5] = data;
  
  if (bytecount >= 79)
  {                          
    bytecount = 0;
    UART_send('F');
  }
  UART_send(bytecount);
  bytecount++;
  return;
}

ACHTUNG: Dein bytecount beginnt ebenfalls bei 0! Wenn du bis 80 zählen 
willst, muss die Bedingung im if so sein, wie ich das da oben 
geschrieben habe.

Und noch was:
if(bytecount<=5)
  {
    spalten[1][bytecount] = data;
  }

Hierbei kann auch versucht werden, auf spalten[1][5] zuzugreifen, was zu 
einem Speicherzugriffsfehler führen wird, den du nicht einmal merkst - 
erst, wenn das Programm sporadisch komische Sachen macht.


EDIT: bytecount sollte bei 0 beginnen mein ich :o)

Autor: 6632 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Division in einer ISR ? Hilfe......

Autor: David Madl (md2k7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 6632: Wenn der OP meint, er muss in der ISR mit einer Endlosschleife
warten, bis der UART das Zeichen gesendet hat, macht eine Division da
nicht mehr viel Unterschied.

Außerdem braucht die Division nur so um die 80 Zyklen.

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.