Forum: Mikrocontroller und Digitale Elektronik HT16K33 KeyScan


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,

ich habe hier vor mir die SOP28 Version des HT16K33.
Ich betreibe bereits erfolgreich 4x7 Segmente an ROW0-ROW7 & 
COM0+COM1+COM3+COM4.

Jetzt möchte ich 3 Taster, welche zwischen COM5 und ROW13-15 hängen 
auslesen.

Wenn ich es richtig verstanden habe lese ich Register 0x45 (für COM5) 
aus und erhlate eine 13Bit lange Antwort, in der alle Kombinationen von 
KS0-KS13 mit COM5 enthalten sind. (?)

Doch meine I2C Lib arbeitet derzeit mit "uint8_t"

Wie müsste ich da entsprechend ran gehen?
1
uint16_t Key_ReadCom5()
2
{
3
  return I2C_ReadRegister(HT16K33, 0x45);
4
}
5
6
uint8_t I2C_ReadRegister(uint8_t busAddr, uint8_t deviceRegister) {
7
  uint8_t data = 0;
8
  I2C_Start(busAddr); // send device address
9
  I2C_Write(deviceRegister); // set register pointer
10
  I2C_Start(busAddr + READ); // restart as a read operation
11
  data = I2C_ReadNACK(); // read the register data
12
  I2C_Stop(); // stop
13
  return data;
14
}

Und reicht es dann Key_ReadCom5(); in einem Interrupt regelmäßig 
aufzurufen, oder muss ich noch andere Dinge vorher initialisieren (wie 
ich es in irgendeiner python-lib erahnen konnte)

PS: Thematik Key-Press-duration/hold/debouncing?

Grüße Oekel

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

D a v i d K. schrieb:

> Jetzt möchte ich 3 Taster, welche zwischen COM5 und ROW13-15 hängen
> auslesen.

Da habe ich dann wohl schon den ersten Designfehler!?
KS0/1/2 = COM1/2/3. Somit sollte ich erst mal Die Zuleitung umlegen.

Dennoch bräuchte ich Infos, wie ich nun die 13Bits von einem der 3 
Register abrufen kann.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn du die Taster wie auf Seite 23 des Datenblattes beschrieben, 
angeschlossen hast, kannst du sequentiell, also ohne Absetzen, die 
Register 40h bis 45h auslesen (siehe Seite 21). Die liest du entweder in 
ein Array ein als uint8_t mit 6 Werten oder du liest, wenn dich nur z.B. 
die Tasten auf COM1 interessieren, Register 40h und 41h ein.
Wenn du z.B. nur K1 - K8 auf COM1 benutzt, reicht ein einziges Lesen des 
Registers 40h, da sind dann die 8 Tasten drin.
Es hängt also nur davon ab, welche K Anschlüsse du mit den drei 
erlaubten COMs verbindest.
D a v i d K. schrieb:
> Jetzt möchte ich 3 Taster, welche zwischen COM5 und ROW13-15 hängen
> auslesen.

Auf Seite 23 siehst du ja, das COM5 gar nicht erlaubt ist.

: Bearbeitet durch User
von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Matthias S. schrieb:

> ein Array ein als uint8_t mit 6 Werten oder du liest, wenn dich nur z.B.
An der Stelle war ich dann wohl doch zu müde, sonst hätte ich vermutlich 
1&1 zusammen zählen können und wäre bei KS1-3 *2 = auf die 6 Register 
40h bis 45h gekommen.

Besten dank! Hab es umgelötet und probiere es gleich aus.

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Funktioniert wunderbar. Noch eine letzte Frage:

ich habe neben dem funktionieren Display einen freien COM6, den ich 
gerne für eine weitere LED nutzen möchte. Allerdings nicht innerhalb 
dieser typischen Matrix.

Normal sollte doch folgendes funktionieren, oder?

5V+ ---> LED --[R]-- COM6

