Anfängerfrage: Verhindern eine Funktion zu kopieren in C

OP #2385957
Lesenswert?

Hallo!

Ich steh ein wenig auf dem Schlauch. Ich habe eine Funktion gebastelt 
die eine LED auf und abblendet. Die Geschwindigkeit des auf und 
abblendens ist jedesmal zufällig.

Nun möchte ich mehrere LEDs ansteuern und könnte dies durch 
kopieren,umbenennen und ändern des Ports in der Funktion erreichen. Das 
scheint mir nicht elegant zu sein.
Andererseits bereitet es mir Kopfzerbrechen das einiges an Parametern 
pro Aufruf der Funktion geändert wird.

Wie macht man sowas richtig?
Angehängte Dateien:
Gast #2386092
Lesenswert?

sowas in der art ?
1
#define PWM_MAX 34
2
#define PWM_CHANNEL 8
3
#define PWM_DIR  (led_val[i]&128)
4
#define PWM_VAL  (led_val[i]&127)
5

6
char led_val[PWM_CHANNEL];
7
char led_dly[PWM_CHANNEL]
8

9
char blink0 (void)
10
{
11
  char i;      // temp general purpose variable
12
  static char pwm;
13
  int var;
14
  
15
  for(i=PWM_CHANNEL;i--;) {
16
    if(!led_dly[i]--)            //Bei Ablauf:
17
    {
18
    if (PWM_VAL==PWM_MAX)              //Zählrichtung bestimmen
19
      led_val[i]=PWM_MAX;
20
    else if (PWM_VAL==0)
21
      led_val[i]=128;
22
      
23
      PWM_DIR?led_dly[i]++:led_dly[i]--;        //Abhängig von der Richtung zählen
24
    led_dly[i]=rand()%200+1;        //Neue zufällige Länge für die Warteschleife
25
    }        
26
  }  
27
  
28
    if (pwm==44)          //Hier wird PWM generiert
29
    pwm=0;
30
    
31
    pwm=pwm+1;  
32

33
    var=0;
34
    for(i=PWM_CHANNEL;i--;) 
35
      if(pwm>PWM_VAL)  var|=1<<i;
36

37
  return var;
38
}
Gast #2386146
Lesenswert?

Das ist so falsch.
Deine Funktion generiert ein Bitpattern welches für ein PWM gebraucht 
werden kann, pwm wird damit selbst nicht generiert.
Der Forschlag ist im Prinzip dein Code, welcher einfach auf 8 leds 
erweitert wurde. Derzeit max 8 leds, wenn du das char blink0 in ein 
unsigned int blink0 änderst sind es dann max 16 leds. Wenn du mehr 
brauchst, auf long ändern sowie auch die Definition von var und du hast 
max 32 leds.
Weniger ist auch möglich, einfach die Konstante ändern.
Gast #2386189
Lesenswert?

Ich denke, es wäre einfacher einfach in HW auszutesten mit ein paar Leds
mehr am Port, dann versetehst du es sicher einfacher.

Ansonsten was ich nicht verstanden habe, wieso du bis 34 zählst und
den pwm bis 44, also ein fixed on-pwm von ca 22.7% immer an hast, aber
ich kenne auch nicht den zeitintervall von einem PWM zum anderen, 
vielleicht
entspricht eine Einheit auch ca 1/2 Stunde.
Sollte aber 44 nur ein Tippfehler sein, dann ändere bitte den Wert auf
PWM_MAX. So kannst du auch ev. später auf z.B. 100 ändern.
OP #2386208
Lesenswert?

Hallo Chris,

ich denke um deinen Code zu verstehen muss ich noch einige Kapitel in 
meinen C Büchern weiterarbeiten. Im Moment versuche ich nur 
nachzuvollziehen was Du im PWM Teil machst dabei stolpere ich im Moment 
über:

 #define PWM_VAL  (led_val[i]&127)

Mir scheint aber das Kapitel "Makros" das Richtige zu sein.

Ich habe das Ganze hier bereits mit 8 LEDs aufgebaut. Die hängen an 
einem 74HC595 (über SPI von einem ATmega8 gesteuert) und die erste LED 
macht was sie soll und , wie gesagt, wenn ich den ganzen Kram 8 mal 
kopieren würde, würden die anderen auch das tun was sie sollen. Aber das 
soll ja nicht Ziel der "Übung" sein ;-)

Die 44 sind kein Fehler. Wenn man noch mehr dimmt sieht man die 
einzelnen Helligkeitstufen und das ist nicht "schön" Wie man das löst 
ist sicherlich auch "Spass" für einige Nachmittage. Tipps nehme ich 
gerne an :-)
OP #2386241
Lesenswert?

Also ich rate jetzt mal ein wenig:

#define PWM_VAL  (led_val[i]&127)

Bedeutet das PWM_VAL "i" mal die Zeichenkette "led_val" denen wiederum 
jeweils der Wert "127" zugewiesen wird?

Und wie geht denn "i--" in einer for Schleife als Bedingung die dann 
auch noch keine Reinitialisierung enthält??? Was passiert denn da dann 
eigentlich?
Gast #2386246
Lesenswert?

Schreib rein was dir nicht klar ist und wieso, werde es dann erklären.

Ein define ist ein substitute, in der einfachsten Form ohne parameter
wie hier dient er hauptsächlich der Lesbarkeit des Quellcodes.

 #define PWM_VAL  (led_val[i]&127)

Ich habe die variable direction sowie x in eine einzige variable
zusammengesteckt, nähmlich led_val. Bit 7 ist direction und der Rest
ist x (von 0-127). Man hätte das auch mit Strukturen und Bitfeldern 
machen
können, bringt aber gewisse Probleme mit sich, welche man dann 
entsprechend
kontrollieren und beseitigen muss. Deshalb hatte ich hier einen 
einfacheren
Weg gewählt. Ist aber im Prinzip dasselbe wie
struct led_val_s {
  int val :7;
  int direction :1;
} led_val[8];

Dies nur am Rande.

PWM_VAL wird verwendet, um val, oder x in deinem Beispiel 
rauszubekommen,
wertebereich 0-127 . und PWM_DIR um die Direction rauszubekommen, 
wertebereich 128 oder 0 der einfachheit halber.

Eigentlich sollte es heissen, es werden die 7 bits ausmaskiert
 #define PWM_VAL  (led_val[i]&((1<<7)-1))
und
 #define PWM_DIR  (led_val[i]&(1<<7))

val&mask heisst hier value and mask, ein binäres and.
<< heisst shift left.

led_val[i] als Bit 0bDVVVVVVV , D=Dir V=val . Auf das reduziert sich 
das.
Gast #2386271
Lesenswert?

led_val ist ein Array aus PWM_CHANNEL Werten, also aus 8 in diesem
Beispiel

char led_var[PWM_CHANNEL]; // ist dasselbe als
char led_var[8];           // ein Array welches von led_var[0] bis 
led_var[7]
                           // zugegriffen wird, 8 variabeln insgesamt.

die variable i ist ein Zähler, welcher auch mit

char i ; // generic counter variable

initialisiert wird.

Das Makro oder die Define
 #define PWM_VAL  (led_val[i]&127)
wird im folgenden Code
 if (PWM_VAL==PWM_MAX)
durch
 if ((led_val[i]&127)==34)
ersetzt. Wenn du cpp bemühst, bekommst du das auch angezeigt.

Das For, PWM_CHANNEL ist dasselbe wie 8 und ein code wie dieser:
    for(i=PWM_CHANNEL;i--;) printf("i=%d\n",i);
->
    for(i=8;i--;) printf("i=%d\n",i);
=   produziert:
i=7
i=6
i=5
i=4
i=3
i=2
i=1
i=0

und wird insgesamt 8 mal durchlaufen.
Beim Vergleich i-- != 0 wird i nachher automatisch decrementiert.
Ansonsten könntest du auch schreiben,
    for(i=0;i<PWM_CHANNEL;i++)
gäbe denselben Effekt, nur die Richtung ist umgekehrt, von 0->max
Gast #2386347
Lesenswert?

Hier nochmal der Code mit deinem Fehler behoben (rauf+runter gezählt).
1
#define PWM_CHANNEL 8
2
#define PWM_MAX   35
3

4
char blink0 (void)
5
{
6
static char val[PWM_CHANNEL];
7
static char dly[PWM_CHANNEL];
8
static char rnd[PWM_CHANNEL];
9
static char pwm;
10

11
  char i;      // temp general purpose variable
12
  int var;
13
  
14
  for(i=PWM_CHANNEL;i--;) 
15
    if(!dly[i]--)            //Bei Ablauf:
16
    {
17
      if (val[i]==0)
18
        dly[i]=rnd[i]=rand()%200+1;
19
      else if (val[i]==PWM_MAX)              //Zählrichtung bestimmen
20
        dly[i]=rnd[i],rnd[i]=0;
21
  
22
      rnd[i]?val[i]++:val[i]--;        //Abhängig von der Richtung zählen
23
    }        
24

25
  
26
    if (pwm==44)          //Hier wird PWM generiert
27
    pwm=0;
28
    
29
    pwm=pwm+1;  
30

31
    var=0;
32
    for(i=PWM_CHANNEL;i--;) 
33
      if(pwm>PWM_VAL)  var|=1<<i;
34

35
  return var;
36
}

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