Assembler Tasterabfrage mit 74HC164

diamant 400

Neues Mitglied
18. Nov. 2014
8
0
0
Hölle
Sprachen
  1. Assembler
Hallo,
ich bin neu hier und fange gerade an mich in die Atmels einzuarbeiten.

Mich würde grundsätzlich interessieren wie ich die Taster und die LEDs mit dem 74HC164 in Kaskade (bis zu 8 Stück) ansteuere und abfrage.
Kann denn ein Atmega auch bis zu 64Bit einlesen, speichern und wieder ausgeben?

Gruß
Dieter
 
Hallo Dieter,

ich bin neu hier und fange gerade an mich in die Atmels einzuarbeiten.

herzlich willkommen im Forum :flowers:

Mich würde grundsätzlich interessieren wie ich die Taster und die LEDs mit dem 74HC164 in Kaskade (bis zu 8 Stück) ansteuere und abfrage.
Kann denn ein Atmega auch bis zu 64Bit einlesen, speichern und wieder ausgeben?

Kann er. Du mußt es nur in Häppchen zu 8Bit machen. Per Software könntest du auch kontinuierlich Bitfolgen aus nem Pin schieben oder einlesen. Per Hardware geht es mit etwas Bastelei auch kontinuierlich.

Gruß
Dino
 
Dankeschön für das Willkommen.

Bei den LEDs kein Problem, da schiebe ich mir das passende Bitmuster ein, aber wenn ein Taster parallel zur LED ist (?)

oder schiebe ich eine 0 und frage ab, dann eine 1 und frage wieder und dann nur noch 1er schieben. Nur wo speichere ich dies Info alles ab? Geht sowas im Stack?
Ach Moment - ich hab die Hardware dazu vergessen
 

Anhänge

  • Taster 1.jpg
    Taster 1.jpg
    134,3 KB · Aufrufe: 37
Hi Dieter,

ist ja ne dolle Schaltung :p Wo hast du die denn ausgegraben? Irgendwo ein Modul gefunden oder ausgebaut?
Das sieht so aus als wenn man die Tastenabfrage dabei über eine Art Scan machen muß. Ist für Einsteiger nicht grade einfach zu überblicken wie man das machen kann. Wird auch eine ziemliche Timing-Frage sein damit man den Scan auf den LEDs nicht sieht :rolleyes:

Also so wie ich es sehe gehen alle Tasten auf eine Leitung und die dann auf einen Pin des Mikrocontrollers. Mit einer durchgeschobenen 0 durch die Register kann man die Tasten dann "abscannen". Damit bei diesem Abscannen nicht die LEDs rumleuchten scheint man die in dieser Phase mit dem BC485 totlegen zu können. Der muß also beim abscannen gesperrt werden damit die LEDs keinen Strom bekommen. Wenn man sich für das scannen aber zuviel Zeit nimmt, dann wird man das bei den LEDs sehen weil die dann kurz dunkel sind. Nach dem Tasten scannen muß man wieder die Daten für die LEDs reinschieben um die gewünschten zum leuchten zu bringen. Den Transistor dafür auch wieder einschalten. Wenn man sich für das abscannen aber zuwenig Zeit nimmt, dann könnte die Zeit evtl nicht reichen das sich die Pegel stabilisieren. Hab ich selber schonmal erlebt.

Also das ist nicht grade Einsteigerfreundlich weil das viele Fallstricke bereithält :lollypop: Ich weiß jetzt nicht wie weit du dich mit Programmierung, Controllern, Elektronik auskennst um absehen zu können ob du das hinbekommst oder es im Frust endet.

Gruß
Dino
 
Hi Dino,

erst einmal Danke für deine ausführliche Antwort.
Diese dolle Schaltung ist ein kleiner Bestandteil meiner Musikmaschine (BJ 1984). Dort werden mehr als 200 Taster auf diese Weise abgefragt.
So große Timingprobleme dürfte es eigentlich nicht geben, da in meinem Musikinstrument nur eine kleine CPU "wörkelt" und das mit nur 4 MHz.
Geplant ist bei mir ein Atmega644 mit 20 MHz.
Das ganze soll eigentlich eine Speichererweiterung werden und ich benötige diese um die oberen Adressen des RAM-Speichers anzusteuern.
Also Taste 1 gedrückt - LED 1 leuchtet - Adressleitungen A18-A13 = 000000
Taste 2 gedrückt - LED 2 leuchtet - Adressleitungen A18-A13 = 000001
usw... bis Taste 16
Taste 1 erneut gedrückt - LED 17 leuchtet - Adressleitungen A18-A13 =0010000

