Forum: Compiler & IDEs AVR Hilfe bei Schieberegister


von N. B. (saint1234)


Lesenswert?

Hallo liebe Community,

ich bin relativ neu dabei in der Digitaltechnik, habe jedoch bereits 
erste Erfolge mit meiner eigenen "binähr Uhr" gemacht. Doch nun wollte 
ich etwas weitermachen und mir eine art "coffee table" mit audio 
spectrum analyzer bauen. Dazu wollte ich nun also eine min. 5x5 
LED-Matrix bauen, die ich gerne mit Schieberegistern bewältigen würde. 
Ich habe mir bereits das Tutorial dazu durchgelesen, bin jedoch leider 
nicht Assembler bewandert sondern nur c und c++. Kann mir irgend jemand 
grundlegend erklären wie ich in c eine Datenübergabe an ein 
Schieberegister durchführen kann. Mir ist vorallem wichtig zu wissen, ob 
ich Bit für Bit über den Bus schieben MUSS oder direkt ein Byte 
übergeben kann. Zudem das Pulsen des SCK-Pins ist mir noch nicht ganz 
klar. Mache ich dies über eine Interrupt Routine, oder gibt es 
einfachere Möglichkeiten?

Zusammengefasst: Ich bräuchte nur einen Anregung zur 
Softwareimplementierung eines Schieberegisters.

Vielen Dank im Voraus!

von Hannes (Gast)


Lesenswert?


von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Weniger kryptisch und Assembler-lastig geht's hier zu:

http://www.rn-wissen.de/index.php/Portexpander_am_AVR

Dort stehen Lösungen in C für reine Software-Ansteuerung sowie für 
Hardware-Ansteuerung mit Unterstützung des SPI-Moduls.

von N. B. (saint1234)


Lesenswert?

Hey vielen Dank erstmal an Euch!!

Hannes:
ja damit hab ichs auch zuerst versucht und zumindets grundlegend 
verstanden worum es ging, jedoch war es halt zu assemblerlastig.

Johann:

Danke dir, hat mich schon deutlich weitergebracht!

So wie ich das also sehe ist es möglich ein byte pro Takt zu senden, und 
wenn ich den RCK Pin(Latchseitig) auf VCC lege spare ich mir den 
Ausgabeimpuls oder? jedoch steht leider nur eine "pseudoausgabe" in den 
Beispielen. Kannst du eventuell mir einen kleinen Einblick geben mit der 
Implementierung realler Befehle. Heißt: Register setzen und eventuell 
einmal 8 bit weiterreichen?

Konkret in meinem Beispiel, müsste ich nach einlesen der Frequenz einen 
LED-Bar meiner LED Matrix mit Spannung versorgen, heißt QA auf 1 setzen 
und den Rest 0.

Nur damit Ihr wisst wozu ich frage ;)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nico Bochmann schrieb:

> So wie ich das also sehe ist es möglich ein byte pro Takt zu senden,

Ein Byte pro Schleifendurchlauf in der HW-Version.

> und wenn ich den RCK Pin(Latchseitig) auf VCC lege spare ich mir den
> Ausgabeimpuls oder?

Soweit hab ich das Datenblatt der *595 nicht intus, AFAIK arbeiten die 
Latches flankengetriggert, nicht pulsgetriggert.

Bevor du eine Schaltung machst auf dem Steckbrett testen, und auch die 
SPI-Konfirguration (SPE, MSTR, CPOL, etc) an den µC anpassen, also 
Datenblätter lesen.

> jedoch steht leider nur eine "pseudoausgabe" in den Beispielen.
> Kannst du eventuell mir einen kleinen Einblick geben mit der
> Implementierung realler Befehle.

Ist ein Pin FOO zum Beispiel an PortB.5 angeschlossen, dann ist

MAKE_OUT (FOO) -->  DDRB  |= 1 << PB5;
SET (FOO)      -->  PORTB |= 1 << PB5;
CLR (FOO)      -->  PORTB &= ~(1 << PB5);


> einmal 8 bit weiterreichen?
>
> Konkret in meinem Beispiel, müsste ich nach einlesen der Frequenz einen
> LED-Bar meiner LED Matrix mit Spannung versorgen, heißt QA auf 1 setzen
> und den Rest 0.

In dem Fall ist SERPA_SIZE auf 1 zu setzen, d.h. es ist nur 1 
Seriell-Parallel-Expander angeschlossen.

Das Hauptprogramm sieht dann in etwa so aus:
 
1
#include "serpa.h"
2
3
int main (void)
4
{
5
    ...
6
    serpa_init();
7
    ...
8
9
    while (1) // main-Loop
10
    {
11
        ...
12
        serpa[0] = 1;
13
        serpa_out();
14
        ...
15
    }
16
}

Wenn man die Ausgabe gern in einer ISR macht, sind noch kleine 
Anpassungen nötig wie volatile für serpa[] und atomares Ändern 
desselben.

Ein extra SPI-ISR ist m.M. nicht praktikabel, da die IRQ-Latenz bereits 
größer ist als die Übertragungsdauer für 1 oder 2 Bytes bei der 
HW-Version.

von Karl H. (kbuchegg)


Lesenswert?

> So wie ich das also sehe ist es möglich ein byte pro Takt zu senden,
> und wenn ich den RCK Pin(Latchseitig) auf VCC lege spare ich mir
> den Ausgabeimpuls oder?

Jetzt mal unabhängig von der Fragestellung: flankengetriggert oder 
pegelgetriggert.

Genau das will man ja nicht haben!
Der Zweck der Ausgabeimpulses ist es ja gerade, dass man in die 
Schieberegisterkette nacheinander etwas reintakten kann, OHNE das sich 
das zunächst an den Ausgabepins bemerkbar macht. Du würdest ja sonst auf 
den Ausgabepins jeden Zwischenzustand während des reinschiebens sehen 
und genau das gilt es doch zu vermeiden. Wenn ich den Pin 5 von Low auf 
High wechseln lassen will und alle anderen sollen Low bleiben, dann 
möchte ich nicht haben, dass auf den restlichen Pins kurzzeitig ein High 
auftaucht, weil ich dieses eine High ja nur sukzessive durchschieben 
kann, bis es an der richtigen Position angelangt ist.


> ja damit hab ichs auch zuerst versucht und zumindets grundlegend
> verstanden worum es ging, jedoch war es halt zu assemblerlastig.

Und ich dachte, ich hätte die Funktion und Arbeitsweise des 595 im 
Vorgeplänkel ausreichend gut beschrieben :-(
Das ist doch nur ein bischen geordnetes Pinwackeln. Jeder der 2 LED 
hintereinander in der richtigen Reihenfolge ein/ausschalten kann, sollte 
das doch eigentlich hinkriegen, wenn er verstanden hat wie die 
Reihenfolge sein muss.

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.