Forum: Mikrocontroller und Digitale Elektronik LED1 OK. aber LED2 blinkt nicht mit voller Helligkeit


von Joey N. (joey_n)


Lesenswert?

Hallo, bin Anfänger und habe das Problem, wenn ich zwei einfache LEDs 
blinken lasse, blinkt LED1 an PB0 sauber mit voller Hellichkeit, LED2 
blinkt auch an PB1 aber nicht mit voller Leuchtkraft.

Ports und LEDs sind OK.

Was kann ich tun bitte?
Würde mich über Tips sehr freuen, vielen Dank.

Hier der Code, Beispiel aus dem Netz, aber PB1 habe ich hinzugefügt,für 
ein Attiny13 der extern an 5 Volt geschaltet ist.
 */
1
#define F_CPU 1000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
int main(void)
7
{
8
  // Pin 1 von Port B (PB1) als Ausgang schalten  "DDRB |= (1 << PB1);"
9
  
10
  DDRB = (1 << PB0);
11
  
12
  // Endlosschleife
13
  
14
  for (;;) {    
15
    PORTB |= (1 << PB0);  // bit im Portregister auf 1 setzen => LED leuchtet
16
    _delay_ms(100);    // warten
17
18
    PORTB &= ~(1 << PB0); // bit im Portregister auf 0 setzen => LED aus
19
    _delay_ms(5000);    // warten
20
    
21
    PORTB |= (1 << PB1);  // bit im Portregister auf 1 setzen => LED leuchtet
22
    _delay_ms(500);    // warten
23
24
    PORTB &= ~(1 << PB1); // bit im Portregister auf 0 setzen => LED aus
25
    _delay_ms(500);    // warten
26
    
27
    }
28
29
}

: Bearbeitet durch User
von Dominik S. (dasd)


Lesenswert?

Mach aus

> DDRB = (1 << PB0);

mal

> DDRB = (1 << PB0) | (1 << PB1);

Da hätte man aber auch selbst drauf kommen können.

von user (Gast)


Lesenswert?

DDRB = (1 << PB0);
zu
DDRB = (1 << PB0)|(1 << PB1);

von Stefan F. (Gast)


Lesenswert?

Wen willst du veräppel?

Du musst nur den Befehl in diesem Kommentar ausführen.

 // Pin 1 von Port B (PB1) als Ausgang schalten  "DDRB |= (1 << PB1);"

von Joey N. (joey_n)


Lesenswert?

Super, vielen Dank
Bin/war blind.

Klasse....

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Divide et impera

Mache 2 Tasks daraus:
1
#define F_CPU 1.2e6
2
3
#include <util/delay.h>
4
#include "sbit.h"
5
6
#define LED0    PORT_B0
7
#define LED0_oe  DDR_B0
8
#define LED1    PORT_B1
9
#define LED1_oe  DDR_B1
10
11
void task_0( void )
12
{
13
  static uint16_t cnt_10ms;
14
  switch( ++cnt_10ms ){
15
    case 100:   LED0 = 0;
16
                break;
17
    case 300:   LED0 = 1;
18
                cnt_10ms = 0;
19
                break;
20
  }
21
}
22
23
void task_1( void )
24
{
25
  static uint16_t cnt_10ms;
26
  switch( ++cnt_10ms ){
27
    case 250:   LED1 = 0;
28
                break;
29
    case 350:   LED1 = 1;
30
                cnt_10ms = 0;
31
                break;
32
  }
33
}
34
35
int main()
36
{
37
  LED0_oe = 1;
38
  LED1_oe = 1;
39
  for(;;){
40
    _delay_ms( 10 );      // main timebase: 10ms
41
    task_0();
42
    task_1();
43
  }
44
}

von meckermann (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Mache 2 Tasks daraus:

Bleibe konsistent beim Setzen der Klammer-Ebenen.

z.B.:
1
int main()
2
{
3
  LED0_oe = 1;
4
  LED1_oe = 1;
5
  for(;;)
6
  {
7
    _delay_ms( 10 );      // main timebase: 10ms
8
    task_0();
9
    task_1();
10
  }
11
}

von HildeK (Gast)


Lesenswert?

meckermann schrieb:
> Bleibe konsistent beim Setzen der Klammer-Ebenen.

Peter Danneggers Variante scheint bei den meisten C-Programmierern 
üblich zu sein (so auch bei meinen SW-Kollegen), ich verwende aber auch 
deine Variante, weil sie mir übersichtlicher erscheint.
Also keine Konsistenzfrage und nichts zu meckern :-)!

von Joey N. (joey_n)


Lesenswert?

Wow, dankeschön Peter und sogar die sbit.h mitgesandt.
Das ist Profi

Bin gespannt und berichte gleich mal...

von Joey N. (joey_n)


Lesenswert?

Danke Hilde,
bin in C absolut Neu und gebe dir Recht
Allerdings finde ich Peters Code auch übersichtlich, wenn ich denn den 
Code in einigen Jahren evtl. mal verstehen werde.:)

von meckermann (Gast)


Lesenswert?

HildeK schrieb:
> Also keine Konsistenzfrage

