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
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.
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
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..
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
>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)...
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?
>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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.