Forum: Mikrocontroller und Digitale Elektronik 32 digtale Eingänge an Mega32 (Kaskadierte Schieberegister)


von Alex O. (Gast)


Lesenswert?

Hallo!

ich versuche mich gerade an einem Eingangs-Porterweiterung an einem 
Mega32 mit 4 kaskadierten Schieberegistern 74HCT165. Die Schieberegister 
werden vom Controller über Software-SPI angesteuert. Über den 
Timerinterrupt werden die Schieberegister alle 10ms eingelesen.

Leider kriege ich im Controller aber falsche Ergebnisse. Zum Test habe 
ich mal alle 32 Eingangspins auf Low gelegt und dann Pin für Pin die 
Eingänge auf High gelegt und mir das im Controller ankommende Ergebnis 
angeschaut (siehe beliegende Tabelle; ganz links das Eingangspin das 
High ist, rechts daneben das vom Controller gelesene Ergebnis (mittels 
RS232 an PC übergeben), und ganz rechts nochmal eine Übersichtstabelle 
welches Pin als High erkannt wird).
Wie man sieht, werden einige Pins falsch eingelesen: z.B. bei Pin 1 
werden Pin 1+16 auf High gesetzt...

weiteres Tests, die ich mit der selben Schaltung, aber nur mit einem 
Register gemacht habe, ergaben keine Probleme. Die von mir entwickelte 
Assembler-Software schaue ich mir schon zum x-ten Mal an, sehe aber dort 
keine Probleme (Simulation im AVR-Studio schaut auch gut aus). Ich 
vermute das Problem eher bei der Hardware / Schaltung.
Ich habe die Schieberegister einfach (wie im Datenblatt angegeben) 
angeschlossen:
- Clock inhibit auf Low
- Clock auf Clockpin des Controllers (alle 4 Register parallel)
- Shift/Load auf entsprechendes Pin des Controllers (alle 4 Register 
parallel)
- Serialinput des 1. Registers auf Low
- Serialinput des 2. Registers geht auf SerialOut-Pin des 1. Reg.
- Serialinput des 3. Registers geht auf SerialOut-Pin des 2. Reg.
- Serialinput des 4. Registers geht auf SerialOut-Pin des 3. Reg.
- Serialoutput des 4. Registers geht auf Input des Controllers
- GND+VCC angeschlossen, Abblockkondensatoren 100nF

Hat jemand von euch vielleicht eine Idee woran die komische Verschiebung 
der eingelesenen Pins liegen könnte?

Vielen Dank für eure Mühe!

von Alex O. (Gast)


Angehängte Dateien:

Lesenswert?

Dateianhang hier...

von Thorsten (Gast)


Lesenswert?

kannste nen schaltplan reinstellen? aus text sich den zusammenzudenken 
ist bisschen umständlich

von Alex O. (Gast)


Angehängte Dateien:

Lesenswert?

so, jetzt hab' ich ihn fertig.
schaut nicht sehr professionell aus, ist nur schnell zusammengezaubert. 
Aber ich denke man sollte alles erkennen.
die Pins 3-6 + 11-14 sind die Eingänge die (für den Test) auf Low 
liegen, nur jeweils ein wurde auf High gelegt...

von crazy horse (Gast)


Lesenswert?

unabhängig von deinem Problem - warum schliesst du das nicht an die SPI 
an?

von Alex O. (Gast)


Lesenswert?

Die skizzierte Schaltung ist eigentlich nur ein Teil der Hardware. Ich 
versuche einen IO-Knoten zu entwickeln, der u.a. folgende Schnittstellen 
haben wird:
- 32 digitale Eingänge
- 32-64 digitale Ausgänge
- TWI-Schnittstelle für Temperatursensoren
- 8 Analoge Eingänge
- Can-Bus-Anbindung
- RS232-Interface
- ...
das alles in der maximalen Ausbaustufe, wenn ich das überhaupt auf dem 
Mega32 unterbringe (Software, Pins, Timing,...).

Ich baue Schaltung für Schaltung auf einem Steckbrett auf, entwickle die 
Software dazu und teste das ganze. Das mit den digitalen Ausgängen 
(74HCT595) klappt schon, bei den Eingängen hänge ich jetzt...

von rene (Gast)


Lesenswert?

Zum Anfangen. Die 74HC595 sind die bessere Wahl. Dann das erste SER darf 
nicht an GND sein, sond wird nichts, da muss ein Portpin her. Dann CLK 
parallel, SH/LD parallel, INH parallel. Dann an SER die Darten anlegen, 
32 mal clocken und Load.

Rene

von rene (Gast)


Lesenswert?

Oh. Ein lesen, sorry. Dann das 74HC597. Den letzten Ausgang an den 
PortPin. Sonst identisch. Man kann die Ausgaenge und die Eingaenge auch 
in Serie haben.

rene

von Kai (Gast)


Lesenswert?

kann man mit einem 74HC597 16 Sensorleitungen auf 8 ADC-Eingänge 
aufteilen, oder ist es wegen Spannungsverfälschungen nicht möglich?

von Alex O. (Gast)


Lesenswert?

@rene:
danke für den Tipp! Ich habe mir eben mal das Datenblatt für den 597 
angesehen. Mal abgesehen dass die Ansteuerung etwas anders ist, macht 
der im Prinzip ja das selbe wie der 165. Denkst du das das mit dem 597 
funktionieren würde?
Kann's leider nicht testen, habe keine da...

