Forum: Mikrocontroller und Digitale Elektronik SPI mit 16Bit


von Shift (Gast)


Lesenswert?

Hallo!

Wollte mich mal erkundigen, wie das so läuft..

Ich habe eine 16Bit Variabel, die ich gerne über die serielle 
Schnittstelle rausgeben möchte. Es handelt sich um einen ATMEGA16, die 
SPI Initalisierung etc. ist kein Problem (steht ja deutlich im DB).

Also wenn ich das jetzt mal als Code annehme:
1
   
2
   uint16_t cData = 0b0010000011110011
3
   SPDR = cData;
4
   /* Wait for transmission complete */
5
   while(!(SPSR & (1<<SPIF)));

Wird dann die GANZE Variabel so in einem Rutsch rausgeschoben?
Also auch die Nullen am Anfang oder werden die Quasi "ausgeblendet"?

Ich hoffe ich habe mich verständlich genug ausgedrückt, ansonsten 
einfach nachfragen!

von Timmo H. (masterfx)


Lesenswert?

Shift schrieb:
> Wird dann die GANZE Variabel so in einem Rutsch rausgeschoben?
Natürlich nicht, SPDR ist nur 8-Bit breit. Und auch nur die untersten 
8-Bit werden dann gesendet.

von Falk B. (falk)


Lesenswert?

@  Shift (Gast)

>Wird dann die GANZE Variabel so in einem Rutsch rausgeschoben?

Nein. Das muss du manuell machen. Zerlege die 16 Bit Zahl in zwei 8 Bit 
Zahlen und übertrage diese nacheinander. Siehe Bitmanipulation.

von Shift (Gast)


Lesenswert?

Hm, Schade.
Naja, so viel Aufwand ist das wohl auch nicht..

Ist es üblich für ATMEGAs "nur" einen 8Bit SPI zu haben?
Oder gibt es auch grössere?

Gruss

von Matthias L. (Gast)


Lesenswert?

1
SPDR = cData;
SPDR ist ein 8bit Register. Also gehen dort auch nur (die untersten) 
acht Bit rein.

Wenn, dann muss du das so machen:
1
#define PORT_CS  PORTA
2
#define P_CS     PA6
3
4
  uint16_t cData = 0b0010000011110011
5
  ..
6
7
  PORT_CS &= ~(1<<P_CS);
8
  SPDR = (uint8_t) (cData>>8);
9
  /* Wait for transmission complete */
10
  while(!(SPSR & (1<<SPIF)));
11
  SPDR = (uint8_t) (cData);
12
  /* Wait for transmission complete */
13
  while(!(SPSR & (1<<SPIF)));
14
  PORT_CS |=  (1<<P_CS);

Die Defines sind nur ein Beispiel...

von Falk B. (falk)


Lesenswert?

Selbst fette 32 Bit Prozessoren haben praktisch alle nur 8 Bit SPI 
Register. Ein Vielfaches davon muss man per Software zusammenbauen, 
bestenfalls macht das die DMA auf größeren Prozessoren.

von Shift (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> Matthias Lipinsky

Vielen Dank für dein Beispiel!

Falk Brunner schrieb:
> Selbst fette 32 Bit Prozessoren haben praktisch alle nur 8 Bit SPI
> Register.

Ah oke, das wusste ich nicht.

Danke für eure raschen Antworten!


Wenn ich das richtig verstanden habe, dann schiebt der SPI bei einer 8 
Bit Variabel (z.B. 0b10010011) zuerst das MSB also 0 raus?

von amateur (Gast)


Lesenswert?

>Selbst fette 32 Bit Prozessoren ...

Im Grunde ist es eine Vereinbarung, wie viele Bytes Du nach dem Hallo 
schickst. Oder anders ausgedrückt: Sender und Empfänger müssen wissen 
was Sache ist.

Schau Dir mal die Kommunikation mit einem Speicherbaustein an:
[Hallo]+[Adresse-Low]+[Adresse-High]+[Daten] letzteres ev. mehrfach.

von spess53 (Gast)


Lesenswert?

Hi

>Wenn ich das richtig verstanden habe, dann schiebt der SPI bei einer 8
>Bit Variabel (z.B. 0b10010011) zuerst das MSB also 0 raus?

Nö. Kommt darauf an, was du mit DORD in SPCR eingestellt hast.

MfG Spess

von Shift (Gast)


Lesenswert?

spess53 schrieb:
> Nö. Kommt darauf an, was du mit DORD in SPCR eingestellt hast.

Danke für die Bezeichnung, das spart immer Zeit beim Suchen :)

"In all the examples shown here the SPI is configured to run in mode 0 
with MSB transmitted first.
This is done by setting the bits CPOL, CPHA and DORD in the register 
SPCR to zero."

von Shift (Gast)


Lesenswert?

Und wenn ich nochmals kurz was fragen dürfte.. (Hat auch mit 
Bitoperatoren zu tun)..

Wenn ich ein Array habe:

uint8_t array[8] = {0, 1, 1, 0, 1, 0, 1, 0,};
uint8_t zusammengefasst;


zusammengefasst = (array[0] << 7) |(array[1] << 6) |(array[2] << 5) 
etc..

Wird dann "zusammengefasst" den Inhalt 0b01101010 haben?

Gruss

von Toggle (Gast)


Lesenswert?

Shift schrieb:
> Wird dann "zusammengefasst" den Inhalt 0b01101010 haben?

Schreib's einfach in dein Programm rein und guck dir im Simulator an, 
was passiert.

von amateur (Gast)


Lesenswert?

uint8_t array[8] = {0, 1, 1, 0, 1, 0, 1, 0,};
uint8_t zusammengefasst;