oder so ähnlich. Somit kann ich meinen Speicherbereich um ein vielfaches erweitern.

Ein Bild meiner Musikmaschine füge ich bei. Die Firma dürfte ja in BüBu bekannt sein.

Gruß
Dieter
 

Anhänge

  • 003 md1030xl.jpg
    003 md1030xl.jpg
    32,4 KB · Aufrufe: 20
Hallo Dieter,
Willkommen im Forum.

Auch wenn es nicht direkt zu deinem Thementitel passt und deine Frage beantwortet, schau dir mal den HT16K33 an. Du könntest die Controller kaskadieren, damit du ausreichend Taster abfragen kannst, das Layout wird sicherlich auch einfacher.

Dirk :ciao:

EDIT: ach, es ist eine bestehende Schaltung :)
 
Hallo Dirk,

auch dir ein herzliches Willkommen.
Das IC von dir klingt auch interessant - kommt für mich leider nicht in Frage da schon bestehende Hardware.

Die ganze Schaltung kommt natürlich noch viel öfter zum Einsatz, da ich insgesammt 4 Platinen vor mir liegen habe.
Es sollen insgesammt 108 Taster werden. Siehe Anhang.
Gruß
Dieter
 

Anhänge

  • Bedientaster 200CT.jpg
    Bedientaster 200CT.jpg
    272,2 KB · Aufrufe: 24
Hi Dieter,

Ein Bild meiner Musikmaschine füge ich bei. Die Firma dürfte ja in BüBu bekannt sein.

?? Ich kenn eigentlich nur Dr.Böhm. Wenn ich mich recht entsinne waren die vor Uhrzeiten mal in Minden beheimatet.
Hatte nen Schulkollege mal ne Orgel davon und hat später nach der Schule da auch angefangen zu arbeiten. Die ICs bei denen waren aber immer abgeschliffen und mit IC1, IC2, ... bedruckt :p

Hmmm :confused: und das willst du in Assembler lösen? Du kannst auch in Bascom sehr schön Assembler einpflegen. Das mache ich zB gerne. Dann kann man die zeitkritischen Sachen in Assembler machen und die komplizierten in Bascom :cool:

Da du bei den Platinen eigentlich nur seriell ausgeben mußt sollte das Programm recht gut umsetzbar sein wenn man bereits ein paar Grundlagen drauf hat. Das komplizierteste dabei ist die Ausarbeitung des zeitlichen Ablaufs für die Tastenabfrage.

Gruß
Dino
 
Hallo Dino,

eben jene "Dr. Böhm" nennt sich jetzt Keyswerk. Nicht alle ICs waren abgeschliffen nur ganz spezielle die man sonst nur auf Umwegen bekommen hätte.

Ja am besten alles in Assembler (Bascom oder C müsste ich mich erst einlesen). Im zeitlichen Ablauf sehe ich erst mal keine Probleme, da erstens immer nur eine Taste gedrückt wird und nicht viele nacheinander und es soll auch nur eine LED leuchten. Also bei 32Bit die eingelesen wurden ist nur eines gesetzt (bzw in meinem Fall 0), ebenso bei den LEDs (da jedoch 64 Bit).

Gruß
Dieter
 
Hi Dieter,

eben jene "Dr. Böhm" nennt sich jetzt Keyswerk. Nicht alle ICs waren abgeschliffen nur ganz spezielle die man sonst nur auf Umwegen bekommen hätte.
aha .. dann kann ich das jetzt einordnen :)

Im zeitlichen Ablauf sehe ich erst mal keine Probleme, da erstens immer nur eine Taste gedrückt wird und nicht viele nacheinander und es soll auch nur eine LED leuchten. Also bei 32Bit die eingelesen wurden ist nur eines gesetzt (bzw in meinem Fall 0), ebenso bei den LEDs (da jedoch 64 Bit).
Du mußt andersrum denken. Du liest kein Bitmuster ein. Du mußt bei der Schaltung ein Bitmuster ausgeben und nachsehen ob sich an einem Pin wo alle Taster dranhängen was tut.

