Forum: Mikrocontroller und Digitale Elektronik Probleme mit SPI- PIC18


von Brom B. (schrori)


Lesenswert?

Hallo zusammen, ich kämpfe ein wenig mit SPI. genauer gesagt 
funktioniert es aber es macht nicht was es soll. Ich steuere einen 
ST7735 an. Und das Problem ist, ich habe Datenverlust sofern ich nicht 
nach jedem einzelnen Byte SPI deaktiviere und neu aktiviere...

Wenn ich SPI Open, Byte Exchange, SPI Close etc. anwende funktioniert 
alles wunderbar. Wenn ich Open Byte Exchange, Byte Exchange anwende 
kommt nur die hälfte an.

Ursprünglivh hatte ich vor den TX Intterupt flag zu nutzen dieser wird 
low sobald kein Platz mehr im FIFO Sende puffer ist. aber es funktiert 
nicht.

Auch wenn ich SPI enable früher setze funktioniert es nicht... 
funktioniert es nicht.


Hat jemand eine Idee?

Hier meine Code Auszüge
1
void SPI1_Initialize(void)
2
{
3
    //EN disabled; LSBF MSb first; MST bus master; BMODE every byte; 
4
    SPI1CON0 = 0x03;
5
    //SMP Middle; CKE Active to idle; CKP Idle:Low, Active:High; FST disabled; SSP active high; SDIP active high; SDOP active high; 
6
    SPI1CON1 = 0x48;
7
    //SSET disabled; TXR required for a transfer; RXR data is not stored in the FIFO; 
8
    SPI1CON2 = 0x03;
9
    //CLKSEL HFINTOSC; 
10
    SPI1CLK = 0x01;
11
    //BAUD 15; 
12
    SPI1BAUD = 0x3;
13
    TRISBbits.TRISB5 = 0;
14
    //SPI1_Open();
15
}
16
17
void SPI1_Open()
18
{
19
    SPI1CON0bits.EN = 1;
20
}
21
22
void SPI1_Close(void)
23
{
24
    SPI1CON0bits.EN = 0;
25
}
26
27
void SPI1_ExchangeByte(uint8_t data)
28
{
29
   // while(!PIR2bits.SPI1TXIF){}; // dieser prüft ob platz im FIFO ist. 
30
    SPI1TXB = data;
31
    while(!SPI1INTFbits.SRMTIF);  //Warten bis leer gesendet wird oder 
32
                                    warten auf den RX Interrupt beides geht.
33
    SPI1INTFbits.SRMTIF = 0;
34
    //while(!PIR2bits.SPI1RXIF);
35
}

: Bearbeitet durch User
von Franko P. (sgssn)


Lesenswert?

Servus
was hast denn da für ein Teilchen? Und mit was arbeitest Du? MPLAB mit 
XC8 oder was? Und die Funktionen da, stammen die von Dir selber oder 
hast du dir das generieren lassen?

Gruß

von Dirk F. (dirkf)


Lesenswert?

Was ist denn mit Slave select Signal ?
Ich musste beim Display_Chip_ST7789V nach jedem Byte SS kurz auf high 
setzen...

von Brom B. (schrori)


Lesenswert?

Servus, der MCU ist ein PIC18F26K42
MPLAB XC8 Compiler.
Der Code ist generiert und angepasst.
Angepasst bedeutet ich habe die re-init bei SPI open entfernt und Byte 
Exchange zu einem void gemacht da ich nur senden möchte.

Die RXIF abfrage aus dem PIR2 register war standardmäßig hinterlegt, die 
IF Abfrage für den leeren Sende speicher kommt von mir da ich 
verschiedene dinge ausprobiert habe. Die Register im Init habe ich 
angepasst. so habe ich BMODE auf 1 und bin im Transmit only mode. (TX = 
1 RY = 0)

Sprich er sendet auch ohne das ich den Byte counter setzen muss.

Mein Ziel war es eigentlich in den sende Befehl (Exchange) eine abfrage 
zu stellen ob der fifo voll ist und wenn nein daten rein knallen bis er 
voll ist. daher die Abfrage nach dem PIR2.TXIF. Dieser geht auf low 
sobald der sende fifo voll ist.

in den wechseln von command und data befehlen wollte ich ebenfalls den 
srmif flag nutzen um sicherzustellen das alles raus ist bevor das bit 
umschaltet.

aber irgendwie klappt das alles nicht ^^

von Brom B. (schrori)


Lesenswert?

Damit habe ich mich ehrlicherweise noch nicht beschäftigt... was genau 
macht der SS dachte der wäre nur um CS mit einem interrupt zu steuern :O

von Peter D. (peda)


Lesenswert?

Dirk F. schrieb:
> Ich musste beim Display_Chip_ST7789V nach jedem Byte SS kurz auf high
> setzen...

Steht im DB des ST7735 exakt auch so drin.

von Brom B. (schrori)


Lesenswert?

Peter D. schrieb:
> Dirk F. schrieb:
>> Ich musste beim Display_Chip_ST7789V nach jedem Byte SS kurz auf high
>> setzen...
>
> Steht im DB des ST7735 exakt auch so drin.

so jetzt habt ihr mich... SS ist doch slave select = CS (Chip select) = 
das signal das dem slave sagt wer gemeint ist oder?

das habe ich tatsächlich dauerhaft aktiv... oder brauche ich hier den 
switch um klar zumachen das jetzt ein neues bit kommt? kann man dadurch 
dann spi o und 1 vermeiden? bzw. sorgt vielleicht spi aus an für die 
byte seperierung die ansonsten das SS machen sollte?

meint ihr das so?

VG

von Brom B. (schrori)


Angehängte Dateien:

Lesenswert?

Also ich konnte dazu nichts im Datenblatt finden... zumal ich ja 
nichtmal 16bit Pixel senden kann. Wenn ich SPI aktiviere und dann high 
und low der 16 bit Farbe über mittle kommt jeder 2. pixel nicht an... :/ 
ich denke nicht das es am Bildschirm liegt sondern das der fehler im MCU 
liegt.

von Falk B. (falk)


Lesenswert?

Brom B. schrieb:
> das habe ich tatsächlich dauerhaft aktiv...

Das sollte man aus mehreren Gründen NICHT tun!

> oder brauche ich hier den
> switch um klar zumachen das jetzt ein neues bit kommt?

Was?

> kann man dadurch
> dann spi o und 1 vermeiden? bzw. sorgt vielleicht spi aus an für die
> byte seperierung die ansonsten das SS machen sollte?

Wirr deiner Worte Sinn gar ist.

Wenn man sich nicht oberschlau ins Knie schießen will, treibt man SS wie 
bei praktisch allen SPI üblich.

SS low
Daten übertragen
SS high

Ja, es gibt Fälle, da kann SS dauerhaft LOW bleiben und es geht 
trotzdem. Aber das sind Ausnahmen. Gewinnen tut man dadurch nichts.

von Brom B. (schrori)


Lesenswert?

Falk B. schrieb:
> Brom B. schrieb:
>> das habe ich tatsächlich dauerhaft aktiv...
>
> Das sollte man aus mehreren Gründen NICHT tun!
>
>> oder brauche ich hier den
>> switch um klar zumachen das jetzt ein neues bit kommt?
>
> Was?
>
>> kann man dadurch
>> dann spi o und 1 vermeiden? bzw. sorgt vielleicht spi aus an für die
>> byte seperierung die ansonsten das SS machen sollte?
>
> Wirr deiner Worte Sinn gar ist.
>
> Wenn man sich nicht oberschlau ins Knie schießen will, treibt man SS wie
> bei praktisch allen SPI üblich.
>
> SS low
> Daten übertragen
> SS high
>
> Ja, es gibt Fälle, da kann SS dauerhaft LOW bleiben und es geht
> trotzdem. Aber das sind Ausnahmen. Gewinnen tut man dadurch nichts.

Also ja wirr. Da bin ich bei dir xD

 Aber SS bzw. Chipselect reißt es in dem Fall ja nicht raus. Ich möchte 
ja lediglich zb. 16bit Farbe am Stück senden. Also mit dem Fifo 2x8bit 
Unterbrechungsfrei durchjagen. Wie im Datenblatt des ST ja auch 
beschrieben. Aber ankommen tut nur jedes 2. Byte Wenn ich spi Open. 2 
Bytes spi Close mache.

Bei spi Open Byte spi Close spi Open Byte spi Close. Kommt Alles an 
unabhängig von SS/CS.

von Falk B. (falk)


Lesenswert?

Brom B. schrieb:
> Aber SS bzw. Chipselect reißt es in dem Fall ja nicht raus.

Es ist aber schon mal eine Fehlerquelle weniger.

> Ich möchte
> ja lediglich zb. 16bit Farbe am Stück senden. Also mit dem Fifo 2x8bit
> Unterbrechungsfrei durchjagen. Wie im Datenblatt des ST ja auch
> beschrieben.

Dann tu das!

> Aber ankommen tut nur jedes 2. Byte Wenn ich spi Open. 2
> Bytes spi Close mache.

Das ist Unsinn. Nimm ein Oszi und schau dir die Signale an. Etwas stimmt 
nicht. Vielleicht der SPI-Mode, vielleicht die Taktfrequenz, oder 
sonstwas.

> Bei spi Open Byte spi Close spi Open Byte spi Close. Kommt Alles an
> unabhängig von SS/CS.

Weil es einen parasitäten Effekt gibt, den du nicht siehst. Betreibe 
eine systematische Fehlersuche.

von Brom B. (schrori)


Lesenswert?

Falk B. schrieb:
> Das ist Unsinn. Nimm ein Oszi und schau dir die Signale an. Etwas stimmt
> nicht. Vielleicht der SPI-Mode, vielleicht die Taktfrequenz, oder
> sonstwas.
Hi Falk danke für die schnelle Antwort.

Taktfrequenzen habe ich schon verschiedene durch von 200khz bis 8mhz 
(das funktioniert mit besagter Open Close Politik stabil)
Das Verhalten ist tatsächlich nur durch SPIOpen (Genau genommen setzen 
den EN Bit) und spi Close (Rücksetzen des enable Bits) reproduzierbar. 
Ich erachte das ebenfalls als Unfug meiner Ansicht nach sollte ich auch 
SPI Einmal aktivieren und künftig nur noch durch CS/SS die slaves 
wählen.

Ebenso Erfolglos ist das ganze wenn ich nicht nach jedem Bit auf die 
Vollständigkeit der Übertragung warte.


Wenn ich dies nicht tue sondern Daten in den TX Puffer lade bzw. Warte 
wenn das PIR Interrupt meldet das dieser Speicher voll ist geht auch 
Garnichts.

Unabhängig davon wann ich SPI aktiviere oder deaktiviere.

Ein Oszilloskop habe ich erst in 2 Wochen wieder. Hast du noch Ideen wie 
ich das prüfen kann?

Ich habe auch vor jedem umsetzen des RS Pin (Data command Switch) ein 
wait while busy drin. Aber dazu kommt es ohnehin nicht da ja ohne Open 
Close nichts geht :( :(

Merkwürdig finde ich jedoch auch das die MPLAB /Mcc funktionen für 
Blocksendung die Bytes auch nicht in den Buffer laden sondern byteweise 
senden...

von Falk B. (falk)


Lesenswert?

Brom B. schrieb:
> Hi Falk danke für die schnelle Antwort.
>
> Taktfrequenzen habe ich schon verschiedene durch von 200khz bis 8mhz
> (das funktioniert mit besagter Open Close Politik stabil)
> Das Verhalten ist tatsächlich nur durch SPIOpen (Genau genommen setzen
> den EN Bit) und spi Close (Rücksetzen des enable Bits) reproduzierbar.

Dann scheint es etwas mit den Statusflags zu tun zu haben.

> Ich erachte das ebenfalls als Unfug meiner Ansicht nach sollte ich auch
> SPI Einmal aktivieren und künftig nur noch durch CS/SS die slaves
> wählen.

Das ist auch so.

> Ebenso Erfolglos ist das ganze wenn ich nicht nach jedem Bit auf die
> Vollständigkeit der Übertragung warte.

Das ist Unfug. Man muss nur am Ende der Übertragung auf das ECHTE Ende 
warten und dann CS deaktivieren. Das kann bei einem SPI mit FIFO etwas 
kniffelig sein, man muss das RICHTIGE Statusbit auslesen! Welches das 
bei DEINEM PIC ist, weiß ich nicht.

> Wenn ich dies nicht tue sondern Daten in den TX Puffer lade bzw. Warte
> wenn das PIR Interrupt meldet das dieser Speicher voll ist geht auch
> Garnichts.

Nimm ein Oszi und schau dir eine Signale an. Ich rate mal. Du wartest 
NICHT auf das ECHTE Ende der Übertragung.

> Ein Oszilloskop habe ich erst in 2 Wochen wieder. Hast du noch Ideen wie
> ich das prüfen kann?

Ein Oszi kann man nur durch ein besseres Oszi ersetzen. Oder VIEEEELE 
Versuche im Blindflug.

> Ich habe auch vor jedem umsetzen des RS Pin (Data command Switch) ein
> wait while busy drin.

Hä?

> Merkwürdig finde ich jedoch auch das die MPLAB /Mcc funktionen für
> Blocksendung die Bytes auch nicht in den Buffer laden sondern byteweise
> senden...

Keine Ahnung. Wenn ich das Datenblatt von deinem PIC18F26K42 lese, kann 
da bei SPI einiges schief gehen, man kann viel einstellen. Auch das 
Ansteuern von SS, was scheinbar durch das SPI-Modukl erfolgt bzw. 
erfolgen kann? Ohne Oszi wird das HART!

32.5.5.2 Software Slave Select Control

von Brom B. (schrori)


Lesenswert?

Falk B. schrieb:
> Brom B. schrieb:
>> Hi Falk danke für die schnelle Antwort.
>>
>> Taktfrequenzen habe ich schon verschiedene durch von 200khz bis 8mhz
>> (das funktioniert mit besagter Open Close Politik stabil)
>> Das Verhalten ist tatsächlich nur durch SPIOpen (Genau genommen setzen
>> den EN Bit) und spi Close (Rücksetzen des enable Bits) reproduzierbar.
>
> Dann scheint es etwas mit den Statusflags zu tun zu haben.
>
>> Ich erachte das ebenfalls als Unfug meiner Ansicht nach sollte ich auch
>> SPI Einmal aktivieren und künftig nur noch durch CS/SS die slaves
>> wählen.
>
> Das ist auch so.
>
>> Ebenso Erfolglos ist das ganze wenn ich nicht nach jedem Bit auf die
>> Vollständigkeit der Übertragung warte.
>
> Das ist Unfug. Man muss nur am Ende der Übertragung auf das ECHTE Ende
> warten und dann CS deaktivieren. Das kann bei einem SPI mit FIFO etwas
> kniffelig sein, man muss das RICHTIGE Statusbit auslesen! Welches das
> bei DEINEM PIC ist, weiß ich nicht.
>
>> Wenn ich dies nicht tue sondern Daten in den TX Puffer lade bzw. Warte
>> wenn das PIR Interrupt meldet das dieser Speicher voll ist geht auch
>> Garnichts.
>
> Nimm ein Oszi und schau dir eine Signale an. Ich rate mal. Du wartest
> NICHT auf das ECHTE Ende der Übertragung.
>
>> Ein Oszilloskop habe ich erst in 2 Wochen wieder. Hast du noch Ideen wie
>> ich das prüfen kann?
>
> Ein Oszi kann man nur durch ein besseres Oszi ersetzen. Oder VIEEEELE
> Versuche im Blindflug.
>
>> Ich habe auch vor jedem umsetzen des RS Pin (Data command Switch) ein
>> wait while busy drin.
>
> Hä?
>
>> Merkwürdig finde ich jedoch auch das die MPLAB /Mcc funktionen für
>> Blocksendung die Bytes auch nicht in den Buffer laden sondern byteweise
>> senden...
>
> Keine Ahnung. Wenn ich das Datenblatt von deinem PIC18F26K42 lese, kann
> da bei SPI einiges schief gehen, man kann viel einstellen. Auch das
> Ansteuern von SS, was scheinbar durch das SPI-Modukl erfolgt bzw.
> erfolgen kann? Ohne Oszi wird das HART!
>
> 32.5.5.2 Software Slave Select Control


Das ECHTE Ende der Übertragung findest du in meinem Code oben es sollte 
das srmif Bit sein. Dieses Interrupt flag löst aus sobald keine Daten 
mehr im sende Bereich sind. Das SPI Modul hat ein eigenes SS allerdings 
nutze ich dieses nicht sondern arbeite hier mit Io

Der RS Pin des ST7735 Seperiert die SPI Daten in Commands und Data. Ist 
er high sind die empfangenen Daten Kommandos ist er Low sind es Daten 
für die Kommandos. Zb. Um einen bestimmten Bereich zu adressieren. Bevor 
ich diesen ändere habe ich ein while busy auf das spi gelegt. Das srmif 
flag wird nur gesetzt nachdem gesendet wurde Default ist es deaktiviert 
weshalb diese Methode nicht zuverlässig ist.

Ich habe mich überwiegend an den Tabellen im Datenblatt orientiert 
demnach sollte es eigentlich nicht soooo wild sein...
Ist es aber doch...

Zuerst dachte ich der Fifo Interrupt zählt bitweise laut Datenblatt ist 
dem aber nicht so und die Open Close Sache klärt es auch nicht.

Auf Open Bleiben funktioniert wirklich nicht mal wenn ich den Interrupt 
des vollständigen sendens nach jedem Byte abwarte... 😪

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.