Forum: Mikrocontroller und Digitale Elektronik Problem mit UART beim empfangen


von Lisa K. (lissy)


Lesenswert?

Hallo an alle,

erst mal ich bin ein absoluter Neuling in diesem Gebiet, verzeicht mir 
also bitte meine (Anfänger-) Fehler =)

Ich möchte Daten zwischen einem Terminal (PC über RS-232) und meinem 
Mikrocontroller (ATMEGA 164 PA) austauschen. Beim senden vom atmega an 
den PC sehe ich die Zeichen auch auf dem Terminal, nur das empfangen 
klappt nicht so recht

Programmaufbau (theoretisch):
UART initialisieren
leere Endlosschleife
Interrupt wenn Controller Daten senden soll (TX)
Interrupt wenn Controller Daten empfangen soll (RX)

Die Daten sollen dann entweder direkt in der ISR gesendet/empfangen 
werden oder in der ISR soll ein Flag gesetzt werden, welches dann in der 
Endlosschleife überprüft wird.

Ich hoffe das war jetzt verständlich...wär lieb wenn jemand helfen 
könnte
 danke schon mal an alle


Hier noch mein Codevorschlag:
1
//Header einbinden
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
#include <avr/interrupt.h>
6
7
//Definitionen
8
#define RXB8 1
9
#define TXB8 0
10
#define UPE 2
11
#define OVR 3
12
#define FE 4
13
#define UDRE 5
14
#define RXC 7
15
#define FRAMING_ERROR (1<<FE)
16
#define PARITY_ERROR (1<<UPE)
17
#define DATA_OVERRUN (1<<OVR)
18
#define DATA_REGISTER_EMPTY (1<<UDRE)
19
#define RX_COMPLETE (1<<RXC)
20
21
22
//Prototypen der Funktionen
23
void USART_Init( unsigned int baud );
24
void sendenByte( unsigned char data );
25
unsigned char empfangenByte( void );
26
27
28
int main(void)
29
{
30
31
    
32
    //UART initialisieren
33
    USART_Init(9600);
34
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
35
    //Interrupts aktivieren
36
    sei();
37
    
38
  
39
    while(1)
40
    {
41
    }
42
}
43
44
void USART_Init( unsigned int baud )
45
{
46
  //Baudrate setzen: (8MHz / (16*baud))-1 = 51 --> 33hex
47
  UBRR0H=0x0;
48
  UBRR0L=0x33;
49
  //keine error-bits gesetzt
50
  UCSR0A = 0x00;
51
  //Interrupts enable, receiver und transmitter enable
52
  UCSR0B = 0xF8;
53
  //asynchroner modus, kein parity bit, 1 stop bit, 8 datenbits
54
  UCSR0C = 0x06;
55
  //Global Interrupt Flag loeschen (Bit 0 bei SREG)
56
  //SREG &= ~(1 << 0);
57
}
58
59
60
void sendenByte( unsigned char data )
61
{
62
  //Sendekanal aktivieren (Bit 3 in UCSR1B)
63
  UCSR0B &= ~(1 << TXEN0);
64
  //pruefen ob vorherige Uebertragung abgeschlossen
65
  if ((UCSR0A & (1 << UDRE0)))
66
  {
67
    for (int i=8; i<=0; i--)
68
    {
69
      UDR0 = data;
70
      //UCSR1A |= (1 << UDRE1);
71
    }
72
    UDR0 = data;
73
  } else
74
  {
75
    sendenByte(data);
76
  }
77
  //Receiver wieder enable
78
  UCSR0B |= (1 << TXEN0);
79
}
80
81
unsigned char empfangenByte( void )
82
{
83
  unsigned char data;
84
  //Emfangskanal aktivieren (Bit 4 in UCSR1B
85
  UCSR0B &= ~(1 << RXEN0);
86
  //solange RXC noch nicht gesetzt Daten empfangen
87
  if (UCSR0A | (1 << RXC0))
88
  {
89
    for (int i=8; i<=0; i--)
90
    {
91
      //Daten empfangen
92
      data = UDR0;
93
    }
94
  }
95
96
  return data;
97
}
98
99
 ISR  (USART0_TX_vect)
