Forum: Mikrocontroller und Digitale Elektronik Komisches Problem bei SPI Datenuebertragung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Kai Z. (liquidsteel)


Lesenswert?

Hi all,

ich habe ein koisches Problem bei der SPI Datenuebertragung. Und zwar 
habe ich in meinem verfassten Code staendig eine printf Ausgabe am ende 
des main-loops um einige werte zu kontrollieren. Die SPI uebertragung 
hat wunderbar funktioniert, doch als ich das printf rausgenommen habe, 
spielen meine Ausganbe werte an den SPI verrueckt: Ich denke wenn ich 
den code hier poste, dann ist es am deutlichsten:
1
...
2
3
#define SPICOF 10.73741824
4
5
int SPIOUT2;
6
float SPISPEED, SPIOUT, SPEED;
7
short SPIVAR1, SPIVAR2;
8
9
...
10
11
SPISPEED = SPEED * 1000;
12
SPIOUT = SPISPEED * SPICOF * 4;
13
SPIOUT2 = (int)SPIOUT;
14
SPIVAR2 = (SPIOUT2 >> 14) & 0x3FFF;
15
SPIVAR2 |= 1 << 14;
16
SPIVAR1 = SPIOUT2 & 0x3FFF;
17
SPIVAR1 |= 1 << 14;
18
while (SPIBUF & 0x20000000);
19
SPIDAT0 = 0x2120;
20
while (SPIBUF & 0x20000000);
21
SPIDAT0 = SPIVAR1;
22
while (SPIBUF & 0x20000000);
23
SPIDAT0 = SPIVAR2;
24
while (SPIBUF & 0x20000000);
25
SPIDAT0 = 0x2028;
26
/*printf("%f \n",SPEED);*/

Die Variable SPEED beinhaltet einen Wert der im vorgehendem code 
berechnet wird, alle anderen Variablen in dem hier aufgefuehrten Code 
werden nicht im vorherigen Codep-teil benutzt.
Das Problem ist nun, wenn ich printf ausgebe, dann werden die richtigen 
werte per SPI uebergeben (also SPIVAR1/2 sind richtig). Wenn ich printf 
wegnehme, dann sind SPIVAR1/2 nicht nur falsch, sondern springen wild 
ueber verschiedene Werte herum.
Kann mir da jemand weiterhelfen?

Gruss
Kai

: Verschoben durch Admin
von (prx) A. K. (prx)


Lesenswert?

Spekulation: Ich nehme an, das SPI hat einen FIFO-Puffer drin, der die 4 
Werte verdaut ohne zu ersaufen. Wenn das printf() danach für genug 
Laufzeit sorgt, dann leert sich das FIFO unterdessen. Ohne printf() 
läuft es über. Möglicherweise erfüllen die while() Schleifen nicht ihren 
Zweck.

Es würde aber sicherlich weiterhelfen, etwas mehr als Nichts über die 
Plattform zu erfahren.

Zum Stil: Variablen ausschliesslich mit Grossbuchstaben zu bezeichnen 
steht eigentlich nur Fortran und Cobol gut an. In C macht man sich damit 
keine Freunde.

von Kai Z. (liquidsteel)


Lesenswert?

Danke für die schnelle Antwort

hab ganz vergessen die Platform zu erwähnen:
Es handelt sich um ein TMS320C6747 floating point DSP. Dieser ist direkt 
verbunden mit AD9833 nem DDS von Analog Devices.

Danke für den Tip mit mit den Variablen und grossbuchstaben. Bin 
erlichgesagt ein neuling in Sachen C programmieren und hab noch bissle 
probleme vorallem mit arrays.

Angeblich ist das Register das ich in der while schleife abfrage genau 
für den Zweck des Buffers gedacht, also ob der Buffer bereit ist neue 
Werte aufzunehmen und entleert ist.

Ich werde morgen mal checken wo genau der Fehler entsteht, vlt. spielen 
schon die Variablen vorher verrückt und nicht der Buffer.

von Kai Z. (liquidsteel)


Lesenswert?

So ich habe mal die variablen befor die SPI uebertragung beginnt in ein 
Array geschrieben. Die errechneten variablen sind tatsaechlich schon vor 
beginn der SPI uebertragung flasch.
Ich blicke da nun garnicht mehr durch. Ich habe aber ein verdacht, wo 
genau kann man nachschaun wie gross der Code bereits ist, also wieviel 
Speicher er wegnimmt?

von Kai Z. (liquidsteel)


Lesenswert?

Ich habe nun die Urache gfeunden, kann mir es aber nicht erklaeren. Es 
hat nix damit zu tun, dass das printf am ende der SPI uebertragung 
auftaucht und ein Delay oder so verursacht. Ich habe einfach mal das 
printf am anfang der main() gesetzt. Das eigentliche programm laeuft in 
einer unendlichen loop wo sich auch die SPI uebertragung befindet. Das 
printf wird also nur ein einziges mal am anfang ausgefuehrt und sorgt 
nun fuer kein Delay zwischen den SPI uebertragungen. Und es 
funktioniert, alle werte sind richtig.
Es muss also was  damit zu tun haben, dass ich printf und somit ne 
library benutze und der compailer etwas anders configuriert wie vorher 
und es deshalb funktioniert.
Was sagen die programmierer dazu?

von (prx) A. K. (prx)


Lesenswert?

Ich wage die Prophezeihung, dass alle Glaskugeln grad defekt, in 
Reparatur oder unpässlich sind.

von Kurti (Gast)


Lesenswert?

Meine nicht ;-).

Wo wird SPEED initialisiert? Ich denke durch das printf wird SPEED im 
weiteren Programm als float behandelt. Ohne wird es wohl direkt auf int 
gecastet (optimiert).


versuch mal das hier:

SPISPEED = SPEED * 1000.0;
SPIOUT = SPISPEED  SPICOF  4.0;

von Kai Z. (liquidsteel)


Lesenswert?

Kurti schrieb:
> Wo wird SPEED initialisiert?

SPEED wird global (also ganz oben :)) als float deklariert.

Kurti schrieb:
> versuch mal das hier:
>
> SPISPEED = SPEED * 1000.0;
> SPIOUT = SPISPEED  SPICOF  4.0;

das funktioniert leider nicht

Kurti schrieb:
> Ich denke durch das printf wird SPEED im
> weiteren Programm als float behandelt.

ich habe die Vriable SPEED aus dem printf genommen, ich gebe also nur 
einen Text aus ohne Variablen zu verknuepfen. Und dann funktioniert es! 
Es liegt also nicht an der verknuepfung von printf mit irgendwelchen 
Variablen, sondern grundsetzlich der gebrauch der printf Funktion.

von ?=? (Gast)


Lesenswert?

Hi, ist es nicht so, das SPIBUF beim TMS320 der Eingangspuffer ist, also 
quasi der Empfangskanal. Wäre es nicht sinnvoller, ein Statusregister 
abzufragen z.B. SPISTS oder SPIFLG ?

von ?=? (Gast)


Lesenswert?

Sorry, beim tms320c6747 ist der obere Teil der Status, die untern 16Bit 
die Empfangsdaten.

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Der TI DSP Compiler macht keine automatischen Typkonvertierungen, das 
muss man wissen.
Man muss alle Konvertierungen manuell casten.

Man muss auch wissen, dass globale und als static deklarierte Variablen 
NICHT automatisch initialisiert werden.

Grüße,

Peter

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.