1. Transistor sperren (LEDs aus)
2. Alle Register mit 1 füllen (reinschieben) -> alle Taster deaktiv
3. Nur eine 0 einschieben damit der erste Taster aktiv wird.
4. Nachsehen ob sich am gemeinsamen Tasterpin was tut.
5. Eine 1 nachschieben.
6. Schleife zu 4. bis alle Taster abgefragt sind.
7. Bitmuster reinschieben für die LEDs die leuchten sollen
8. Transistor wieder ansteuern (LEDs an)

so sollte die Routine in etwa aussehen.

Gruß
Dino
 
Hi Dino,

genau so hatte ich es auch vor. Nur muss ich ja dieses Bitmuster was über die Taster ankommt irgendwo zwischenspeichern, damit ich es als LED Muster wieder ausgeben kann. Und jetzt kommt mein großes Problem: Wie und Wo speichere ich ein durchgeschobenes Bit (bzw. Am Ende 32Bit) ab und hole es in der richtigen Reihenfolge wieder für meine LEDs.

Dieter
 
Und jetzt kommt mein großes Problem: Wie und Wo speichere ich ein durchgeschobenes Bit (bzw. Am Ende 32Bit) ab und hole es in der richtigen Reihenfolge wieder für meine LEDs.

du denkst zu kompliziert :) Wie Caesar: Teile und herrsche :cool:
Bau dir in die Schleife nen Bitzähler rein. Nimm die unteren 3 Bit des Zählers als Pointer inerhalb eines Bytes und die übrigen Bits als Pointer auf das Byte. Du legst also die 32Bit in 4 einzelnen Bytes ab. Bei Assembler gibt es doch so schöne Bit-Popelei-Befehle :cool:

Du kannst doch auch wenn der Taster gedrückt wurde den Pin testen und über das Carry oder mit Hilfe des T-Bits und dem Carry in ein Byte schieben und wenn ein Byte voll ist wird es über den Byte-Pointer (siehe oben) in die passende SRAM-Zelle gelegt.

Gruß und gute Nacht
Dino
 
Hallo,

habe mir unterdessen einiges an Wissen zugelegt und folgende Zeilen dazu
geschrieben.
Nun ist meine Frage:
Ist das soweit ok oder habe ich immer noch einen Denkfehler um meine Taster zu sperren?

