Forum: Mikrocontroller und Digitale Elektronik UART merkwürdiges Verhalten


von Marcel H. (repac3r)


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

von g457 (Gast)


Lesenswert?

Mir dünkt Dir gehen ein paar Klammern ab zu den bitweisen Nichten.

von Marcel H. (repac3r)


Lesenswert?

g457 schrieb:
> Mir dünkt Dir gehen ein paar Klammern ab zu den bitweisen Nichten.

Bin ich nur zu doof zum lesen, oder
versteht man wirklich nicht was du mir damit sagen möchtest ?
Wäre nett wenn du das nochmal schreiben würdest ;)

Lg, marcel

von g457 (Gast)


Lesenswert?

> PORTB &= ~(1<<PB1) | (1<<PB2);
            ^                  ^
            Gute Stellen für zusätzliche Klammern
           ^
           Bitweises Nicht

..und bei allenen anderen releventen Stellen ebenso.

von Martin (Gast)


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;

von Mike (Gast)


Lesenswert?

Marcel Hoffmann schrieb:
> Bin ich nur zu doof zum lesen, oder
> versteht man wirklich nicht was du mir damit sagen möchtest ?
Das blöde an Computern ist, dass sie machen, was man ihnen sagt und 
nicht unbedingt das, was man von ihnen möchte.

von Marcel H. (repac3r)


Lesenswert?

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, habe sie trotzdem 
hinzugefügt, aber leiger gleiches Resultat

von Marcel H. (repac3r)


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 ?

von Karl H. (kbuchegg)


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?

von Michael .. (bigneal)


Lesenswert?

Marcel Hoffmann schrieb:
> g457 schrieb:
>>> PORTB &= ~(1<<PB1) | (1<<PB2);
>
> Nein dort fehlen eigentlich kleine Klammern

http://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t

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.