Forum: Mikrocontroller und Digitale Elektronik Schieberegister 74HC595 ansteuern


von Ulrich (Gast)


Lesenswert?

Hallo,
Ich habe einen Atmega32 den ich per Assembler programmiere (bzw.
programmieren will ;-)

Zur steuerung von ein paar L298 habe ich mir gedacht da sind 2
Schieberegister hintereinander perfekt.

Ich habe die schieberegister ungefähr nach dieser Anleitung
Zusammengelötet
http://www.mikrocontroller.net/wiki/Bild:Hc595-porterweiterung.png

Nun weiß ich allerding nicht wie ich sie ansteuern soll.

Nach dem ich es nicht direkt hinbekommen habe, habe ich mal diesen Code
testweise ausprobiert:
ldi temp, 0b00000000
  out PORTC, temp
  inc temp
  out PORTC, temp
  inc temp
  out PORTC, temp
  .
  .
  12 mal noch hoch 10 mal noch runter
  .
  .
  dec temp
  out PORTC, temp
  dec temp
  out PORTC, temp
  dec temp

Das Ergebnis ist die Erkenntnis das die Schieberegister im Prinzip
funktionieren.

Ich habe es auch schonaml probiert das ding gezielt anzusprechen aber
ich habe kein Erfolg, und da ich nicht sicher war mit den flanken habe
ich auch alles Probiert ;-(

könnt ihr mir vielleicht ein beipiel Code geben?

oder der Ablauf wie die Bits gesetzt werden müssen?

Ich denke auf SER liegen immer die zum reintakten gedachten Daten
Mit SCK wird getaktet (low ==> high oder high ==> low ?)
und mit RCK wird der Inhalt an die Ausgänge durchgeschalten low ==>
high oder high ==> low ?

Dann noch eine andere Frage angenommen ich will ein Byte raustakten
welches ich in einem schieberegister habe, wie lese ich dann immer ein
Bit aus dem Byte? Ich weiß schon das man mit ROR ein Byte rotieren
kann, aber wie ich dann ns 1. bit komme weiß ich noch nicht

MFG
Ulrich

: Bearbeitet durch Admin
von Mark Hämmerling (Gast)


Lesenswert?

Salve,

Du hast den dazugehörigen Artikel im Wiki aber auch gelesen, oder?
http://www.mikrocontroller.net/wiki/Porterweiterung_mit_SPI

Schau mal ins Datenblatt vom ATmega32, Stichwort: SPI. Das Verhalten
ist "kompatibel" zu den Shiftregistern. Leitungen verbinden, SPI
initialisieren, SPDR schreiben - fertig.

Was genau Dein Codeschnipsel machen soll, ist mir leider nicht klar...
Werte von 0 bis irgendwas aufwärts und dann wieder abwärts an PORTC
ausgeben. Wo besteht da der Zusammenhang zu dem Shiftregister?

Wie ein Shiftreg. funktioniert, hast Du doch verstanden. Dann schalte
doch die Leitungen einfach mal entsprechend (Datenbit an MOSI,
Taktzyklus auf SCK, nach 16 Bits Taktzyklus auf RCK) - bzw. laß es über
das interne SPI laufen.

Zur letzten Frage: Datenbit vom letzten QH* an MISO, reintakten,
Carrybit entsprechend Bit an MISO setzen, ROL/ROR (je nach bitorder) -
oder auch hier: SPI nehmen. Das taktet Dir die Daten automatisch ins
SPDR (getrennte Register für Schreib-/Lesevorgänge - laß Dich da nicht
verwirren).

Viel Erfolg,
Mark

von Ulrich (Gast)


Lesenswert?

Ich will es ja nicht über ds SPI Interface machen. Ich habe die 3
Leitungen zum Schieberegister an PortC angeschlossen und weil überhaupt
nichts funktionierte, habe ich mit dem geposteten code irgendwelche
werte in das schieberegister reingetaktet.

Ich würde mich freuen wenn mir jemand einen funktionierenden
Codeschnipsel geben könnte welches ganz gezielt 1 Byte ins
schieberegister reintaktet. Bei mir funktioniert es einfach nicht

von Felix (Gast)


Lesenswert?

Hallo Ulrich
Hier ist mein Assembler-Code mit dem ich die HC595 ansteuer. Dabei
können die an jeden x-beliebigen Port angeschlossen sein.

;  serielle daten an pind 4
;  seriell-clock an pind 5
;  shift-reg-clock an pind 6


.include "d:\avr\2313def.inc"


.def temp1=r16
.def temp2=r17
.def temp3=r18
.def byte=r19

.equ speicher_0 = 0x060
.equ speicher_1 = 0x061

reset:
  ldi temp1, 0
  ldi temp2, 0

  ldi temp1, ramend       :stack einrichten
  out spl, temp1

  ldi temp1, 0b01110000
  out ddrd, temp1

  ldi temp1, 0xFF    ;testweise
  sts speicher_0, temp1
  ldi temp1, 0x01    ;testweise
  sts speicher_1, temp1

main:
  rcall serial_out

  rjmp main


serial_out:
  cbi portd, 6

  lds byte, speicher_0    ;daten aus dem speicher_0 holen
  rcall serial_out_start
  lds byte, speicher_1    ;daten aus dem speicher_1 holen

  sbi portd, 6      ;daten übernehmen
  cbi portd, 6

ret



  serial_out_start:    ;gibt das aktuelle byte seriell aus
    rol byte
    rol byte    ;msb zuerst

    ldi temp3, 8

    serial_out1:
    mov temp1, byte
    sbrs temp1, 0
    rjmp serial_out11
    sbi portd, 4

    serial_out11:
    sbi portd, 5
    cbi portd, 5

    rol byte
    cbi portd, 4

    dec temp3
    brne serial_out1
  ret

Wenn noch Fragen sind, dann schreib einfach

Gruß Felix

von Ulrich (Gast)


Lesenswert?

Gerade eben habe ich es selbst hinbekommen, der Fehler war:
-verbindung zwischen 2 Pins

sonstige Fehler:
-Kaputter Ausgang des MC
-Pins vertauscht

Hier mein Programm mit dem ers gerade ging:

.equ  SPORT = PORTC
.equ  SER = 0
.equ  SCK = 2
.equ  RCK = 5

  ldi temp, 0xF0
  ldi temp2, 8

  cbi SPORT, SCK
  cbi SPORT, RCK

  loop_01:

  cbi SPORT, SER
  sbrc temp, 0
  sbi SPORT, SER
  lsr temp  ; Byte nach rechts schieben
  sbi SPORT, SCK
  cbi SPORT, SCK

  dec temp2
  cpi temp2, 0     ; Byte mit '0' vergleichen
        brne loop_01


  sbi SPORT, RCK
  cbi SPORT, RCK
  cbi SPORT, SER

Das ist nur für ein Byte, ich werde es wie du geschon programmiert hast
auf 2 Bytes erweitern und im ram speichern... ich poste nacher nomal das
komplette UP wie ich es dann verwende
Danke für die Hilfe ;-)