@Kai:
ich denke, ich verstehe nicht was du meinst. die Analogen Eingänge 
können auch als digitale Eingänge verwendet werden. In Kombination mit 
einem 74x597 sind allerdings nur digitale Signale zu verwenden. Um 
mehrere analoge Signale zu erfassen würde ich einen Analog Multiplexer 
verwenden. Ich habe mit denen allerdings auch noch nix gemacht...

von Peter D. (peda)


Lesenswert?

rene wrote:
> Oh. Ein lesen, sorry. Dann das 74HC597.

Nö, bleib mal beim 74HC165, der ist genau richtig.
Der 74HC597 braucht noch nen zusätzlichen Takt für das Eingangslatch.


@Alex,

bei der Schaltung kann man eigentlich nichts falschmachen.
Der Fehler wird wohl in Deiner Software liegen.


Peter


von Kai (Gast)


Lesenswert?

also digitale Eingänge habe ich genug, nur leider analoge vom ADC nicht.
Deswegen suche ich da eine Möglichkeit.
Kann da jemand was empfehlen? Vielen Dank

von crazy horse (Gast)


Lesenswert?

dafür gibts die Analog-Multiplexer (4051/52/53).
Wieviele Eingänge brauchst du denn? 4051 macht 8 Eingänge auf einen 
Ausgang.
Nimmst du davon 2 Stück, brauchst du 3 Steuereingänge vom MC zum 
Multiplexer und 2 Analogeingänge am MC -> 16 Analogeingänge an 5 
Portpins.

von Alex O. (Gast)


Angehängte Dateien:

Lesenswert?

@Peter:
ich fürchte du hast recht. Ich dachte nur an irgendwelche 
Ansteuerprobleme, die erst beim Kaskadieren auftreten, Störungen durch 
das Steckbrett,...
Da aber die Fehler immer reproduzierbar sind, wird's wohl doch irgendwo 
an der Software liegen.

ich poste mal meinen kompletten Code, vielleicht sieht jemand von euch 
wo das Problem liegen könnte.
Schnell zum Aufbau:
- Erster Teil Initialisierung (Timer, Ports, RS232)
- Hauptschleife
- beim Timerinterrupt
  - Schieberegister einlesen
  - Bytes im Ram speichern
  - anschliessend mit einer anderen Kopie im Ram vergleichen
  - wenn Änderung entdeckt, Flag setzen
  - neu gelesene Bytes im Ram ablegen
- wenn Flag gesetzt, wird aus Mainloop eine Sendeprozedur aufgerufen, 
die die Bytes per RS232 an PC sendet

Danke für eure Hilfe!
Alex

von Falk (Gast)


Lesenswert?

Hmm, das Datenblatt sagt

"Either the CP or the CE should be HIGH before the LOW-to-HIGH 
transition of PL to prevent shifting the data when PL is activated."

Du setzt aber CP auf LOW, bevor du den PL Pulse generierst.

MfG
Falk


von Falk (Gast)


Lesenswert?

Ausserdem generierst du nur 7 Schiebetakte pro Byte. Das reicht wenn nur 
1 Schieberegister dranhängt, schlägt aber fehlt bei 4.

Weiterhin ist dein Programmierstil noch verbesserungsfähig. Z.B.

in temp, SER_PIN
andi temp, (1<<SER_DS)  ;Maskiere den In-Pin
cpi temp, (1<<SER_DS)    ;ist der Eingangspin auf High?
brne BitNotSet_SR    ;nein, wie vermutet :-)

Die dritte Zeiel mit cpi kann entfallen, das andi setzt schon das Z-Flag

Ebenso ist deine Schleifenendeabfrage zu kompliziert, macht das Prgramm 
nur länger und unleserlich

  dec ByteZaehler
  cpi ByteZaehler, 0   ;Alle Bytes ausgegeben (mit '0' vergleichen)
  breq ExitLoop_SR    ;ja, wir können die Funktion verlassen
                ;es sind noch nicht alle Bytes eingelesen
  rjmp OuterLoop_ST

Sollte man sinnvollerweise so schreiben

  dec ByteZaehler
  brne OuterLoop_ST  ;es sind noch nicht alle Bytes eingelesen
                ;ja, wir können die Funktion verlassen

MfG
Falk

von Falk (Gast)


Lesenswert?

Aller guten Dinge sind drei. Auch bei Kritik. ;-)
Du solltest den Timer am Anfang des Interrupts neu laden.

out tcnt0,TSW               ;Timer0-Startwert setzen

Sollte gleich nach dem pushen der Register kommen. Denn wenn dein 
Interrupt (Bits schieben, vergleichen etc.) länger als 1024 Takte 
(Vorteiler) dauert, dann ist der Abstand der Timerinterrupts >10ms. Wenn 
der Timer auch noch für ne Uhr oder ähnliches benutzt wird, kommt es 
dann zu Abweichungen.

MfG
Falk

von Alex O. (Gast)


Lesenswert?

@Falk:
danke für deine guten Tipps! habe eben das Programm etwas umgestellt und 
jetzt gehts! Das Problem lag eindeutig an den 7 Schiebetakten, nachdem 
ich die Schleife etwas umgestellt hatte ging's!

Das mit dem ersten Tipp ("Either the CP or the CE should be HIGH before 
the LOW-to-HIGH transition of PL to prevent shifting the data when PL is 
activated") habe ich auch umgesetzt.

Du hast mit deiner Kritik betreffend meinem Programmierstil absolut 
Recht: ist noch etwas holperig, ich habe erst vor einigen Wochen mit dem 
Assembler-Programmieren begonnen. Da gibts noch Verbesserungspotential

Danke nochmal für die Hilfe!

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.