Forum: Compiler & IDEs 12 Bit Felder seriell ausgeben


von PulsWelle (Gast)


Lesenswert?

Hallo,
Ich habe ein 16-Bit Array mit 24 Elementen. Die Elemente nutzen aber nur 
12 Bit und nur diese 12 Bit sollen auch seriell ausgegeben werden.
Wie stelle ich das am besten an?
Prozessor ist ein ATMega8. Soll ich die SPI SChnittstelle nutzen?

Oder einfach nen Timer nehmen und damit die Daten rausknüppeln und nur 
Bit 0-11 aus jedem Arrayelement lesen?

Oder gibt es eine Möglichkeit ein Array mit 12 Bit breiten Elementen zu 
erzeugen?


MfG

PW

von Klugscheisser (Gast)


Lesenswert?

Mehr Information über Sinn und Zweck der Anwendung und Randbedingungen 
wäre sinnvoll.

>Soll ich die SPI SChnittstelle nutzen?
Du kannst diese oder auch jede andere Schnittstelle benutzen.


>der einfach nen Timer nehmen und damit die Daten rausknüppeln und nur
>Bit 0-11 aus jedem Arrayelement lesen?
Das geht, hat aber nichts mit der Schnittstelle zu tun. Warum das "Oder" 
am Satzanfang?

>Oder gibt es eine Möglichkeit ein Array mit 12 Bit breiten Elementen zu
>erzeugen?
Eigentlich nicht.
Das hat aber weder was mit der Schnittstelle noch mit einem Timer zu 
tun.

Zunächst mal, würde ich die Schnittstelle nach der Art der Gegenstelle 
wählen.

Die meisten Schnittstellen arbeiten mit 8 Bit breiten Worten. Wenn die 
Geschwindigkeit an sich nicht entscheidend ist, würde ich pro 12Bit Wort 
zwei 8Bit Worte übertragen und im Empfänger eben die oben 4 Bit 
ignorieren.

Also. Bitte mehr Infos.

von Wolfgang M. (womai)


Lesenswert?

Ich nehme mal an, Du willst alle Arrayelemente auf einmal ausgeben. Dann 
kannst Du einfach je zwei Elemente in drei Bytes packen und diese dann 
normal mit den Standard-Routinen fuer serielle Schnittstelle (RS-232) 
oder SPI-Schnittstelle ausgeben. Also

aaaaaaaa aaaabbbb bbbbbbbb

wobei "a" die Bits des ersten Wertes sind und "b" die Bits des zweiten 
Wertes.

unsigned int data[24]; // 16-bit-Variablen
char i;
char byte1, byte2, byte3;

for (i = 0; i < 24; i += 2)
{
byte1 = data[i] >> 4;
byte2 = ((data[i] & 0x0f) << 4) | (data[i+1] >> 8);
byte3 = data[i+1] & 0x00ff;

sende byte1, byte2 und byte3 ueber RS-232 oder SPI
}


Der Empfaenger klaubt sich die Werte dann wieder auseinander. (die 
Programmierung ist dem Leser als Uebung ueberlassen :-)

Wolfgang

von PulsWelle (Gast)


Lesenswert?

Mehr Infos kommen...

Ich möchte einen tlc5947 PWM Led Treiber füttern. Dieser hat einen 
seriell zu füllenden Eingangslatch. Es können 24 LEDs mit je 12 Bit 
Genauigkeit angesteuert werden.
In meinem Programm halte ich die Helligkeit für jede LED in einem 16Bit 
Feld. Somit dürfen bei der Ausgabe die 4 hochwertigsten Bits nicht mit 
ausgegeben werden.


Der Vorschlag von Wolfgang ist schon ganz gut. Nur ich dachte es geht 
noch performanter...

Das vorgehen ist also folgendes:

Auszugebenden Datensatz im Main Programm erzeugen (zB noch Wolfgangs 
Methode). Dann ein Flag setzen welches im Timerinterrupt gelesen wird. 
Dort die Daten raussenden und das Flag zurücksetzen bis zur nächsten 
Datenübertragung.

Ist das so empfehlenswert?

MfG

PS: Meine Idee mit der SPI Schnittstelle war dass diese Vorteile haben 
könnte als wenn ich die Daten über einen normalen Port raussende. 
Beispielsweise so wie Hardware PWM einen Prozessor weniger belastet als 
Software PWM..

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sind die Latches denn kaskadiert?

Falls nicht, kannst du doch einfach 16 Bits rausschicken per SPI und die 
4 überflüssigen fallen hinten raus...who cares..

Johann

von Matthias L. (Gast)


Lesenswert?

>PS: Meine Idee mit der SPI Schnittstelle war dass diese Vorteile haben
>könnte als wenn ich die Daten über einen normalen Port raussende.
>Beispielsweise so wie Hardware PWM einen Prozessor weniger belastet als
>Software PWM..

Ich würde die HArdware SPI nehmen. Bau das einfach beim Senden zusammen. 
Da das genau vier Bits sind, schiebt der Compiler noch nicht mal 
(swap)...

von PulsWelle (Gast)


Lesenswert?

Ja die Latches sind kaskadiert - sprich ich schiebe die Daten 
hintereinander da rein. Da wuerde vier 0 mitten drin schon stören ;-)

Hardware SPI und Daten im Interrupt zusammenbauen? Spricht das nicht 
gegen das Prinzip in Interrupts möglichst wenig "rechenaufwaendiges" zu 
machen?

von Matthias L. (Gast)


Lesenswert?

>Hardware SPI und Daten im Interrupt zusammenbauen? Spricht das nicht
>gegen das Prinzip in Interrupts möglichst wenig "rechenaufwaendiges" zu
>machen?

Sie es mal so, wenn du mit 8MHz SPI-Takt arbeitest, ist es Unsinn, den 
SPI-Interrupt zu verwenden:
Das Senden eines Bytes dauert 1µs. Also acht ASM-Befehle. Und die 
brauchst du auch etwa um das Nächste zu holen...

>ein 16-Bit Array mit 24 Elementen

Also schiebst du 24*1,5 = 36Bytes raus..

Die Zeit, während eines gesendet wird, kannst du nutzen, um das Nächste 
zusammenzubauen. Du brauchst nicht mal das SPIF-Flag mehr abfragen..
Etwa so:
1
_u8Temp = (uint8_t) u16Value[0];
2
SPDR    = _u8Temp;
3
4
_u8Temp = ...
5
SPDR    = _u8Temp;

Ich schätze, diese gesamte Senderoutine wird etwa 50µs brauchen..

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.