100
 {
101
    sendenByte(0xAA);
102
 }
103
 ISR (USART0_RX_vect)
104
 {
105
   empfangenByte();
106
 }

von Karl H. (kbuchegg)


Lesenswert?

1
unsigned char empfangenByte( void )
2
{
3
  unsigned char data;
4
  //Emfangskanal aktivieren (Bit 4 in UCSR1B
5
  UCSR0B &= ~(1 << RXEN0);
6
  //solange RXC noch nicht gesetzt Daten empfangen
7
  if (UCSR0A | (1 << RXC0))
8
  {
9
    for (int i=8; i<=0; i--)
10
    {
11
      //Daten empfangen
12
      data = UDR0;
13
    }
14
  }
15
16
  return data;
17
}

das ist Quatsch.

Erst mal: lass die Enable Bits in Ruhe. Zweites brauchst du auch nicht 
prüfen, ob etwas empfangen wurde. Die ISR wurde aufgerufen WEIL etwas 
empfangen wurde - d.h. du weißt an dieser Stelle, dass was da ist.
Drittens: wozu die for-Schleife? Der Interrupt wird für jedes Zeichen 
einzeln aufgerufen und ja - du MUSST das UDR auslesen.


ISR (USART0_RX_vect)
{
  char c = UDR;

  // mach was mit c
}

und lass die ENable Bits in Ruhe! Wenn die UART aktiv ist, dann bleibt 
sie auch die ganze Zeit aktiv.

von Paule H. (stk500-besitzer)


Lesenswert?

Also entweder entscheidest du dich für einen Empfang per Interrupt oder 
per Polling. Momentan schmeisst du beides zusammen.

Hast du dich bei deinem Programm an den Besipielen im Datenblatt 
orientiert?

von Lisa K. (Gast)


Lesenswert?

Danke schon mal für die Hilfe...

eigentlich würde ich das ganze gern Interrupt-gesteuert machen