Code:
/*------------------------------------------------------------------------------------------------------------
 * Tasterabfrage1.asm
 *
 *  Created: 20.11.2014 20:40:51
 *   Author: Dieter
 * Anschlußbelegung: Atmega 644P
 *
 * Pin 1 PB0 = A von CD4067 Pin 10					Pin 40 PA0 = LED 1.1 von Platine 45
 * Pin 2 PB1 = B von CD4067 Pin 11					Pin 39 PA1 = LED 1.2 von Platine 45
 * Pin 3 PB2 = C von CD4067 Pin 14					Pin 38 PA2 = LED 2.1 von Platine 46
 * Pin 4 PB3 = D von CD4067 Pin 13					Pin 37 PA3 = LED 2.2 von Platine 46
 * Pin 5 PB4 =								Pin 36 PA4 = LED 3.1 von Platine 47
 * Pin 6 MOSI								Pin 35 PA5 = LED 3.2 von Platine 47
 * Pin 7 MISO								Pin 34 PA6 = LED 4.1 von Platine 48
 * Pin 8 SCK								Pin 33 PA7 = LED 4.2 von Platine 48
 * Pin 9 RESET								Pin 32 AREF (VCC)
 * Pin 10 VCC								Pin 31 AGND (GND)
 * Pin 11 GND								Pin 30 AVCC (VCC)
 * Pin 12 Quarz Takt 20 MHz						Pin 29 PC7 = Serial In von Platine 45
 * Pin 13 Quarz Takt 20 MHz						Pin 28 PC6 = Serial In von Platine 46
 * Pin 14 PD0 = A13 von SRAM Pin 28					Pin 27 PC5 = Serial In von Platine 47
 * Pin 15 PD1 = A14 von SRAM Pin 3					Pin 26 PC4 = Serial In von Platine 48
 * Pin 16 PD2 = A15 von SRAM Pin 31					Pin 25 PC3 = CLK (gemeinsame Taktleitung aller Platinen)
 * Pin 17 PD3 = A16 von SRAM Pin 2					Pin 24 PC2 = Tasterrückleitung von Platine 45
 * Pin 18 PD4 = A17 von SRAM Pin 30					Pin 23 PC1 = Tasterrückleitung von Platine 46
 * Pin 19 PD5 = A18 von SRAM Pin 1					Pin 22 PC0 = Tasterrückleitung von Platine 47
 * Pin 20 PD6 =										Pin 21 PD7 = Tasterrückleitung von Platine 48
 *
 * Die Tasterrückleitungen sind mit Pullup Widerständen auf 1 gezogen und werden auf 0 abgefragt
 *
 *------------------------------------------------------------------------------------------------------------- 
 */ 

 .INCLUDE <m644Pdef.inc>						    ;Controllertyp Atmega 644P

 ;---------------------------------------------------------------------------------------
 ;
 ; definieren der Register
 ;
 ;---------------------------------------------------------------------------------------
 .def temp1    = r16                                                            ; Register 1 für temporäre Aufgaben
 .def temp2    = r17								; Register 2 für temporäre Aufgaben
 .def temp3    = r18								; Register 3 für temporäre Aufgaben
 .def temp4    = r19								; Register 4 für temporäre Aufgaben
 .def temp5    = r20								; Register 5 für temporäre Aufgaben

 ;-----------------------------------------------------------------------------------------
 ;
 ; festlegen der Daten
 ;
 ;-----------------------------------------------------------------------------------------
 .equ F_CPU = 20000000                                                          ; Systemtakt in Hz (20MHz)
 .equ TRANS        = DDRA							;
 .equ TRANS_AUS    = PORTA							; PORT A für Transistoren der LEDs
 .equ MULTI        = DDRB							;
 .equ MULTI_AUS    = PORTB							; PORT B für CD4067 Multiplex
 .equ SRAM         = DDRD							;
 .equ SRAM_AUS     = PORTD							; PORT D für SRAM Adressen
 .equ SCHIEBE_DDR  = DDRC							;
 .equ SCHIEBE_PORT = PORTC							; PORT C für Serial IN
 .equ SCK          = PC3							; Takt PIN 8 von 74HC164
 .equ SIN1         = PC4							; Serial Eingang Pin 1 von 74HC164 Platine 48
 .equ SIN2	   = PC5							; Serial Eingang Pin 1 von 74HC164 Platine 47
 .equ SIN3	   = PC6							; Serial Eingang Pin 1 von 74HC164 Platine 46
 .equ SIN4	   = PC7							; Serial Eingang Pin 1 von 74HC164 Platine 45
 .equ TAST1        = PC2							; Eingang von Tasterplatine 45
 .equ TAST2        = PC1	                        			; Eingang von Tasterplatine 46
 .equ TAST3        = PC0							; Eingang von Tasterplatine 47
 .equ TAST4        = PD7							; Eingang von Tasterplatine 48

 ;-----------------------------------------------------------------------------------------------
 ;
 ; Initialisieren
 ;
 ;-----------------------------------------------------------------------------------------------
    ldi   temp1, LOW(RAMEND)						; Stackpointer initialisieren
    out   SPL, temp1
    ldi   temp1, HIGH(RAMEND)
    out   SPH, temp1

;------------------------------------------------------------------------------------------------ 
;
; Die Port Pins auf Ausgang konfigurieren
;
;------------------------------------------------------------------------------------------------
    ldi   temp1,  (1<<SCK) | (1<<SIN1)  | (1<<SIN2) | (1<<SIN3) | (1<<SIN4)    ; Wert 248 laden und
    out   SCHIEBE_DDR, temp1						       ; an PORT C ausgeben. PC3 - PC7 Ausgang
    ldi   temp1,  255							       ; Wert 255 laden und
    out   TRANS,  temp1							       ; an PORT A ausgeben. PA0 - PA7 Ausgang
    ldi   temp1,  0							       ; Wert 0 laden und
    out   PORTA,  temp1							       ; an Portpins ausgeben zum sperren der Transistoren
    ldi   temp1,  63							       ; Wert 63 laden und
    out   MULTI,   temp1						       ; an PORT B ausgeben. PB0 - PB4 Ausgang
    ldi   temp1,  127							       ; Wert 127 laden und
    out   SRAM,   temp1							       ; an PORT D ausgeben. PD0 - PD6 Ausgang

