UART und schwach leuchtende LEDs

Gast #2667206
Lesenswert?

Hallo zusammen,

ich habe zur Übung ein eigentlich primitives Programm geschrieben.
Über die serielle Schnittstelle kann ich mit X und Y zwei Led's 
einschalten
und mit x und y wieder ausschalten.
Funktioniert soweit auch, nur leider leuchten die angeschlossenen LEDs 
nur ziemlich schwach, im Vergleich dazu, wie wenn man sie einfach über 
einen High Pegel ansteuern würde.
Die LEDs hängen wie UART an PORTD. Verwendet wird ein Atmega8, avr-gcc 
und das Pollin Evaluationsboard.

Könnte es sein, dass UART den PORTD so stark belastet, dass er die LEDs 
nicht mehr richtig treiben kann?

Gruß

1
#include <avr/io.h>
2
#define F_CPU 16000000L
3
#define BAUD 9600L
4
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)    
5

6

7
char empfangen(void)
8
{
9
  while (!(UCSRA & (1<<RXC)))   
10
  ;
11
  return UDR;                   
12
}
13

14
void init_uart(void)
15
{
16
  DDRD &= 0xE0; 
17
  UBRRH = UBRR_VAL >> 8;
18
  UBRRL = UBRR_VAL & 0xFF;
19
  UCSRB = (1<<TXEN) | (1<<RXEN);
20
}
21

22
int main(void)
23
{ 
24
  init_uart();
25
  
26
  while(1)
27
  {
28
    switch (empfangen())
29
    {
30
  case 'X':
31
    PORTD |= 0x40;
32
    break;
33
  case 'x':
34
    PORTD &= 0xBF;
35
    break;
36
  case 'Y':
37
    PORTD |= 0x20;
38
    break;
39
  case 'y':
40
    PORTD &= 0xDF;
41
    break;
42
    }
43
     
44
  }
45
  return 0;
46
}
#2667222
Lesenswert?

myraculix schrieb:

> Könnte es sein, dass UART den PORTD so stark belastet, dass er die LEDs
> nicht mehr richtig treiben kann?

Nö.

Aber es kann sein (*), dass du

  DDRD &= 0xE0;

die LED Pins auf Eingang konfiguriert hast und nur den Pullup zu und 
wieder wegschaltest.


(*) sollte eigentlich heißen: es ist so. Aber dann hätte es nicht so 
schön als Fortsetzung zu deinem Satz gepasst :-)
#2667238
Lesenswert?

myraculix schrieb:
> Die beiden LEDs hängen an D6 und D5 und die sind doch als Ausgang
> gesetzt, oder steht ich grad so aufm Schlauch?

Warum sollen die beiden Pins auf Ausgang stehen?
Von Haus aus sind alle Ports mit allen Pins auf Eingang gestellt. 
Sozusagen der Power-Up Default.

Wenn du einen Pin auf Ausgang stellen willst, musst du im DDR Register 
das entsprechende Bit auf 1 stellen.
#2667247
Lesenswert?

Und gewöhn dir diese Schreibweise mit den Hex-Zahlen wieder ab.


Das mindeste ist:
1
void init_uart(void)
2
{
3
  DDRD |= ( 1 << PD5 ) | ( 1 << PD6 );
4

5
  UBRRH = UBRR_VAL >> 8;
6
  UBRRL = UBRR_VAL & 0xFF;
7
  UCSRB = (1<<TXEN) | (1<<RXEN);
8
}
9

10
int main(void)
11
{ 
12
  init_uart();
13
  
14
  while(1)
15
  {
16
    switch (empfangen())
17
    {
18
  case 'X':
19
    PORTD |= ( 1 << PD5 );
20
    break;
21
  case 'x':
22
    PORTD &= ~( 1 << PD5 );
23
    break;
24
  case 'Y':
25
    PORTD |= ( 1 << PD6 );
26
    break;
27
  case 'y':
28
    PORTD &= ~( 1 << PD6 );
29
    break;
30
    }
31
  }
32
  return 0;
33
}


Noch besser wäre
1
#define LED1   PD5
2
#define LED2   PD6
3

4
void init_uart(void)
5
{
6
  DDRD |= ( 1 << LED1 ) | ( 1 << LED2 );
7

8
  UBRRH = UBRR_VAL >> 8;
9
  UBRRL = UBRR_VAL & 0xFF;
10
  UCSRB = (1<<TXEN) | (1<<RXEN);
11
}
12

13
int main(void)
14
{ 
15
  init_uart();
16
  
17
  while(1)
18
  {
19
    switch (empfangen())
20
    {
21
  case 'X':
22
    PORTD |= ( 1 << LED1 );
23
    break;
24
  case 'x':
25
    PORTD &= ~( 1 << LED1 );
26
    break;
27
  case 'Y':
28
    PORTD |= ( 1 << LED2 );
29
    break;
30
  case 'y':
31
    PORTD &= ~( 1 << LED2 );
32
    break;
33
    }
34
  }
35
  return 0;
36
}

man kann das dann noch besser schreiben aber fürs erste reicht das schon 
mal. Warum das besser ist, sollte wohl unmittelbar klar sein, wenn man 
sich den Code ansieht.

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