Forum: Mikrocontroller und Digitale Elektronik Zustandsvariablenblöcke als serielle Bits an Schieberegister ausgeben?


von Uli A. (schnuppi44)


Lesenswert?

Hallo zusammen,

ich bin aktuell zwar noch mit vielen strukturellen Vorarbeiten zu einem 
Projekt (STM32 µC) beschäftigt und muss noch viel lernen. Dennoch habe 
ich mich schon gefragt, wie man wohl in C folgendes Problem löst:

Ich möchte viele einzelne LEDs mit Tastern schalten. Aufgrund der 
schieren Menge der Elemente (ca 60) soll sowohl die Eingabe der Taster 
als auch die Ausgabe an die LEDs über Schieberegister erfolgen, außerdem 
soll die aktuelle "Zustandsmatrix" mit den ON/OFF-Einträgen auf einem 
FRAM gespeichert werden.

Also, das Grundprinzip ist, denke ich klar:
Es entstehen durch die Tastereingaben Variablenwerte für ON 1-60. Diese 
sollen dann sowohl im FRAM als gesetzte Bits abgelegt (und als "Presets" 
ggfs. wieder abgerufen) werden und natürlich an die LEDs (der Taster) 
als Zustandsrückmeldung ausgegeben werden.

Wie kann ich mir das denn nun als sinnvolle Programmieridee in C 
vorstellen ?
Oder ganz konkret. Wie kann ich aus den ON/OFF Variablen in einem Rutsch 
den aktualisierten Gesamtzustand seriell ausgeben für die 
Schieberegister ?

Beispiel im kleinen mit nur vier Tastern/LEDs:

Ich habe den Anfangszustand OFF  OFF  OFF / OFF.

Nun drücke ich Taster 2, der den Zustand von #2 entsprechend verarbeiten 
soll bzw. ihn in das Gesamtbild OFF  ON  OFF / OFF übersetzt und das 
Ganze dann seriell über das Schieberegister ausgibt....wie mache ich das 
elegant ?

Und wieder auf das große Modell (hier mit 48 "Kanälen") übertragen, 
heißt das ja z.B.

Status
00101001 11100010 01000100 01001110 10000011 00010100

soll nach Betätigung von Taster 13 folgendes Ausgabepattern ergeben:

00101001 11101010 01000100 01001110 10000011 00010100

Also wie kann ich dieses eine Bit mittendrin als Ausgangsbild 
aktualisieren, wenn ich die Taster bzw. die Zustandswerte mit einem 
Array von boole'schen Variablen abfrage....?

Oder sollte ich das dann ganz anders machen ?

Freue mich über Anregungen !

PS: Ach ja, das gilt natürlich auch für die Eingangsseite mit den 
PISO-Schieberegistern....

: Bearbeitet durch Moderator
von Planloser (Gast)


Lesenswert?

Du kopierst ganz simpel die einzelnen Bytes (oder Worte je nach 
Schieberegister) der Reihe nach per SPI in das Schieberegister. Es ist 
egal, ob das ein Register oder 100 hintereinander sind.

von Gerd E. (robberknight)


Lesenswert?

Uli A. schrieb:
> Ich möchte viele einzelne LEDs mit Tastern schalten. Aufgrund der
> schieren Menge der Elemente (ca 60) soll sowohl die Eingabe der Taster
> als auch die Ausgabe an die LEDs über Schieberegister erfolgen,

Nur mal so in den Raum geworfen: Hast Du überlegt für Taster und LEDs 
eine Matrix zu verwenden?

Also gerade für Taster bietet sich das an weil Du dadurch mit viel 
weniger IO-Pins auskommst. Bei STM32ern kann man die Abfrage einer 
Matrix im Hintergrund per DMA laufen lassen, das braucht dann nur sehr 
wenig CPU.

Bei LEDs hängt es davon ab ob die LEDs nur zur Signalisierung gebraucht 
werden, dann reicht vermutlich ne Matrix, oder zur Beleuchtung.