orientiert habe ich mich am Datenblatt...wenn ich das allerdings 
übernommen habe, hat das bei mir nicht funktioniert =(

Hier die Funktion für das Empfangen aus dem Datenblatt

unsigned char USART_Receive( void )
{
    /* Wait for data to be received */
    while ( !(UCSRnA & (1<<RXCn)) );
/* Get and return received data from buffer */
return UDRn;
}


@ Karl Heinz Buchegger:
danke für den Tipp, wie gesagt bin blutiger Anfänger, unerfahren und 
noch etwas verwirrt =( hab das mal so ausprobiert, leider kann ich immer 
noch nichts empfangen, bin ich echt so blöd =(

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
void sendenByte( unsigned char data )
2
{
3
  //Sendekanal aktivieren (Bit 3 in UCSR1B)
4
  UCSR0B &= ~(1 << TXEN0);
5
  //pruefen ob vorherige Uebertragung abgeschlossen
6
  if ((UCSR0A & (1 << UDRE0)))
7
  {
8
    for (int i=8; i<=0; i--)
9
    {
10
      UDR0 = data;
11
      //UCSR1A |= (1 << UDRE1);
12
    }
13
    UDR0 = data;
14
  } else
15
  {
16
    sendenByte(data);
17
  }
18
  //Receiver wieder enable
19
  UCSR0B |= (1 << TXEN0);
20
}

ist .... ich sags nicht, was mir da auf der Zunge liegt.
Das ist eine rekursive Funktion, ist dir das bewusst, was damit 
zusammenhängt?

Ausserdem ist das viel zu kompliziert
1
void sendenByte( unsigned char data )
2
{
3
  while( !(UCSR0A & (1 << UDRE0))
4
    ;
5
6
  UDR0 = data;
7
}

das ist eine Funktion, die 1 Byte versendet. Wenn du mehrere Bytes 
verschicken willst, dann rufst du die Funktion eben mehrfach auf:
1
void sendeMehrfach( unsigned char c )
2
{
3
  uint8_t i;
4
5
  for( i = 0; i < 8; ++i )
6
    sendenByte( c );
7
}

Aber du musst VOR jeder Ausgabe an UDR prüfen, ob dir UDRE0 das 
überhaupt erlaubt. Du kannst nicht einfach 30 Bytes an UDR0 zuweisen. 
Der letzte Ansatz gewährleistet das, weil sendenByte genau das tut: Bei 
jedem einzelnen Byte so lange zuzuwarten, bis die UART wieder frei ist.

von Lisa K. (Gast)


Lesenswert?

Also ich hab mal einen Breakpoint in die ISR gesetzt, leider wird die 
bei mir nie ausgeführt, der Sprung in den Interrupt wird durchgeführt...

Kann es sein dass "USART0_RX_vect" nie wahr wird, muss ich dafür erst 
etwas gesendet haben um in diese ISR zu kommen?

Tut mir Leid wenn ich mich so blöd anstelle, aber ich weiß es wirklich 
nicht besser, hab davor eher Java, etc. gemacht

von Karl H. (kbuchegg)


Lesenswert?

Hast du irgendwelche Warnungen vom Compiler.
Irgendwas in Richtung: xxxxx seems to be an illegal Interrupt Name

> ISR (USART0_RX_vect)

meistens heißt die irgendwas in Richtung

ISR (USART0_RXC_vect)

RX steht für Receive und das C für Complete. Genau aus dem Grund heißt 
ja auch die Freigabe für den Interrupt

>     UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);


RXCIE0

  RX   Receive
  C    Complete
  I    Interrupt
  E    Enable
  0    der UART 0

von Karl H. (kbuchegg)


Lesenswert?

Lisa K. schrieb:

> @ Karl Heinz Buchegger:
> danke für den Tipp, wie gesagt bin blutiger Anfänger, unerfahren und
> noch etwas verwirrt =( hab das mal so ausprobiert, leider kann ich immer
> noch nichts empfangen, bin ich echt so blöd =(


Dann solltest du vielleicht nicht gerade gleich mal mit Interrupts 
einsteigen.

AVR-GCC-Tutorial

von Lisa K. (Gast)


Lesenswert?

Errors habe ich nicht, aber 2 Warnings:

#warning "F_CPU not defined for <util/delay.h>"

Warning  unused variable 'c'


xxxxx seems to be an illegal Interrupt Name  kommt bei mir nicht

von Karl H. (kbuchegg)


Lesenswert?

Stimmt.

Der Vector heisst wirklich

#define USART0_RX_vect      _VECTOR(20)

(zu finden in iomxx4.h welches von iom64.h includiert wird, welches von 
io.h includiert wird - wenn die µC Einstellung stimmt.)

von Karl H. (kbuchegg)


Lesenswert?

>   //Interrupts enable, receiver und transmitter enable
>  UCSR0B = 0xF8;


Was macht das alles?

Mach deine erste Kommunikation erst mal ohne INterrupts, ok?

von Lisa K. (Gast)


Lesenswert?

mit polling habe ich es bereits versucht, dabei habe ich zumindest Daten 
auf dem Terminal erhalten

Hier mal der Code:
1
/*
2
 * Test_UART0.c
3
 *
4
 * Created: 14.05.2013 13:23:33
5
 *  Author: u56460
6
 */ 
7
8
//Header einbinden
9
#include <avr/io.h>
10
#include <util/delay.h>
11
#include <stdint.h>
12
13
//Definitionen
14
#define RXB8 1
15
#define TXB8 0
16
#define UPE 2
17
#define OVR 3
18
#define FE 4
19
#define UDRE 5
20
#define RXC 7
21
22
#define FRAMING_ERROR (1<<FE)
23
#define PARITY_ERROR (1<<UPE)
24
#define DATA_OVERRUN (1<<OVR)
25
#define DATA_REGISTER_EMPTY (1<<UDRE)
26
#define RX_COMPLETE (1<<RXC)
27
28
29
//Prototypen der Funktionen
30
void initUART( void);
31
void sendenByte( unsigned char data );
32
33
34
int main(void)
35
{
36
  initUART();
37
  
38
    while(1)
39
    {
40
    //Daten senden
41
    sendenByte(0xAA);
42
  
43
    }
44
}
45
46
void initUART( void )
47
{
48
  int ubrr;
49
  UCSR0A=0x00;
50
  // Receiver und Transmitter enable
51
  UCSR0B=0x18;
52
  //asynchroner Modus, kein Parity, 1 Stop Bit, 8 Datenbits
53
  UCSR0C=0x06;
54
  //Baudrate setzen:
55
  UBRR0H=0x00;
56
   UBRR0L=0x33;
57
58
59
  //analoger Comparator disable
60
  ACSR=0x80;
61
  // Analog Comparator Input Capture by Timer/Counter 1: Off
62
  //analoger Comparator Multiplexer enable
63
  ADCSRB=0x00;
64
  
65
}
66
67
68
void sendenByte( unsigned char data )
69
{
70
  //Sendekanal aktivieren (Bit 3 in UCSR1B)
71
  UCSR0B &= ~(1 << TXEN0);
72
  //pruefen ob vorherige Uebertragung abgeschlossen
73
  if ((UCSR0A & (1 << UDRE0)))
74
  {
75
    for (int i=8; i<=0; i--)
76
    {
77
      UDR0 = data;
78
      //UCSR1A |= (1 << UDRE1);
79
    }
80
    UDR0 = data;
81
  }  //Receiver wieder enable
82
  UCSR0B |= (1 << TXEN0);
83
}


Zudem sollte ich den Interrupt für eine Aufgabe für die Schule erledigen 
=(

von Lisa K. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
>>   //Interrupts enable, receiver und transmitter enable
>
>>  UCSR0B = 0xF8;

das sollte laut Registerbeschreibung (wenn ich das so richtig verstanden 
habe) RXC Interrupt, TXC Interrupt und UDR empty Interrupt aktivieren, 
sowie den Empfänger und den Sender aktivieren

von Karl H. (kbuchegg)


Lesenswert?

OK.

Paule hats oben schon gesagt: du hast da einen höllischen Mischmasch 
veranstaltet.

Langsam vorgehen. Eins nach dem anderen.
Geh von deiner Polling Lösung aus und mach erst mal nur den 
Empfangsinterrupt.

von Karl H. (kbuchegg)


Lesenswert?

>   UCSR0B=0x18;
>  //asynchroner Modus, kein Parity, 1 Stop Bit, 8 Datenbits

Bitte nicht.
Die Bits haben Namen. Niemand hier hat Lust, das Datenblatt zu wälzen 
nur um rauszufinden, welche BIts du benutzt hast.

Im AVR-GCC-Tutorial gibt es einen Abschnitt über den UART. Orientier 
dich daran.

von Uwe (de0508)


Lesenswert?

Anmerken möchte ich noch, dass manchmal überalterte Datenblätter 
verwendet werden.
Das kann dann zu Missverständnissen führen.

Die aktuellen enthalten i.a. weniger Fehler und mehr Erläuterungen:

http://www.atmel.com/Images/Atmel-8011-8-bit-AVR-Microcontroller-ATmega164P-324P-644P_datasheet.pdf

von Lisa K. (Gast)


Lesenswert?

Also ich hab das Ganze jetzt noch eine Weile probiert, finde das gar 
nicht so einfach wie alle immer sagen :D

Danke noch an Uwe S. für das Datenblatt

Hier noch mal mein bisheriger Code (der leider immer noch nicht 
funktioniert)
1
//Header einbinden
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
#include <avr/interrupt.h>
6
7
//Definitionen
8
#define RXB8 1
9
#define TXB8 0
10
#define UPE 2
11
#define OVR 3
12
#define FE 4
13
#define UDRE 5
14
#define RXC 7
15
16
#define FRAMING_ERROR (1<<FE)
17
#define PARITY_ERROR (1<<UPE)
18
#define DATA_OVERRUN (1<<OVR)
19
#define DATA_REGISTER_EMPTY (1<<UDRE)
20
#define RX_COMPLETE (1<<RXC)
21
22
23
//Prototypen der Funktionen
24
void USART_Init( void );
25
void sendenByte( unsigned char data );
26
void sendeMehrfach( unsigned char c );
27
28
//Variablen deklarieren
29
char receivedData;
30
31
int main(void)
32
{
33
34
    //UART initialisieren
35
    USART_Init();
36
    //Interrupts aktivieren
37
    //SREG |= (1<<7);
38
    
39
  
40
    while(1)
41
    {
42
    sendenByte(0xAA);
43
    }
44
}
45
46
void USART_Init( void )
47
{
48
  //Baudrate setzen: 8MHz, 9600 baud
49
         //33 hex nach Datenblatt-Tabelle
50
  UBRR0H=0x0;
51
  UBRR0L=0x33;
52
  //Interrupts enable
53
  UCSR0B |= (1 << RXCIE0);
54
  UCSR0B |= (1 << TXCIE0);
55
  UCSR0B |= (1 << UDRIE0);
56
  //Receiver und Transmitter enable
57
  UCSR0B |= (1 << RXEN0);
58
  UCSR0B |= (1 << TXEN0);
59
  //asynchroner modus, kein parity bit, 1 stop bit, 8 datenbits
60
  UCSR0C |= (1 << UCSZ01);
61
  UCSR0C |= (1 << UCSZ00);
62
63
}
64
65
void sendenByte( unsigned char data )
66
{
67
  while( !(UCSR0A & (1 << UDRE0)))
68
  ;
69
70
  UDR0 = data;
71
}
72
73
74
void sendeMehrfach( unsigned char c )
75
{
76
  uint8_t i;
77
78
  for( i = 0; i < 8; ++i )
79
  sendenByte( c );
80
}
81
82
83
//Daten erhalten (wenn es ungelesene Daten gibt, diese empfangen)
84
ISR (USART0_RX_vect)
85
{
86
  receivedData = UDR0;
87
}

Allerdings habe ich es noch nie geschafft, dass mit USART0_RX_vect oder 
USART0_TX_vect ein Interrupt ausgelöst wird. Bisher hat das bei mir nur 
mit USART0_UDRE_vect geklappt. Woran könnte das liegen oder was mache 
ich alles falsch?
Senden klappt inzwischen leider auch nicht mehr =(

von Cyblord -. (cyblord)


Lesenswert?

Sehe kein sei() in deinem Code. Wie soll dann ein Interrupt ausgelöst 
werden?

Ah grade gesehen:
1
//Interrupts aktivieren
2
//SREG |= (1<<7);

Zwar auskommentiert aber da.

Dein Code ist furchtbar. Da schreibt man ein
1
sei();

um die Interrupts zu aktivieren.

gruß cyblord

von Uwe (de0508)


Lesenswert?

Hallo Lisa.

wie Karl-Heinz schon schrieb, mache es erstmal ohne Interrupts.

Auch darfst Du nicht gleich alle ISR frei schalten, dann fehlen noch die 
passenden ISR dazu und du musst auch verstehen, wann einer der ISR frei 
geschaltet werden darf !

von Karl H. (kbuchegg)


Lesenswert?

Lisa K. schrieb:

>   //Interrupts enable
>   UCSR0B |= (1 << RXCIE0);
>   UCSR0B |= (1 << TXCIE0);
>   UCSR0B |= (1 << UDRIE0);


Hüte dich vor solchen Rundumschlägen!

Wenn du einen INterrupt freigibst, dann MUSS es dafür auch eine ISR 
geben! Das ist ganz wichtig. Denn wenn du keine ISR dafür hast, dann 
tritt ein Default in Kraft, der zu einem µC-Reset führt!


Eventuell ist es für dich sinnvoll, am Programmstart, nachdem die UART 
initialisiert wird, erst mal einen bekannten Text (oder zeichen) 
auszugeben, damit dir solche Dinge nicht verborgen bleiben
1
void sendeString( char* text )
2
{
3
  while( *text )
4
    sendenByte( *text++ );
5
}
6
7
8
int main(void)
9
{
10
    //UART initialisieren
11
    USART_Init();
12
 
13
14
   sendeString( "Reset\n" );
15
16
   //Interrupts aktivieren
17
    //SREG |= (1<<7);
18
19
   sei();  // <------    
20
  
21
   while(1)
22
   {
23
     sendenByte(0xAA);
24
   }
25
}


Das geht allerdings nur so lange, solange du das Senden noch nicht über 
Interrupts abwickelst. Denn dann geht natürlich vor den sei() erst mal 
auch das Senden nicht. Aber bis dahin ist ja noch Zeit.

von Lisa K. (Gast)


Lesenswert?

Ok also hier noch die abgeänderte Polling-Version:
1
//Header einbinden
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
6
//Definitionen
7
#define RXB8 1
8
#define TXB8 0
9
#define UPE 2
10
#define OVR 3
11
#define FE 4
12
#define UDRE 5
13
#define RXC 7
14
15
#define FRAMING_ERROR (1<<FE)
16
#define PARITY_ERROR (1<<UPE)
17
#define DATA_OVERRUN (1<<OVR)
18
#define DATA_REGISTER_EMPTY (1<<UDRE)
19
#define RX_COMPLETE (1<<RXC)
20
21
22
23
//Prototypen der Funktionen
24
void initUART( void);
25
void sendenByte( unsigned char data );
26
void sendeMehrfach( unsigned char c )´;
27
unsigned char empfangenByte( void );
28
void sendeString( char* text );
29
30
//Variablen deklarieren
31
unsigned char ausgabe;
32
int baud = 9600;
33
34
35
int main(void)
36
{
37
  initUART();
38
  
39
  sendeString( "Reset\n" );
40
41
  //Interrupts aktivieren
42
  sei();
43
  
44
    while(1)
45
    {
46
    //Daten senden
47
    sendenByte(0xAA);
48
  
49
    }
50
}
51
52
void USART_Init( void )
53
{
54
  //Baudrate setzen: 8MHz, 9600 baud --> 33 hex nach Datenblatt-Tabelle
55
  UBRR0H=0x0;
56
  UBRR0L=0x33;
57
  //Interrupts enable
58
  UCSR0B |= (1 << RXCIE0);
59
  UCSR0B |= (1 << TXCIE0);
60
  UCSR0B |= (1 << UDRIE0);
61
  //Receiver und Transmitter enable
62
  UCSR0B |= (1 << RXEN0);
63
  UCSR0B |= (1 << TXEN0);
64
  //asynchroner modus, kein parity bit, 1 stop bit, 8 datenbits
65
  UCSR0C |= (1 << UCSZ01);
66
  UCSR0C |= (1 << UCSZ00);
67
68
}
69
70
71
void sendenByte( unsigned char data )
72
{
73
  while( !(UCSR0A & (1 << UDRE0)))
74
  ;
75
76
  UDR0 = data;
77
}
78
79
80
void sendeMehrfach( unsigned char c )
81
{
82
  uint8_t i;
83
84
  for( i = 0; i < 8; ++i )
85
  sendenByte( c );
86
}
87
unsigned char empfangenByte( void )
88
{
89
  unsigned char data;
90
  //solange RXC noch nicht gesetzt Daten empfangen
91
  while (UCSR1A | (1 << RXC1))
92
  {
93
    //Daten empfangen
94
  }
95
  data = UDR1;
96
  return data;
97
}
98
void sendeString( char* text )
99
{
100
  while( *text )
101
  sendenByte( *text++ );
102
}


jetzt war ich nur so blöd und hab nicht ganz verstanden, was ich mit der 
sendeString Funktion anstellen soll...so wie ich das sehe, wird da reset 
übergeben...und solange ( *text ) soll diese Übergabevariable gesendet 
werden? Weiß nicht ob ich das o richtig verstanden habe, aber danke für 
deine Hilfe

Wenn ich den Code nun compilieren will, bekomme ich den Error 
stray'\246' in programm bei der Funktion sehndeMehrfach. Als ich nach 
dieser Fehlermeldung gegoolet habe, hieß es, dass keine boolean-Werte in 
Char gespeichert werden dürfen. Aber wo mache ich das?

Vielen Dank noch mal für eure Hilfe und Gedult

von Lisa K. (Gast)


Lesenswert?

oh...das sei(); soll raus, das hab ich verstehentlich falsch kopiert

von gfhf (Gast)


Lesenswert?

senden geht nicht weil du im ISR senden willst .. so deine INIT 
jedenfalls
versuch mal so ..
1
#define UBRR   ( (F_CPU/(16*9600UL))-1)
2
3
void USART_Init( void )
4
{
5
  UBRR0H = (uint8_t)(UBRR>>8);
6
  UBRR0L = (uint8_t) UBRR;
7
8
  UCSR0B = (1 << RXCIE0)|(1 << RXEN0)|(1 << TXEN0);
9
10
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
11
}

von gfhf (Gast)


Lesenswert?

Lisa K. schrieb:
> UBRR0L=0x33;
>   //Interrupts enable
>   UCSR0B |= (1 << RXCIE0);
>   UCSR0B |= (1 << TXCIE0);
>   UCSR0B |= (1 << UDRIE0);
>   //Receiver und Transmitter enable

ist ja immernoch drin ?...

von Lisa K. (Gast)


Lesenswert?

nun nochmals der Code ohne Interrupts mit Initialisierung von gfhf:
1
//Header einbinden
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
6
//Definitionen
7
#define RXB8 1
8
#define TXB8 0
9
#define UPE 2
10
#define OVR 3
11
#define FE 4
12
#define UDRE 5
13
#define RXC 7
14
15
#define FRAMING_ERROR (1<<FE)
16
#define PARITY_ERROR (1<<UPE)
17
#define DATA_OVERRUN (1<<OVR)
18
#define DATA_REGISTER_EMPTY (1<<UDRE)
19
#define RX_COMPLETE (1<<RXC)
20
21
#define UBRR   ( (F_CPU/(16*9600UL))-1)
22
23
24
//Prototypen der Funktionen
25
void USART_Init( void );
26
void sendenByte( unsigned char data );
27
void sendeMehrfach( unsigned char c );
28
unsigned char empfangenByte( void );
29
void sendeString( char* text );
30
31
32
int main(void)
33
{
34
  USART_Init();
35
  
36
  sendeString( "Reset\n" );
37
38
  
39
    while(1)
40
    {
41
    //Daten senden
42
    sendenByte(0xAA);
43
  
44
    }
45
}
46
47
48
void USART_Init( void )
49
{
50
  UBRR0H = (uint8_t)(UBRR>>8);
51
  UBRR0L = (uint8_t) UBRR;
52
53
  UCSR0B = (1 << RXCIE0)|(1 << RXEN0)|(1 << TXEN0);
54
55
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
56
}
57
58
void sendenByte( unsigned char data )
59
{
60
  while( !(UCSR0A & (1 << UDRE0)))
61
  ;
62
63
  UDR0 = data;
64
}
65
66
void sendeMehrfach( unsigned char c )
67
{
68
  uint8_t i;
69
70
  for( i = 0; i < 8; ++i )
71
  sendenByte( c );
72
}
73
unsigned char empfangenByte( void )
74
{
75
  unsigned char data;
76
  //solange RXC noch nicht gesetzt Daten empfangen
77
  while (UCSR1A | (1 << RXC1))
78
  {
79
    //Daten empfangen
80
  }
81
  data = UDR1;
82
  return data;
83
}
84
void sendeString( char* text )
85
{
86
  while( *text )
87
  sendenByte( *text++ );
88
}


Fehlermeldungen oder Warnings erhalte ich jetzt nicht mehr =)
Dankeschön dafür, leider kann ich immer noch nicht senden

von Uwe (de0508)


Lesenswert?

Hallo,

ich will dich noch auf diesen Fehler hinweisen:

UCSR0A != UCSR1A

==> es gibt zwei usart im µC !

Also musst du auch die richtigen Pins beschalten !!!!

von Lisa K. (Gast)


Lesenswert?

Uwe S. schrieb:
> UCSR0A != UCSR1A

oh...vielen Dank =)
habs geändert

von gfhf (Gast)


Lesenswert?

er meint das da ...

Lisa K. schrieb:
> unsigned char empfangenByte( void )
> {
>   unsigned char data;
>   //solange RXC noch nicht gesetzt Daten empfangen
>   while (UCSR1A | (1 << RXC1))
>   {
>     //Daten empfangen
>   }
>   data = UDR1;
>   return data;
> }

du willst auf UART1 empfangen und auf UART0 senden ...
bitte entscheide dich ^^

von Lisa K. (Gast)


Lesenswert?

das mit UART1 war versehentlich noch drin...aber inzwischen geht ja 
leider nicht mal mehr das senden...empfangen wurde in diesem Code ja gar 
nicht aufgerufen...

Hier trotzdem noch mal in verbesserter Form:
1
//Header einbinden
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
6
//Definitionen
7
#define RXB8 1
8
#define TXB8 0
9
#define UPE 2
10
#define OVR 3
11
#define FE 4
12
#define UDRE 5
13
#define RXC 7
14
15
#define FRAMING_ERROR (1<<FE)
16
#define PARITY_ERROR (1<<UPE)
17
#define DATA_OVERRUN (1<<OVR)
18
#define DATA_REGISTER_EMPTY (1<<UDRE)
19
#define RX_COMPLETE (1<<RXC)
20
21
#define UBRR   ( (F_CPU/(16*9600UL))-1)
22
23
24
//Prototypen der Funktionen
25
void USART_Init( void );
26
void sendenByte( unsigned char data );
27
void sendeMehrfach( unsigned char c );
28
unsigned char empfangenByte( void );
29
void sendeString( char* text );
30
31
32
33
int main(void)
34
{
35
  USART_Init();
36
  sendeString( "Reset\n" );
37
  
38
    while(1)
39
    {
40
    //Daten senden
41
    sendenByte(0xAA);
42
    }
43
}
44
45
46
void USART_Init( void )
47
{
48
  UBRR0H = (uint8_t)(UBRR>>8);
49
  UBRR0L = (uint8_t) UBRR;
50
51
  UCSR0B = (1 << RXCIE0)|(1 << RXEN0)|(1 << TXEN0);
52
53
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
54
}
55
56
57
void sendenByte( unsigned char data )
58
{
59
  while( !(UCSR0A & (1 << UDRE0)))
60
  ;
61
62
  UDR0 = data;
63
}
64
65
66
void sendeMehrfach( unsigned char c )
67
{
68
  uint8_t i;
69
70
  for( i = 0; i < 8; ++i )
71
  sendenByte( c );
72
}
73
unsigned char empfangenByte( void )
74
{
75
  unsigned char data;
76
  //solange RXC noch nicht gesetzt Daten empfangen
77
  while (UCSR0A | (1 << RXC0))
78
  {
79
    //Daten empfangen
80
  }
81
  data = UDR0;
82
  return data;
83
}
84
void sendeString( char* text )
85
{
86
  while( *text )
87
  sendenByte( *text++ );
88
}

von Uwe (de0508)


Lesenswert?

Hallo,

hast Du dir mal die MÜHE gemacht und das Datenblatt "gegen" deinen Code 
abgeglichen, um zu verstehen was da eigentlich passiert ?

Nicht einfach probieren, sondern alles 1 zu 1 im Datenblatt nachlesen, 
verstehen und auf deiner Checkliste abhaken !

Also was und wie bewirkt das Bit RXCIE0 in UCSR0B, wenn es 1 ist ?

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.