;----------------------------------------------------------------------------
;
; Schleife muss 4 mal durchlaufen
;
;----------------------------------------------------------------------------
Schleife:
    push  temp3					; Register 18 auf Stack sichern
    ldi   temp3, 4				; Schleife muss 4 mal durchlaufen werden
    rcall Sperr					; Aufruf zum sperren aller Taster

loop:
    rjmp  loop					; hier kommt das eigentliche Programm hin
;-------------------------------------------------------------------------------------------------
;
; nach dem sperren aller Taster eine 0 einschieben und Tasterpins abfragen
; eine 1 nachschieben und Tasterpins wieder abfragen bis alle Taster abgefragt wurden
; Bitmuster für die LEDs einschieben
; Transistoren freigeben für LEDs
;
;--------------------------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------------------------
;
; Datenbyte ausgeben zum sperren aller Taster
;
;------------------------------------------------------------------------------------------------
Sperr:
    ldi   temp1, 255						; Wert 255 laden
    rcall Schiebe						; Aufruf von Schiebe:


;-----------------------------------------------------------------------------
;
; 8 Bits aus temp1 an das Schieberegister ausgeben
;
;------------------------------------------------------------------------------
Schiebe:
    push  temp2				   ; Register 17 auf Stack sichern
    ldi   temp2, 8                         ; 8 Bits müssen ausgegeben werden
 
Schiebe_1:
;-----------------------------------------------------------------------
;
; jeweils das höchstwertige Bit aus temp1 ins Carry-Flag schieben
; Je nach Zustand des Carry-Flags wird die Datenleitung entsprechend
; gesetzt oder gelöscht
;
;------------------------------------------------------------------------
    rol  temp1                 ; MSB -> Carry
    brcs Schiebe_One           ; Carry gesetzt? -> weiter bei Schiebe_One
    cbi  SCHIEBE_PORT, SIN1    ; Eine 0 ausgeben
    cbi  SCHIEBE_PORT, SIN2    ; Eine 0 ausgeben
    cbi  SCHIEBE_PORT, SIN3    ; Eine 0 ausgeben
    cbi  SCHIEBE_PORT, SIN4    ; Eine 0 ausgeben
    rjmp Schiebe_Clock         ; und Sprung zur Clock Puls Generierung
Schiebe_One:
    sbi  SCHIEBE_PORT, SIN1    ; Eine 1 ausgeben
    sbi  SCHIEBE_PORT, SIN2    ; Eine 1 ausgeben
    sbi  SCHIEBE_PORT, SIN3    ; Eine 1 ausgeben
    sbi  SCHIEBE_PORT, SIN4    ; Eine 1 ausgeben
 
;--------------------------------------------------------
;
; einen Impuls an SCK zur Übernahme des Bits nachschieben
;
;---------------------------------------------------------
Schiebe_Clock:
    sbi   SCHIEBE_PORT, SCK    ; Clock-Ausgang auf 1 ...
    cbi   SCHIEBE_PORT, SCK    ; und wieder zurück auf 0
 
    dec   temp2                ; Anzahl der ausgegebenen Bits runterzählen
    brne  Schiebe_1            ; Wenn noch keine 8 Bits ausgegeben -> Schleife bilden
    dec   temp3		       ; Anzahl der Durchläufe runterzählen
    brne  Sperr		       ; Wenn noch keine 4 Durchläufe -> Schleife bilden
 
    pop   temp2		       ; Register 17 aus Stack zurückholen
    pop   temp3		       ; Register 18 aus Stack zurückholen
    ret			       ; Rücksprung nach loop:
 

Anhänge

  • Tasterabfrage1.txt
    8,4 KB · Aufrufe: 33
Hi Dieter,

ich hab dein Programm mal eingefügt. Dann muß man nicht extra die Datei runterladen. Das beschleunigt die Hilfe hoffentlich ;)

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)