Bilderbucharithmetik:
(array[0] << 7) = 0b00000000
(array[1] << 6) = 0b01000000
(array[2] << 5) = 0b00100000
(array[3] << 4) = 0b00000000
(array[4] << 3) = 0b00001000
(array[5] << 2) = 0b00000000
(array[6] << 1) = 0b00000010
(array[7] << 0) = 0b00000000
oder              0b01101010 oder so

von Shift (Gast)


Lesenswert?

amateur schrieb:
> Bilderbucharithmetik:
> (array[0] << 7) = 0b00000000
> (array[1] << 6) = 0b01000000
> (array[2] << 5) = 0b00100000
> (array[3] << 4) = 0b00000000
> (array[4] << 3) = 0b00001000
> (array[5] << 2) = 0b00000000
> (array[6] << 1) = 0b00000010
> (array[7] << 0) = 0b00000000
> oder              0b01101010

Dankeschön, hatte das auch so überlegt, war mir aber nicht ganz sicher 
ob das dann auch stimmt.

Toggle schrieb:
> Schreib's einfach in dein Programm rein und guck dir im Simulator an,
> was passiert.

Ich habe leider keine Ahnung, wie man Variabeln überwacht :S

von Falk B. (falk)


Lesenswert?

@  Shift (Gast)

>Ich habe leider keine Ahnung, wie man Variabeln überwacht :S

Dann solltest du das Lernen. Das WATCH Fenster ist dein Freund.

von Shift (Gast)


Lesenswert?

Falk Brunner schrieb:
> Dann solltest du das Lernen. Das WATCH Fenster ist dein Freund.

Ja, das habe ich schon gesehen, aber ich krieg' da irgendwie keine 
Variabel rein?

von Falk B. (falk)


Lesenswert?

Rechte Maustaste, Add Item, Namen eintragen

von Shift (Gast)


Angehängte Dateien:

Lesenswert?

Falk Brunner schrieb:
> Rechte Maustaste, Add Item, Namen eintragen

Das habe ich natürlich schon versucht :)

Allerdings tut sich da bei mir nix..
Abgesehen davon heisst es bei mir Add Watch aber ich denke das läuft 
aufs gleiche raus..

Gruss

von Tobias K. (kurzschluss81)


Lesenswert?

Falk Brunner schrieb:
> Selbst fette 32 Bit Prozessoren haben praktisch alle nur 8 Bit SPI
> Register. Ein Vielfaches davon muss man per Software zusammenbauen,
> bestenfalls macht das die DMA auf größeren Prozessoren.

Das Ist so nicht richtig.
Die C2000 Familie von TI hat 16 BIT Breite Register.
Ich habe hier bei einem Projekt unter anderem auch eine zwei 
Prozessorlösung bei der ein C2000 und ein MSP über SPI miteinander 
Kommunizieren (C2000 ist Master) dort nutze ich die 16Bit voll aus und 
auch der MSP430 hat mit den 16 Bit keine Probleme.

von Fritz (Gast)


Lesenswert?

Tobias Korrmann schrieb:
> MSP430 hat mit den 16 Bit keine Probleme

Sogar die kleinen MSPs mit dem USI-Modul können 16Bit in einem Rutsch. 
Die größeren dann wieder nicht mehr :-\ Aber braucht man ja auch 
wirklich nicht. Quasi alle Bausteine zum Anschließen sind doch auf ein 
Vielfaches von 8Bit ausgelegt.

von Electronics'nStuff (Gast)


Lesenswert?

Fritz schrieb:
> Vielfaches von 8Bit ausgelegt.

Und da gehört 16 jetzt nicht dazu oder wie?

von Fritz (Gast)


Lesenswert?

Shift schrieb:
> Allerdings tut sich da bei mir nix..

Beim CCS musst du die Variable markieren, oder halt selbst eintragen im 
Watch-Fenster.

von Fritz (Gast)


Lesenswert?

Electronics'nStuff schrieb:
> Und da gehört 16 jetzt nicht dazu oder wie?

Natürlich gehört 16Bit auch dazu. Ich meine ja nur, dass ein 16Bit 
breiter SPI nicht notwendig ist.

von amateur (Gast)


Lesenswert?

@Tobias

Doppelter Sonderfall:

Sender kann's und Empfänger kann's.

von MCUA (Gast)


Lesenswert?

>> Selbst fette 32 Bit Prozessoren haben praktisch alle nur 8 Bit SPI
>> Register. Ein Vielfaches davon muss man per Software zusammenbauen,
>> bestenfalls macht das die DMA auf größeren Prozessoren.
>Das Ist so nicht richtig.
Jo. 32Biter haben norm zumindest 8 oder 16 Bits (an einem) zur Auswahl 
(nat weniger INTs oder DMAs nötig). Manche bis 32 Bits, zT mit zus FIFOs 
(obwohl da noch DMAs drauf sind, was wohl zeigt dass die DMAs nicht gut 
genug sind).

von Tobias K. (kurzschluss81)


Lesenswert?

amateur schrieb:
> @Tobias
>
> Doppelter Sonderfall:
>
> Sender kann's und Empfänger kann's.

Das ist es ja eben der MSP430 kanns eigntlich nicht. aber ihn 
interesieren nur die Bits und wenn 8 raus sind werden die nächsten 8 
verarbeitet da er ja 8 Bit Zeit die nächsten 8 Bit aus oder ins Register 
zu schieben.

von Vlad T. (vlad_tepesch)


Lesenswert?

amateur schrieb:
> @Tobias
>
> Doppelter Sonderfall:
>
> Sender kann's und Empfänger kann's.

dem Emfänger ist doch egal wie breit das Ausgangsregister des Senders 
ist.
Er liefert dann halt 2 Interupts.

Die TI Stellaris ARMs können auch alles zwischen und inklusive 4 und 16 
bit

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.