Es gibt ICs, die LED- und Tastaturmatrix in einem Baustein kombinieren 
und dann z.B. per I2C oder SPI angesteuert werden können.

von Uli A. (schnuppi44)


Lesenswert?

Okay. Anscheinend war das noch nicht klar ausgedrückt.
Das eigentliche Rausschieben bzw. "Reinziehen" der Bits / Bytes ist mir 
grundsätzlich klar. Aber es geht vielmehr um das Verarbeiten innerhalb 
des Programms. Vielleicht sollte ich noch erklären, dass es für jeweils 
3 der Taster am Ende eine programmierte "Auslösefunktion" geben 
soll....das heißt von den Dreierpacks kann immer nur einer ON sein, und 
das Drücken eines der Anderen löst denjenigen dann ab. Und wenn der 
Gleiche Taster nochmal gedrückt wird, geht der Kanal wieder aus
Also:

Gegeben ist der Zustand:

OFF  OFF  ON

Taster 1 wird gedrückt ergibt:

ON  OFF  OFF

Taster 3 drücken ergibt:

OFF  OFF  ON

Taster 3 drücken ergibt

OFF  OFF  OFF

etc.

Um das dann zu verarbeiten, muss ich ja zwischen Einlesen der Zustände 
über das PISO und Ausgeben über das SIPO irgendein System verwenden, um 
auf die einzelnen Bits zuzugreifen und die in dieser XOR-Logik zu 
verarbeiten.

Also quasi eine Art Byte - zu - Variablen - Konverter....;-)

Und umgekehrt....

von A. S. (Gast)


Lesenswert?

Uli A. schrieb:
> Also quasi eine Art Byte - zu - Variablen - Konverter....;-)

Nein.

Mach dir Routinen, wie du ein Bit in einer Struktur von X Bytes
Setzen
Löschen
Abfragen
Toggeln kannst.

Also set, res, tst, tog

jeweils mit einem int idx und welche Struktur (LEDs, Taster, ...)

Und dann schreibe die Bytes der Struktur ins fram und in die 
Schieberegister. Bzw lese daraus

Für die Tastenabfrage noch eine entprellung und eine Flankendetektion 
(am einfachsten Peters Code auf ganze structs erweitern)

von Uli A. (schnuppi44)


Lesenswert?

Gerd E. schrieb:
> Es gibt ICs, die LED- und Tastaturmatrix in einem Baustein kombinieren
> und dann z.B. per I2C oder SPI angesteuert werden können.

Hättest Du da ein Beispielexemplar ? Kenne ich so noch nicht...dachte 
eigentlich, dass man solche Matritzen auch über Schieberegister 
ansteuert...

von Uli A. (schnuppi44)


Lesenswert?

A. S. schrieb:
> Mach dir Routinen, wie du ein Bit in einer Struktur von X Bytes
> Setzen
> Löschen
> Abfragen
> Toggeln kannst.

> Also set, res, tst, tog

Hui. Das ist mir leider noch unbekannt - Könntest Du mir dafür ein 
einfaches Beispiel liefern....?

von A. S. (Gast)


Lesenswert?