Doch die LED leuchtet dauerhaft, egal wie ich die beiden Register für 
COM6 beschreibe:
1
  I2C_WriteRegister(HT16K33, 0x0C, 0x00);//COM6
2
  I2C_WriteRegister(HT16K33, 0x0D, 0x00);//COM6
3
  //I2C_WriteRegister(HT16K33, 0x0C, 0xFF);//COM6
4
  //I2C_WriteRegister(HT16K33, 0x0D, 0xFF);//COM6

Hat da Jemand noch einen Tipp?

Grüße Oekel

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

D a v i d K. schrieb:
> Normal sollte doch folgendes funktionieren, oder?
>
> 5V+ ---> LED --[R]-- COM6

Nö, die wird immer leuchten, weil die COM Outputs einfach 
durchgeklappert werden. Du musst auch diese LED zum Bestandteil der 
Matrix machen, indem du sie nicht gegen +5, sondern gegen einen der ROWs 
schaltest. Aktivieren dann genauso wie die LEDs, die du schon in der 
Matrix auf den unteren COMs hast, nur eben auf COM6.
Wenn du also die LED gegen ROW0-ROW7 schaltest gilt Adresse 0x0C, bei 
ROW8-ROW15 dann Adresse 0x0D.

: Bearbeitet durch User
von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Matthias S. schrieb:
> D a v i d K. schrieb:
>> Normal sollte doch folgendes funktionieren, oder?
>>
>> 5V+ ---> LED --[R]-- COM6
>
> Nö, die wird immer leuchten, weil die COM Outputs einfach
> durchgeklappert werden. Du musst auch diese LED zum Bestandteil der
> Matrix machen, indem du sie nicht gegen +5, sondern gegen einen der ROWs
> schaltest.

Ich möchte aber einen "sanften Übergang" von altem HW-Design (Wo die LED 
noch direkt vom µC-PIN geschaltet wird) zum Neuen (über den HT16K33)

Derzeit "jumper" ich die LED genau an dieser Stelle um. Gibt es da eine 
elegante Übergangslösung, denn ich möchte dasss DIESE LED nicht mit 
gedimmt wird.

Grüße Oekel

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

D a v i d K. schrieb:
> Gibt es da eine
> elegante Übergangslösung, denn ich möchte dasss DIESE LED nicht mit
> gedimmt wird.

Nicht mit diesem Chip. Entweder steuerst du die LED wie in alten Zeiten 
direkt vom MC an oder du steigst auf einen Frontplatten Controller mit 
extra LED Ausgängen um. Mir fällt im Moment der Kram von Princeton Tech 
ein, wie der PT6312, der ist aber für VFD gedacht und hat 4 extra LED 
Ausgänge.
Die LED Driver von Princeton (z.B. der PT6963) scheinen aber auch 
keine extra Ausgänge für Einzel-LED zu haben.

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Ok danke, dann weiß ich zumindest, dass diese Funktionalität auf dem 
Markt völlig unüblich ist. Und für eine einzelne einen weiteren 
I2C-PortExpander halte ich total übertrieben.

Wäre einfach schön gewesen von der Hauptplatine zum Display wirklich nur 
noch die 4 I2C Leitungen zu haben.

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,

könnt ihr das Datenblatt für mich ein letztes Mal deuten? ;)
Ich erhoffe mir eine Funtionalität, die ich aber nicht im text finde.

Das HT16K33 'act' Bit. Im Datenblatt überall dort zu finden, wo von INT 
die Rede ist. Das ein externe PIN==act geschaltet wird oder eben 
PIN==!act ist mir klar.

Nur nicht, wann dieses genau gesetzt wird. Laut Pegel auf den Grafiken 
hat es etwas mit dem KeyScan zu tun??

Aktuell speicher ich mir die alten Tastenzustände, um in der nächsten 
Iterration ein bool anySwitchChanged zu definieren.

Bietet mir das 'act' evtl. genau diese Funktionalität?

Grüße Oekel

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.