Forum: Mikrocontroller und Digitale Elektronik Eingänge einlesen und per Shift register ausgeben


von T.M .. (max)


Lesenswert?

Hallo,

ich bräuchte mal einen Denkanstoß...

An einen Mikrocontroller sollen 8 Eingänge (Schalterstellungen) 
abgefragt werden.
Schalten will ich damit 8 bistabile Relais. D.h ich benötige am 
Mikrocontroller 2 Pins, um Set und Reset am relais auslösen zu können.
Hierzu will ich zwei Shiftregister 595 nehmen.
Nur wie bekomme ich die einzelnen Schalterstellungen zusammengefasst, um 
sie auf das Register zu schicken??
 Vielleicht hat jemand einen Tipp wie man das am geschicktesten löst?

von Felix Bait (Gast)


Lesenswert?

Hallo Max,

am besten fasst Du deine 8 Schalterzustände in einem sogenannten Byte 
zusammen. Das hat zufällig genau 8 Bit, die jeweils den Zustand 0 oder 1 
haben. Also nimmst du je Schalter ein Bit dieses Bytes und schon ist 
alles so zusammengefasst, dass du es bequem weiterverarbeiten kannst.

Felix

von Max H. (hartl192)


Lesenswert?

Max .. schrieb:
>  Vielleicht hat jemand einen Tipp wie man das am geschicktesten löst?
Mit einem µC der genug IOs hat, sodass du auf die SR (Schieberegister) 
verzichten kannst.
Wenn das nicht geht: Hang die Eingänge an die unteren 8 bit eines Ports, 
und sende dann an die SR:
1
while(1)
2
{
3
  sendByte(TASTERORT);   // Zweites SR
4
  sendByte(~TASTERORT);  // Erstes SR
5
  STCP_HIGH();
6
  STCP_LOW();
7
}
An das erste SR hängst du alle SET, ans zweite alle RESET (das Relais 
für den Taster an PORTx0 an die Q0 der SRs usw.). Wenn die 
Schalterstellungen exklusiv-oder die Relais Low aktiv sind vertauschst 
du die beiden Zeilen.

Wenn das ganze Layouttechnisch nicht geht: Eine if-Abfrage für jeden 
Eingang, in der dann die entsprechenden bits in einer uint16_t 
gesetzt/gelöscht werden. Diese uint16_t sendest du dann an die SR. z.B. 
für einen Eingang und SET/REST an Q0/Q1 des ersten SRs
1
uint16_t tx_data
2
while(1)
3
{
4
  if(EINGANG_1)
5
  {
6
    tx_data |= (1 << 0);
7
    tx_data &= ~(1 << 1);
8
  }
9
  else
10
  {
11
    tx_data |= (1 << 1);
12
    tx_data &= ~(1 << 0);
13
  }
14
  // Weitere Eingänge
15
16
17
  sendByte(tx_data >> 8);       // Zweites SR
18
  sendByte(tx_data);  // Erstes SR
19
}

: Bearbeitet durch User
von Georg (Gast)


Lesenswert?

Max .. schrieb:
> An einen Mikrocontroller sollen 8 Eingänge (Schalterstellungen)
> abgefragt werden.
> Schalten will ich damit 8 bistabile Relais.

Denkanstoss: warum schaltest du die Relais nicht direkt mit den 
Schaltern?

Georg

von Dirk K. (dekoepi)


Lesenswert?

Hm, billiges Schieberegister, an jeden Ausgang einen Taster (oder halt 
Schalter). Dann in der Schleife oder im Interrupt einfach immer ein Bit 
durchschieben. Auf der anderen Tasterseite alle gemeinsam auf eine 
Leitung schalten; am µC-Pin dazu den Pulldown aktivieren und vielleicht 
noch einen 1kOhm-Widerstand zwischen die Leitung und µC-Pin setzen. Wenn 
du nun mitzählst, kannst du ständig alle 8 Stellungen durchlaufen. und 
bei einer davon ist bei gedrücktem Taster der µC-Pin auf 1 statt 0.
Ausgangsseitig nun genau andersherum, da das passende Bit setzen, das 
Byte durchschieben, Latch aktivieren, fertig.
Entprellung wäre noch nett dazu, aber grob sollte das so gehen.

Oder verstehe ich das Problem falsch?
Ein Shiftregister verarbeitet auch nur Bytes, halt bitweise.

Pseudocode, Schnellschuss, geht hübscher, könnte leichten Fehler haben 
;) :
1
// 595_TASTER: Schieberegister mit den Schaltern dran
2
// 595_RELAIS: Schieberegister mit den 8 Relais dran
3
// 595_*_*_PIN: der jeweilige µC-Pin mit den Schieberegister-Anschlüssen dran
4
5
595_TASTER_LATCH_PIN=0;
6
595_RELAIS_LATCH_PIN=0;
7
8
595_TASTER_DATA_PIN=1;  // durchzuschiebendes Bit für die Tastenabfrage setzen
9
10
for (uint8_t j=0; j<8; j++) 
11
{
12
  595_TASTER_CLK_PIN=1;  // einen CLK-Puls zum weiterschieben des Bits
13
  595_TASTER_CLK_PIN=0;
14
  595_TASTER_LATCH_PIN=1;  // Schieberegister-Ausgang anschalten
15
  595_TASTER_DATA_PIN=0;  // und jetzt nur noch Nullen nachsetzen
16
17
  if (TASTER_LEITUNG) 595_RELAIS_DATA_PIN=1;  // Taste an dieser Position gedrückt -> Bit im Relais-Register an richtiger Stelle setzen
18
  595_RELAIS_CLK_PIN=1;  // und mit einem Takt weiterschieben
19
  595_RELAIS_CLK_PIN=0;
20
  595_RELAIS_DATA_PIN=0;  // aber nur setzen, wenn Taste gedrückt war
21
  595_TASTER_LATCH_PIN=0;  // Taster-Register wieder "ausschalten"
22
}
23
595_RELAIS_LATCH_PIN=1;  // und am Ende die Relais nach dem umkopierten Register an/ausschalten.

Transferaufgabe für dich: Das war jetzt nur das SET-Register. Bestücke 
das Reset-Register in den Code - sollte trivial sein.

: 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.