1
#define MAX_IDX 60
2
#define N_BYTES ((MAX_IDX+7)/8)
3
typedef unsigned char BYTE;
4
struct sB
5
{
6
   BYTE a[N_BYTES];
7
};
8
9
void Set(struct sB *pB, unsigned int i)
10
{
11
   if(i < MAX_IDX) {pB->a[i/8]|=1<<(i%8)}
12
}
13
14
void Res(struct sB * pB, unsigned int i)
15
{
16
   if(i < MAX_IDX) {pB->a[i/8]&=~(1<<(i%8))}
17
}
18
19
int Tst(struct sB *pB, unsigned int i)
20
{
21
   if(i < MAX_IDX && (pB->a[i/8] & 1<<(i%8))) {return 1;}
22
   return 0;
23
}
24
int Tog(struct sB *pB, unsigned int i)
25
{
26
   if(Tst(pB, i)) Res(pB, i); else Set(pB, i);
27
}
28
29
struct sB BKeys;
30
struct sB BKeysOld;
31
struct sB BLEDs;
32
33
34
int main(void)
35
{
36
int i;
37
...
38
   /* Keys Lesen */
39
   for(i=0; i < N_BYTES; i++)
40
   {
41
      BKeys.a[i]=...; /* lesen des nächsten Bytes */
42
   }
43
   /* Tastenauswertung */
44
   for(i=0; i < MAX_IDX; i++)
45
   {
46
      if(Tst(&BKeys, i) && !Tst(&BKeysOld, i)) Tog(&BLEDs, i);
47
   }
48
   for(i=0; i < N_BYTES; i++)
49
   {
50
      ...=BLEDs.a[i]; /* Schreiben der LEDs oder in FRAM */
51
   }
52
}
natürlich ist der Code nicht gut, hat Schreibfehler und kein 
Tastenentprellen. Und natürlich wäre es viel performanter, das ganze in 
32-Bit-Strukturen anzulegen und diese komplett zu verodern, vor allem 
beim Entprellen. Das darf aber keine Rolle spielen, dass der Code dann 
10 statt 109µs dauert.

von Uli A. (schnuppi44)


Lesenswert?

Danke A.S. für Deine Mühe !

Super. Da habe ich schonmal was zum Knobeln und Recherchieren....das ist 
ne für mich noch komplett unbekannte "Denke", nachdem ich bisher nur ein 
bisschen Arduino C mit Variablen programmiert habe....

Spannend....!

von Falk B. (falk)


Lesenswert?

Bitte mal die Diskussion verschieben.

von Gerd E. (robberknight)


Lesenswert?

Uli A. schrieb:
> Gerd E. schrieb:
>> Es gibt ICs, die LED- und Tastaturmatrix in einem Baustein kombinieren
>> und dann z.B. per I2C oder SPI angesteuert werden können.
>
> Hättest Du da ein Beispielexemplar ? Kenne ich so noch nicht...dachte
> eigentlich, dass man solche Matritzen auch über Schieberegister
> ansteuert...

Die chinesischen TM1637 und TM1638 können LED- und Tastenmatrix. Gibt es 
z.B. bei LCSC. Englisches Datenblatt und Beispielcode findest Du über 
Google.

Der MAX7219 wäre noch eine Alternative die nur LED-Matritzen ansteuern 
kann.

von Uli A. (schnuppi44)


Lesenswert?

Danke noch @Gerd für die Beispiele mit den ICs. Einen MAX habe ich eh 
schon hier und rein von der Ansteuerung ist das auch ein guter Ansatz.
Allerdings ist die Schieberegisteridee in meinem Fall trotz der höheren 
Anzahl von ICs die bessere Wahl, vor allem, weil ich mit dem gleichen 
"Steuerbit" auch noch je ein Relais schalten muss und daher mehr Power 
brauche....das mit den Relais hatte ich hier rausgelassen, weil es für 
mich mit der Frage in erster Linie um die Lösung auf Programmierebene 
ging - daher eigentlich auch der Eintrag in der Rubrik "Projekte & Code" 
;-)

Und nochmal Dank an A.S. für das Bringen auf die Spur mit dem 
Strukturenansatz - das macht natürlich total Sinn....!

Wieder alles sehr lehrreich hier !!!

von Peter D. (peda)


Lesenswert?

EVA-Prinzip:
Du liest alle Tasten in den internen SRAM ein.
Dann verarbeitest Du die Tastendrücke (Eingänge) zu entsprechenden 
Aktionen auf den virtuellen Ausgängen im SRAM. Und dann gibst Du die 
Ausgangsmuster aus.

Alle Verarbeitung erfogt also nur auf virtuellen Portpins im SRAM.
Und eine Schieberoutine liest nur ein bzw. gibt aus. Typisch nimmt man 
dazu die SPI-Schnittstelle.

Du kannst im SRAM auch noch Zwischenvariablen ablegen. Z.B. für die 
Flankenerkennung brauchst Du je Taste noch ein Merkerbit.

: Bearbeitet durch User
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.