Frage zu "shiftOut()" Befehl

Programmierung und Hardwaredesign mit Arduino, AVR, PIC und Konsorten.

Moderatoren: MaxZ, ebastler, SeriousD

Antworten
Benutzeravatar

Thread-Ersteller
L_B_S
Beiträge: 531
Registriert: Fr 24. Jul 2015, 10:13
Schule/Uni/Arbeit: KFZ-Elktr.
Hat sich bedankt: 19 Mal
Danksagung erhalten: 23 Mal

Frage zu "shiftOut()" Befehl

Beitrag von L_B_S »

Hallo zusammen,

In einer Arduino-Referenz (nicht die Orginal-) wird dazu das beschrieben:
shiftOut()
Beschreibung
Gibt ein Bit einer Bytevariablen an einem Port aus.
Beginnt entweder von links (Most Significant Bit) oder
von rechts (Least Significant Bit). Jedes Bit wird auf
einen Data-Pin geschrieben, nachdem ein Clock-Pin getaktet
wurde (auf high setzen, dann wieder auf low), welches anzeigt,
dass das Bit verfügbar ist. Es kann immer nur ein Bit auf
einmal ausgegeben werden. Sollen also alle acht Bits eines
Bytes geändert werden, ist dieser Befehl acht Mal auszuführen
.


ich will ja kein Bit dieses Byte's ändern , nur seriell ausgeben, etwas missverständlich :|

ein Codeschnipsel:

Code: Alles auswählen

......
// LSBFIRST serial 
data = 500;
shiftOut(dataPin, clock, LSBFIRST, data);          // shift out lowbyte 
shiftOut(dataPin, clock, LSBFIRST, (data >> 8));   // shift out highbyte 
......
hier wird "shiftOut()" doch nur einmal ausgefürt. Wird hier data (ist ein Int-Wert) LOW-Byte zuerst und dann HIGH-Byte
automatisch Bit für Bit seriell ausgegeben oder muss man den in eine (8x) Schleife packen ?
Das soll ein Anschluss an ein MAX7219- 8 x 7-Segment-Platine werden. Da gibt es natürlich einige Lib's aber diese funktionieren nicht korrekt.
Also will ich das mal über shiftOut probieren.

Gruss
Ludwig
Benutzeravatar

gamerpaddy
Beiträge: 2624
Registriert: Mo 13. Aug 2012, 09:03
Spezialgebiet: Spezialgebiet
Schule/Uni/Arbeit: Schule/Uni/Arbeit
Wohnort: Mannheim
Hat sich bedankt: 33 Mal
Danksagung erhalten: 303 Mal
Kontaktdaten:

Re: Frage zu "shiftOut()" Befehl

Beitrag von gamerpaddy »

Der shiftet alle Bits von data aus und gleichzeitig den clock dazu. Du musst es nicht 8x ausführen.


So sieht zb. 0 bis 6 aus im logicanalyzer:
LSB First
Logic_JSvaUAPyym.png
MSB First
Logic_u38sH1c037.png
die Periode Clocksignals ist dabei 11µS, ebenso die breite jedes datenbit.


Testcode für mein beispiel:

Code: Alles auswählen

void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT); //CLOCK
  pinMode(12,OUTPUT); //DATA
  delay(1000);
}
byte t = 0;
void loop() {
  
  shiftOut(12, 13, LSBFIRST, t);
  
  t = t +1;
  if(t>255){t=0;}
  delayMicroseconds(100);
}
Die 8 bits vorshiften von data macht man nur, wenn man eine variable hat die mehr als ein byte groß ist.
Ein int würde man in etwa so senden.

Code: Alles auswählen

  t = -21302 // 1010110011001010
  shiftOut(12, 13, LSBFIRST, t);
  shiftOut(12, 13, LSBFIRST, (t>>8));
Logic_sux8sS1Qe3.png
Logic_sux8sS1Qe3.png (8.52 KiB) 1534 mal betrachtet

Die geschwindigkeit ist wohl fix und wird von digitalWrite gebremst. die eigentliche funktion sieht in der arduino library so aus:

Code: Alles auswählen

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val)
{
     int i;

     for (i = 0; i < 8; i++)  {
           if (bitOrder == LSBFIRST)
                 digitalWrite(dataPin, !!(val & (1 << i)));
           else      
                 digitalWrite(dataPin, !!(val & (1 << (7 - i))));
                 
           digitalWrite(clockPin, HIGH);
           digitalWrite(clockPin, LOW);            
     }
}



"MD_MAX72XX" library hat bei mir damals glaube ich gut funktioniert. andere libraries waren um 90° gedreht und ließen sich nicht auf das modul welches ich hatte konfigurieren.
Unter "HARDWARE_TYPE" das richtige eintragen. Bei meinen modulen war es

Code: Alles auswählen

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
Und natürlich die #define MAX_DEVICES 4 anpassen sonst versucht der auf 11 modulen zu malen..
IMG_20210112_154836.jpg
:wurst:
Benutzeravatar

Thread-Ersteller
L_B_S
Beiträge: 531
Registriert: Fr 24. Jul 2015, 10:13
Schule/Uni/Arbeit: KFZ-Elktr.
Hat sich bedankt: 19 Mal
Danksagung erhalten: 23 Mal

Re: Frage zu "shiftOut()" Befehl

Beitrag von L_B_S »

Dank erst einmal,

so sieht das Serial-Data Format des MAX7219 aus:
Serial-Data Format.png
Serial-Data Format.png (2.77 KiB) 1517 mal betrachtet
wenn ich jetzt z.B. die Helligket aller Segmente ändern will, müsste ich dann das
Intensity Register Format (Address (Hex) = XA)
Register.png
Register.png (5.71 KiB) 1517 mal betrachtet
und...
Intensity Register.png
Intensity Register.png (8.6 KiB) 1517 mal betrachtet
...also müsste der Code doch so aussehen:

Code: Alles auswählen

data = 0xA0F  // (Binär = "00001010 00001111") = größte Helligkeit
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));  // shift out highbyte
shiftOut(dataPin, clock, MSBFIRST, data);         // shift out lowbyte
...um auf grösste Helligkeit zu schalten, Ist das richtig ?
Benutzeravatar

Thread-Ersteller
L_B_S
Beiträge: 531
Registriert: Fr 24. Jul 2015, 10:13
Schule/Uni/Arbeit: KFZ-Elktr.
Hat sich bedankt: 19 Mal
Danksagung erhalten: 23 Mal

Re: Frage zu "shiftOut()" Befehl

Beitrag von L_B_S »

....da ich nur 7-Seg-Anzeigen steuern will, kann ich mir ne Menge Code sparen wenn ich die

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val)

direkt verwende, schnell genug ist die allemal
Benutzeravatar

gamerpaddy
Beiträge: 2624
Registriert: Mo 13. Aug 2012, 09:03
Spezialgebiet: Spezialgebiet
Schule/Uni/Arbeit: Schule/Uni/Arbeit
Wohnort: Mannheim
Hat sich bedankt: 33 Mal
Danksagung erhalten: 303 Mal
Kontaktdaten:

Re: Frage zu "shiftOut()" Befehl

Beitrag von gamerpaddy »

Sollte eigentlich funktionieren.
0xA0F ist Volle helligkeit
laut Logicanalyzer kommen die daten korrekt raus, CS danach high damit die daten geladen werden.
0000 1010 0000 1111
Logic_wQ8k9N29UN.png
Nur ist mein Board nicht so kooperativ wie ich das erwarte^^ das macht und tut was es will, aber nich was ich dem sage^^...
:wurst:
Antworten