Doch, sonst müsste ja man (ich hab den Code ja im Ganzen zitiert)
mit

int main() { ....

anfangen.

Der "Unsinn" die Klammer an einer anderen Ebene zu schliessen
gegenüber dem Punkt wo sie geöffnet wurde ist sogar in ATMEL
Code (ASF) weit verbreitet. Für mich ist das Chaos .....

von Walter (Gast)


Lesenswert?

HildeK schrieb:
> Also keine Konsistenzfrage
vermutlich wegen

int main()
{

und nicht
int main(){

aber ich verwende wegen Übersichtlichkeit wie Du die { in einer neuen 
Zeile

von meckermann (Gast)


Lesenswert?

meckermann schrieb:
> Für mich ist das Chaos .....

In einem kleinen Projekt bzw Source Code mag das noch
überschaubar sein, aber wenn es der Klammer-Ebenen zuviel
wird dann ist es echt Chaos.

von Joey N. (joey_n)


Lesenswert?

Danke für deine Gedanken
lg

von Georg G. (df2au)


Lesenswert?

meckermann schrieb:
> Klammer-Ebenen zuviel
> wird dann ist es echt Chaos.

Wenn man statt edlin einen vernünftigen Editor verwendet, bleiben beide 
Varianten und nach 4711 Schachtelebenen übersichtlich.

SCNR

P.S.: Ich bevorzuge auch Peter Variante.

von Peter D. (peda)


Lesenswert?

meckermann schrieb:
> Bleibe konsistent beim Setzen der Klammer-Ebenen.

Ich benutze den Klammerungsstil als Unterscheidungsmerkmal.
Nur eine Funktion hat die '{' in einer extra Zeile.
Dadurch kann ich leichter erkennen, wann eine neue Funktion beginnt und 
wann nur ein conditional Block darin.

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

Naja, solange man nur den eigenen Code verstehen muss, sind die 
verwendeten Varianten weitgehend egal. Ich kann hier im Forum gut mit 
beiden oder den gemischten Varianten leben.

Ich habe eher Probleme, den Teile von Peters Code in sbit.h zu 
verstehen:
1
struct bits {
2
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
3
} __attribute__((__packed__));
4
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
5
#define SBIT(x,y)       SBIT_(x,y)
speziell mit den Ausdrücken:
1
 __attribute__((__packed__))
2
3
oder 
4
5
((*(volatile struct bits*)&port).b##pin)
Wenn du mal Zeit hast, dann kannst du mir hier vielleicht auf die 
Sprünge helfen ...
Vielleicht lerne ich es noch :-)

von Peter D. (peda)


Lesenswert?

Joey N. schrieb:
> wenn ich denn den
> Code in einigen Jahren evtl. mal verstehen werde.:)

Warum so pessimistisch.
Frag ruhig, wenn Du etwas nicht verstehst.
Ich habe ihn absichtlich nicht kommentiert.
Ich hab auch nicht versucht den Zeitablauf aus Deinem Code zu 
extrahieren.
Ich denke aber, daß das Prinzip klar wird, wie man mehrere Tasks 
gleichzeitig und unabhängig voneinander ausführen kann.

von Joey N. (joey_n)


Lesenswert?

Hallo Peter, Entschuldigung, das war  keine Kritik an dich.
Ich wollte nur zum Ausdruck bringen, das ich Neu bin und gerne so 
programmieren könnte wie du.


Das war sowieso mein nächstes Ziel, wie ich die  LEDs unabhängig 
voneinander ansteuern kann.

Ich bedanke ich mich nochmals für den tollen Code und frohes Neues.


lg

von Karl H. (kbuchegg)


Lesenswert?

HildeK schrieb:

> #define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
> #define SBIT(x,y)       SBIT_(x,y)
> [/c]
> speziell mit den Ausdrücken:
>
1
>  __attribute__((__packed__))
2
>

der Zweck von 'packed' besteht darin, dass der COmpiler nicht auf blöde 
Ideen kommt, und zwischen die einzelnen Strukturmember in
1
struct bits {
2
    uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
3
} __attribute__((__packed__));
noch Alignment Bytes hineinpackt, weil er dir schnellstmöglichen zugriff 
auf die Member ermöglichen will. An dieser Stelle wollen wir den 
Compiler dazu zwingen, dass er alle 8 Bit Member in genau 1 Byte packt.

>
1
> ((*(volatile struct bits*)&port).b##pin)
2
>

https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

## 'hängt' einfach nur 2 Tokens zusammen und generiert daraus einen 
neuen Token.
Steht 'pin' für die Zahlenkonstante 5, dann generiert 'b##pin' daraus 
'b5'.

von HildeK (Gast)


Lesenswert?

@Karl Heinz (kbuchegg)
Herzlichen Dank für die Erklärung!
Ich habe bisher nur die einfachen Preprocessor Kommandos verwendet. Da 
scheint viel möglich zu sein, ich muss mich wohl damit mal intensiver 
beschäftigen ...

von Joey N. (joey_n)


Lesenswert?

Hilde hats auch echt drauf, danke

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.