von Ulrich (Gast)


Lesenswert?

so und hier auch für andere Leute die was suchen (Verbesserungsvrschläge
bitte mitteilen)

schieberegister:

  push temp  ; in den Stack legen
  push temp1  ; in den Stack legen
  push temp2  ; in den Stack legen

  ldi temp, 16  ;zaehler verwenden

    lds temp1, SREGISTERBYTE_0  ; Daten aus dem SREGISTERBYTE_0 holen
  lds temp2, SREGISTERBYTE_1  ; Daten aus dem SREGISTERBYTE_1 holen


    loop_01:

    cbi SPORT, SER  ; SER auf 0 setzen
  sbrc temp2, 0  ; Abfrage rechtes Bit=1
  sbi SPORT, SER  ; dann setze SER
  lsr temp1  ; Linkes Byte nach rechts schieben ins Carry
  ror temp2  ; Carry in unteres Byte und dabei rollen

    sbi SPORT, SCK ; weiter takten
  cbi SPORT, SCK ;

  dec temp
  cpi temp, 0     ; Byte mit '0' vergleichen
        brne loop_01

  sbi SPORT, RCK  ; Ausgänge 595 durchschalten
  cbi SPORT, RCK  ; RCK auf 0 setzen

  cbi SPORT, SER  ; SER auf 0 setzen


  pop temp2  ; aus dem Stack holen
  pop temp1  ; aus dem Stack holen
  pop temp  ; aus dem Stack holen

  cbi PORTA, 2  ; Nur für Anzeige Ob daten versendet wurden.....

  reti

aktuell sind es 258 Takte die diese UP benötigt. Bei 8 MHz sind dies
0,03ms. Geht das noch schneller? (Natürlich außer SPI Interface) Wenn
noch jemand vorschläge hat bitte posten...

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.