Hallo zusammen
In meinem Code mit 'switch' Anweisung habe ich Tabellen bestehend aus 16
channels mit je ein zugewiesener Wert. Um das Ganze zu vereinfachen
möchte ich die Tabellen durch ein zweidimensionales Array ersetzen.
Ich könnte mir sowas vorstellen:
Verstehe ich das richtig, Du hast einen 8-Bit-Eingang (Port C), und in
Abhängigkeit vom anliegenden Wert möchtest Du eine Funktion mit zwei
anderen Werten aufrufen?
Dafür braucht es kein zweidimensionales Array, und auch kein
switch-Statement, sondern zwei eindimensionale Arrays mit je 256
Elementen.
Und dann wird das ganze recht einfach:
1
uint8_tchannels[256]={...};
2
uint8_tvalues[256]={...};
3
4
// etc. pp.
5
6
while(1)
7
{
8
input=PINC;
9
10
pwm_settings(channels[input],values[input]);
11
}
Du musst nur noch auseinanderklabüsern, welcher Bit-Kombination an Port
C welche Werte für "Kanal" und "Wert" zuzuordnen sind.
Oder habe ich Dich komplett missverstanden?
In Abhängigkeit vom Port C Eingang möchte ich diverse LEDs mit
unterschiedlicher Helligkeit schalten. Unter 'channel' sind die Port B
und Port D Ausgänge gemeint, unter 'value' die vordefinierten
Helligkeitswerte.
Im Anhang ist der komplete und funktionierende Code den ich anpassen
möchte.
MfG
Firebird
Wenn sich die Werte nicht ändern, sollte die Tabelle const sein
und vermutlich auch global (außerhalb aller Funktionen) oder
zumindest static.
Ggf. explizit im Flash.
Danke für die Vorschläge. Leider habe ich (als Anfänger) immernoch
Verständnisprobleme und komme nicht weiter.
Der erste Case-Fall ist unten abgebildet. 'channel' ist für die Zuordung
der PINs und 'value' den Wert für die Helligkeitsberechnung der LEDs. Im
Prinzip eine einfache Tabelle mit PIN-Zuweisung und Wert.
1
case0xc1:// Wenn PORTC = 11000001
2
pwm_setting(0,0);// (channel,value) d.h. PB0 mit Wert 0
3
pwm_setting(1,5);// (channel,value) d.h. PB1 mit Wert 5
4
pwm_setting(2,5);// (channel,value) d.h. PB2 mit Wert 5
5
pwm_setting(3,5);// (channel,value) d.h. PB3 mit Wert 5
6
pwm_setting(4,0);// (channel,value) d.h. PB4 mit Wert 0
7
pwm_setting(5,0);// (channel,value) d.h. PB5 mit Wert 0
8
pwm_setting(7,0);// (channel,value) d.h. PB6 mit Wert 0
9
pwm_setting(8,0);// (channel,value) d.h. PB6 mit Wert 0
10
pwm_setting(9,0);// (channel,value) d.h. PB6 mit Wert 0
11
pwm_setting(10,0);// (channel,value) d.h. PB6 mit Wert 0
12
pwm_setting(11,0);// (channel,value) d.h. PB6 mit Wert 0
13
pwm_setting(12,0);// (channel,value) d.h. PB6 mit Wert 0
14
pwm_setting(13,5);// (channel,value) d.h. PB6 mit Wert 5
15
pwm_setting(14,0);// (channel,value) d.h. PB6 mit Wert 0
16
pwm_setting(15,0);// (channel,value) d.h. PB6 mit Wert 0
17
break;
Weil es später ein Vielfaches an Case-Fälle geben soll suche ich eine
kürzere Schreibform oder wenn möglich eine intelligentere Lösung.
Im Tutorial unter http://www.mikrocontroller.net/articles/Soft-PWM ist
z.B.
1
constuint8_tt1[8]={27,40,3,17,150,99,5,9};
2
memcpy(pwm_setting,t1,8);
Ich weiss nicht wie ich sowas ähnliches in meinem Code anwenden, bzw.
umsetzen kann.
MfG
Firebird
> Weil es später ein Vielfaches an Case-Fälle geben soll suche> ich eine kürzere Schreibform oder wenn möglich eine> intelligentere Lösung.
Wieviele Cases hast du und wie zeitkritisch ist das Ganze?
Intelligenter wär zb sowas:
1
#define NR_CASES 5
2
#define NR_VALUES 16
3
4
structLed
5
{
6
unsignedcharInputValue;// welcher Wert muss am PINC vorliegen ...
7
unsignedcharValues[NR_VALUES];// ... damit diese Werte auf die Led ausgegeben werden
input=PINC;// Schalterkombination an "input" übergeben
22
23
// den richtigen caseNr suchen
24
// wird keiner gefunden, dann ist NR_CASES - 1 (also der letzte) der Default
25
caseNr=NR_CASES-1;
26
for(i=0;i<NR_CASES-1;++i)
27
{
28
if(Cases[i].InputValue==input)
29
{
30
caseNr=i;
31
break;
32
}
33
}
34
35
// die Werte für diesen Fall ausgeben
36
for(i=0;i<NR_VALUES;++i)
37
pwm_setting(i,Cases[caseNr].Values[i]);
38
}
Hier muss man den Programmtext überhaupt nicht mehr ändern, wenn ein
neuer Fall dazukommt. Die neuen Einstellungen werden zusammen mit dem
auslösenden Wert am PINC einfach in die Tabelle eingetragen und der
Programmcode sucht und findet die Led-Einstellungen wenn am PINC der
richtige Wert vorliegt.
Danke, sowas suchte ich. Nach einer kleinen Anpassung sieht der
Code-Ausschnitt so aus:
1
unsignedcharValues[NR_CASES][PWM_CHANNELS]=
2
{{0,5,5,5,0,0,0,0,0,0,0,0,0,5,0,0},
3
{0,PWM_MAX,5,PWM_MAX,0,0,0,0,0,0,0,0,0,5,0,0},
4
{0,5,5,5,0,0,0,0,0,0,5,0,0,0,5,0},
5
{0,PWM_MAX,5,PWM_MAX,0,0,0,0,0,0,5,0,0,0,5,0},
6
{0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,5},
7
};
8
9
sei();// Interruptfreigabe
10
11
while(1)
12
13
input=~PINC;// Schalterkombination an "input" übergeben
14
15
switch(input)
16
{
17
case0xc1:
18
for(i=0;i<PWM_CHANNELS;i++)
19
pwm_setting(i,Values[0][i]);
20
break;
21
22
case0xd1:
23
for(i=0;i<PWM_CHANNELS;++i)
24
pwm_setting(i,Values[1][i]);
25
break;
26
27
case0xc5:
28
for(i=0;i<PWM_CHANNELS;++i)
29
pwm_setting(i,Values[2][i]);
30
break;
31
32
case0xd5:
33
for(i=0;i<PWM_CHANNELS;++i)
34
pwm_setting(i,Values[3][i]);
35
break;
36
37
default:
38
for(i=0;i<PWM_CHANNELS;++i)
39
pwm_setting(i,Values[4][i]);
40
}
41
}
Irgendwo habe ich etwas übersehen, die LEDs leuchten alle hell auf
unabhängig vom Zustand an PORTC. Ich vermute dass die 'Values' nicht
übergeben werden.
MfG
Firebird
Der zweite Vorschlag scheint mir besser zu passen für meinen
Anwendungsfall. Aber, auch hier leuchten die LEDs einfach hell. Wie kann
man die Werte von
1
pwm_setting(i,Cases[caseNr].Values[i]);
an die Definition
1
// Makro zur einfacheren Handhabung
2
#define pwm_setting(channel, value) pwm_value[channel] = PWM_MAX - value
übergeben, bzw. anpassen?
Voraussichtlich sollen 24 Case-Fälle geschaltet werden. Zeitkritisch ist
das Ganze nicht.
Danke und Gruss
Firebird
Firebird schrieb:
> Der zweite Vorschlag scheint mir besser zu passen für meinen> Anwendungsfall. Aber, auch hier leuchten die LEDs einfach hell. Wie kann> man die Werte von>
Jetzt bekomme ich eine Fehlermeldung:
main.c:116: warning: implicit declaration of function 'pwm_setting'
Kannst Du mir bitte einen Hinweis geben was ich übersehen habe.
Danke und Gruss
Firebird
Firebird schrieb:
> @ Frank>> Karl heinz Buchegger schrieb:>>>Vergiss das Makro. Du brauchst es nicht.>>Schreib>>>
1
>pwm_value[i]=PWM_MAX-Cases[caseNr].Values[i];
>>>>ist genausogut wie dein Makro und man sieht wenigstens was wirklich>>passiert.>> Es ist bestimmt eine Kleinigkeit das ich übersehe.>
Nein. Keine Kleinigkeit.
Du sollst dort, wo du das Makro verwendest, anstelle des Makros den
Inhalt des Makros einsetzen.
Anstatt
1
for(i=0;i<NR_VALUES;++i)
2
pwm_setting(i,Cases[caseNr].Values[i]);
das hier
1
for(i=0;i<NR_VALUES;++i)
2
pwm_value[i]=PWM_MAX-Cases[caseNr].Values[i];
Denn genau das macht der Präprozessor aus deinem Makro.
Ich dachte eigentlich, dass das sonnenklar sei. Aber man lernt nie aus.
So.
Und jetzt rückst du mal dein Programm richtig ein und achtest auch
darauf wo du { } hast, und wo nicht.
Im speziellen würde mich interessieren, wie du dir vorstellst, dass
1
while(1)
2
3
input=~PINC;// Schalterkombination an "input" ?ben
jemals den Teil nach dem input = ~PINC ausführen soll, wenn du keine { }
um den Block hast.
Das Fehlen der {} habe ich übersehen und der Hinweis mit dem Makro hatte
ich falsch verstanden.
Jetzt funktioniert alles wie gewünscht.
Danke an allen fürs Mitwirken und Helfen.
MfG
Firebird
Firebird schrieb:
> Das Fehlen der {} habe ich übersehen.
Genau darum gehts.
Wenn du dein Programm sauber einrückst, dann kannst du das nicht
übersehen. Eine optisch saubere Programmstruktur ist nicht nur reiner
Selbstzweck sondern auch ein Fehlerverhütungs bzw.
Fehlersuchmechanismus.