UART merkwürdiges Verhalten

OP #3220095
Lesenswert?

Guten tag liebe com,

ich versuche gerade via UART 3 Led's zu steuern, was aber nur teilweise 
klappt, denn diese verhalten sich der komisch.

Hier mein Code:
1
#define F_CPU 3686400UL
2
#define BAUD 9600UL
3

4
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
5
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
6
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
7

8
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
9
#error Baud_error
10
#endif
11

12
#include <avr/io.h>
13

14
void uart_init()
15
{
16
  UBRRH = UBRR_VAL >> 8;
17
  UBRRL = UBRR_VAL & 0xFF;
18
  
19
  UCSRB |= (1<<TXEN) | (1<<RXEN);
20
  UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
21
}
22

23
int main(void)
24
{
25
  DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2);
26
  
27
  uart_init();
28
  uint8_t i;
29
  
30
    while(1)
31
    {
32
    i = uart_getdata();
33
    uart_data(i);
34
    if(i == '1')
35
    {
36
      PORTB |= (1<<PB0);
37
      PORTB &= ~(1<<PB1) | (1<<PB2);
38
      
39
    }
40
    else if(i == '2')
41
    {
42
      PORTB |= (1<<PB1);
43
      PORTB &= ~(1<<PB0) | (1<<PB2);
44
    }
45
    else if(i == '3')
46
    {
47
      PORTB |= (1<<PB2);
48
      PORTB &= ~(1<<PB1) | (1<<PB0);
49
    }
50
    else if(i == '0')
51
    {
52
      PORTB |= (1<<PB1) | (1<<PB0) | (1<<PB2);
53
    }
54
    else{
55
      PORTB &= ~(1<<PB1) | (1<<PB0) | (1<<PB2);
56
    }
57
  
58
    }
59
}
60

61
uint8_t uart_getdata()
62
{
63
  while(!(UCSRA &(1<<RXC)))
64
  {
65
    
66
  }
67
  return UDR;
68
}

Wenn ich über ein Terminal die Zahl 1 sende, leuchtet die erste Led.
Danach schreibe ich die Zahl 2, aber diese leuchtet nur sehr kurz auf.
Bei der Zahl 3 leuchtet wieder die dritte Led. Doch wenn ich dann wieder 
die Zahl 1 sende, leuchtet die erste und die dritte ? Normal sollte 
diese ja durch das löschen des Bits ausgehen.

Mache ich irgendwas Falsch ? Denn ich weiß absolut nicht wo der Fehler 
ist, bzw. bin mir sicher das dort kein Fehler ist. Denn wenn ich den 
empfangenen Wert zurückschicke kommt exakt die Zahl, die ich eingegeben 
habe.


lg, marcel
Gast #3220106
Lesenswert?

Probiermal mit zusätzlichen klammern :

PORTB &= ~((1<<PB1)|(1<<PB2));

für alles was hinter der Tilde ist....


Ich denke mit "uart_data(i);" sendet du das empfangene Zeichen wieder 
zurück oder? setze das mal hinter die if-Bedingung und probiere es 
nochmal!


Sonst würde ich auch nur auf die Baudrate tippen aber wie das klingt 
funktioniert bei dir die Kommunikation .... aber ich berechne die 
anders:

#define F_CPU 3686400UL
#define BAUD 9600UL

uint16_t baudvalue=(((F_CPU/16)/BAUD)-1);
UBRR0H=(baudvalue>>8);
UBRR0L=baudvalue;
OP #3220209
Lesenswert?

Okay ein Fehler beim Uart habe gerade ausgeschlossen, denn wenn ich das 
ganze so aufbaue:
1
1 senden: LED1 an
2
2 senden: LED1 aus
3

4
3 senden: LED2 an
5
usw...

Funktioniert alles genauso wie es sollte, bloß wenn ich jetzt z.B.: die 
Zahl 2 sende, um alle LED's auszumachen, geht wieder nur eine aus. Das 
heißt irgendwas klappt da mit dem löschen des Bits nicht, oder ?
#3220212
Lesenswert?

Marcel Hoffmann schrieb:
> g457 schrieb:
>>> PORTB &= ~(1<<PB1) | (1<<PB2);
>>             ^                  ^
>>             Gute Stellen für zusätzliche Klammern
>>            ^
>>            Bitweises Nicht
>>
>> ..und bei allenen anderen releventen Stellen ebenso.
>
> Nein dort fehlen eigentlich kleine Klammern,

Doch, die fehlen dort. Darüber brauchen wir nicht diskutieren. Rechne es 
halt mal binär nach!
Und bei allen anderen Verundungen fehlen sie ebenso. Hast du sie ÜBERALL 
nachgetragen oder nur an der einen Stelle?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren