Hallo Community,
Ich habe zurzeit ein kleines Problem. Und zwar habe ich seit länger Zeit
ein kleinen Webserver auf dem ATMega644 mit dem ENC28J60 laufen.
Der ENC28J60 wird über das SPI Interface angesteuert. Nun wollte ich
mein Projekt gerne weiter ausbauen mit einen TFT Display, um Information
über den Server dort anzuzeigen.
Das Display ist ein 240x320 2.2 Zoll QVGA SPI Display mit dem ILI9341
Treiber.
Dieses Display habe ich dann auch mit dem SPI Bus verbunden anstatt denn
SS Pin(Nutzt der ENC) habe ich ihm Pin 2 gegeben.
Wenn ich nun an das Display ein Text schreibe. Wird dieser Text auch
nach dem Einschalten angezeigt. Jedoch wenn ich dann meinen Webserver im
Internet aufrufe dann wird mir die Webseite, im Browser dargestellt, und
zudem wird das TFT Display weiß.
Wenn ich aber nach dem Init des Display die CS Leitung vom TFT Display
abziehe, und dann Webseite öffne bleibt der Text auf dem Display stehen.
Also müssen sich die beiden Geräte gegenseitig stören, oder?
Da beide die SPI Kommunikation nutzten. Habe ich eine Klasse
erstellt(SPI.c/h) um dort das SPI zu Initialisieren.
SPI.c:
1
#include "processor.h" //Enthält F_CPU und BAUD
2
#include "SPI.h" //Dort sind die Macros festlegt: SPI_CONTROL_DDR=DDRB; SPI_CONTROL_PORT=PORTB; MOSI=PORTB5; MISO=PORTB6; SCK=PORTB7; SS=PORTB4
SPI_CONTROL_PORT |= (1<<SPI_CONTROL_SS); //SS High
11
12
SPCR = (1<<SPE) | (1<<MSTR);
13
SPSR |= (1<<SPI2X);
14
15
}
Der ENC28J60 nutzt als CS Pin: Port B 4
Das TFT Display nutzt als CS Pin: Port B 2
Was könnte da das Problem sein. Denn nachdem senden des Textes wird die
CS Leitung vom TFT Display wieder auf HIGH gelegt. Und dürfte somit
nicht auf Daten die an denn ENC28J60 gesendet werden reagieren, oder?
Lg Jan.
Alloziert Du die Resource SPI so, dass Dir kein Interrupt
dazwischenfunkt?
SPI ETH wird wohl im Interrupt gebraucht. Wartet der Interrupt dann, bis
eine Display SPI Zugriff fertig ist? Behandelt er den Display CS
richtig?
Nur mal so zum nachdenken.
Lothar M. schrieb:> Richtig, dafür ist der Slaveselect da. Wird er tatsächlich auf high> gelegt? Hast du das gemessen?
Messen wird denk ich schwer, da ich an der CS leitung ein 10K Pullup
Widerstand habe.
So werden die Codes beim TFT gesendet:
Jan H. schrieb:> Lothar M. schrieb:>> Richtig, dafür ist der Slaveselect da. Wird er tatsächlich auf high>> gelegt? Hast du das gemessen?>> Messen wird denk ich schwer, da ich an der CS leitung ein 10K Pullup> Widerstand habe.
Ja und? Pegel ist Pegel egal ob Pullup oder nicht. Den SPI Teilnehmer
interessiert das nicht.
Was soll der Pullup überhaupt? Dein Ausgangspin für das CS ist jeweils
eine Push Pull Stufe. Was soll der Pullup? Unnötig den CS Ausgangspin
belasten? Oder hast du Angst, dass im Reset während der CS Ausgangspin
floatend ist irgendwas passiert?
GHD schrieb:> Ja und? Pegel ist Pegel egal ob Pullup oder nicht. Den SPI Teilnehmer> interessiert das nicht.>> Was soll der Pullup überhaupt? Dein Ausgangspin für das CS ist jeweils> eine Push Pull Stufe. Was soll der Pullup? Unnötig den CS Ausgangspin> belasten? Oder hast du Angst, dass im Reset während der CS Ausgangspin> floatend ist irgendwas passiert?
Habe mir mal die CS Leitung mit meinen Oszi angeschaut. Wenn ich nur
denn Text setzte habe ich nach dem Init genau 5 CS Low. Für set_cursor,
set_rotation, set_textSize, set_TextColor, clearScreen. Danach nur noch
HIGH 3,3 Volt. Beim ENC28J60 genau so. Also auch HIGH wenn nix passiert
und LOW beim Empfänger habe getestet in dem ich die Webseite aufgerufen
habe und aufs Oszi geschaut habe.
Kann es vllt. passieren das eine Anfrage an denn ENC28J60 geht dieser
denn CS auf Low schreibt und gleichzeitig im TFT Display noch was
gemacht wird? So das das TFT auch gleichzeitig low ist?
Lg Jan.
Jan H. schrieb:> controlport &=~((1<<dc)|(1<<cs));//dc and cs both low to send command
Um beim AVR 2 Bits auf einmal zu setzen/löschen, ohne einem Interrupt
eine Lücke zu öffnen, kann man nicht die PORTx Register verwenden. So
wie hier besteht die Möglichkeit, dass ein Interrupt, der den gleichen
Port bedient, zwischenrein funkt. Alternative: einzelbitweise bei Ports,
die bitadressierbar sind, oder die Toggle-Funktion von PINx verwenden.
https://www.mikrocontroller.net/articles/Interrupt#Atomarer_Datenzugriff
GHD schrieb:> Was soll der Pullup überhaupt?
Bei den meisten AVRs sitzt SPI auf den gleichen Pins wie ISP. Pullups an
allen SS stellt sicher, dass ISP und die Slaves nicht kollidieren.
Manche Slaves haben den aber schon drin.
Lothar M. schrieb:> Richtig, dafür ist der Slaveselect da.
Als Chip-Select Ausgang ist der SlaveSelect-Eingang eben nicht da.
Aber da man den Pin sowieso auf Ausgang setzen muss wenn man SPI benutzt
und nicht die SlaveSelect Funktionalität haben will, drängt sich die
Verwendung als Chip-Select quasi auf, ja. :-)
Die Informationen sind auf jeden Fall noch zu dünn.
Weder ist die Hardware ausreichend beschrieben, noch die Software.
Ich tippe da auf einen Software-Fehler.
Aber das könnte auch ein falsch angeschlossener Pegel-Wandler sein, das
war so der einzige Fehler den ich bisher auf dem SPI hatte mit mehreren
Slaves.
Versuch mal, das Programm auf ein Minimum zu reduzieren.
Rudolph schrieb:> Versuch mal, das Programm auf ein Minimum zu reduzieren.
Ich habe habe mal alles unnötige aus mein Programm entfernt. So das nur
noch die Klassen drin sind wo mit SPI gearbeitet wird. Dieses sind
ili9341.c/h, enc28j60.c/h, main.c, SPI.c/h und processor.h. Andere
Sachen wie ADC, USART, DS18B20 TFT Grafik IP ARP habe ich raus gelassen.
Mal so ne Andere Frage. Was wäre wenn man bevor man ein CS Aktiv macht
ein Status setzt(w. encSPI=1) und dann beim display spi vorher abfragt:
1
if(encSPI == 1) {
2
while(encSPI != 0) {
3
//Wait for encSPI equals 0
4
if(encSPI == 0) break;
5
}
6
tftSPI = 1; //Not Ready to use ENC SPI
7
TFT_CS == LOW //Enable TFT CS
8
Command ... //Write Command
9
TFT_CS == HIGH //Disable TFT CS
10
tftSPI = 0; //Ready to use ENC SPI
11
}else{
12
tftSPI = 1; //Not Ready to use ENC SPI
13
TFT_CS == LOW //Enable TFT CS
14
Command ... //Write Command
15
TFT_CS == HIGH //Disable TFT CS
16
tftSPI = 0; //Ready to use ENC SPI
17
}
und halt umgekernt. Dann müsste es doch auch gehen. Bin mir nur nicht so
sicher bei dem while()
lg jan.
Nur kurz drüber geschaut, weder das Display noch der ENC28J werden im
Interrupt bedient, oder etwa doch?
So können die sich doch regulär gar nicht in die Quere kommen und die
Status-Variablen sind überflüssig.
Mit Interrupts wäre das while() auf jeden Fall tödlich, wenn gerade auf
dem SPI gesendet wird und der IRQ aufgerufen wird der auch senden
soll...
Und das manipuliert immer noch am Display rum?
Also es gibt einen Unterschied zwischen dem geposteten Code und
einer Version die iniEthernet() und ethernet_arp_request()
auskommentiert hat?
Wie sieht denn die Hardware dazu aus?
Rudolph schrieb:> Nur kurz drüber geschaut, weder das Display noch der ENC28J werden im> Interrupt bedient, oder etwa doch?
Eigentlich müsste man mit einem Oszilloskop per Zufallstreffer
sehen dass beide Chip Selects irgendwann gleichzeitig aktiv
sind.
Jan H. schrieb:> Da beide die SPI Kommunikation nutzten. Habe ich eine Klasse> erstellt(SPI.c/h)
1
voidinit_SPI_Interface(void)
ist aber nicht Member irgendeiner Klasse. Insofern verstehe
ich das mit der Klasse nicht .....
Rudolph schrieb:> Interrupt bedient, oder etwa doch?
Nein. Im Interrupt(habe ich entfernt in diesen Code) wird nur die
Temperatur eines LM35 ausgelesen und die Temperaturen des DS18B20.
Rudolph schrieb:> Und das manipuliert immer noch am Display rum?
Also falls du damit meinst wo das Display immer noch rum spinnt. Janein.
Also wenn ich die ganze Zeit mit ein Delay(nicht _delay_ms() Methode
sondern mit Timer2 Overflow gereget) 100 ms ein Punkt auf dem Display
löse und setzte. Und dann die Webseite aufrufe, dann bleibt das Display
stehen und reagiert nicht mehr. ENC reagiert ebenfalls nicht mehr.
Wenn ich aber was auf Display schreibe und dann die Webseite aufrufe
bleibt der Punkt auf dem Display stehen. Es seiden man kommt an die +5V
oder GND Kabel.
Rudolph schrieb:> Wie sieht denn die Hardware dazu aus?
Ich habe mal ein Schaltplan erstellt von meiner Hardware. Das ist
wirklich nur der Controller und der Reset die Spannungversorgung ist
dort nicht mit drin.
Arduinoquäler schrieb:> ist aber nicht Member irgendeiner Klasse. Insofern verstehe> ich das mit der Klasse nicht .....
Klar, ich hätte das mit dem SPI Interface auch in der main.c Klasse
machen können jedoch finde ich es so übersichtlicher.
Lg Jan.
Jan H. schrieb:> Klar, ich hätte das mit dem SPI Interface auch in der main.c Klasse> machen können jedoch finde ich es so übersichtlicher.
Deine Erwiderung lässt mich daran zweifeln ob du weisst was
eine Klasse im Sinne von C-Programmierung ist.
Die Leitungen gehen sicher nicht direkt ohne andere Teile dazwischen auf
den ILI9341 von dem Display und den ENC28J60, da zumindest der ENC28J60
ja für 3,3V ist.
Wenn ich das richtig interpretiere geht auch der ILI9341 nur bis 3,3V.
Und wenn Du den Schaltplan erst erstellen musstest, ist das Teil auf dem
Steckbrett aufgebaut?
Jan H. schrieb:> Ich habe mal ein Schaltplan erstellt von meiner Hardware. Das ist> wirklich nur der Controller und der Reset die Spannungversorgung ist> dort nicht mit drin.
Der ENC28J60 braucht vergleichsweise (zum Controller) viel Strom
und könnte bei schwachen oder fehlenden Abblock-Massnahmen auf
der Versorgung die anderen Schaltungsteile stören.
Rudolph schrieb:> ja für 3,3V ist.> Wenn ich das richtig interpretiere geht auch der ILI9341 nur bis 3,3V.
Ja das ist richtig. Die CS, MOSI, SCK DC, RESET Leitung gehen auf denn
CD4050 Converter der mit 3,3 Volt betrieben wird. Dadurch kommen nur 3.3
Volt auf denn Steuerleitungen an.
Rudolph schrieb:> Und wenn Du den Schaltplan erst erstellen musstest, ist das Teil auf dem> Steckbrett aufgebaut?
Also der ENC28J60 ist mit einer Ethernet Buchse auf einer
Lochrasterplatine aufgelötet. Mit einen Pin Header(Vcc, Gnd, Sck, miso,
mosi, cs, adc(lm35)).
Und das TFT Display habe ich auf eine Platine gemacht. Diese passt genau
auf denn Arduino UNO. Ist also ein "Arduino Shield". Dort drauf ist ein
3,3 Regler. 2 CD4050 Converter 1 für TFT ILI9341 und einer für denn SD
Karten Slot.
Arduinoquäler schrieb:> Der ENC28J60 braucht vergleichsweise (zum Controller) viel Strom> und könnte bei schwachen oder fehlenden Abblock-Massnahmen auf> der Versorgung die anderen Schaltungsteile stören.
Die Spannungversorgung wäre eigentlich mit ein 7805 gemacht. Jedoch
Powerere ich das ganze mit mein Labornetzteil. Das auf 5V eingestellt
ist. Die Schaltung zieht 245 mA. Ohne ENC und TFT nur 40 mA.
Lg Jan.
Arduinoquäler schrieb:> Deine Erwiderung lässt mich daran zweifeln ob du weisst was> eine Klasse im Sinne von C-Programmierung ist.
Es gibt keine Klassen im Sinne von C-Programmierung.
Jan H. schrieb:> Die Spannungversorgung wäre eigentlich mit ein 7805 gemacht. Jedoch> Powerere ich das ganze mit mein Labornetzteil. Das auf 5V eingestellt> ist. Die Schaltung zieht 245 mA. Ohne ENC und TFT nur 40 mA.
Du hast es wieder nicht verstanden (wie bei der Klasssen-
Programmierung).
Ein Labornetzteil garantiert noch keine zuverlässige Abblockung.
Ausserdem ist auch der Aufbau entscheidend für die korrekte
Funktion. Aus den bisherigen Verlauf entnehme ich dass du uns
deinen Aufbau nicht zeigen willst.
Jan H. schrieb:> Ja das ist richtig. Die CS, MOSI, SCK DC, RESET Leitung gehen auf denn> CD4050 Converter der mit 3,3 Volt betrieben wird. Dadurch kommen nur 3.3> Volt auf denn Steuerleitungen an.>> Und das TFT Display habe ich auf eine Platine gemacht. Diese passt genau> auf denn Arduino UNO. Ist also ein "Arduino Shield". Dort drauf ist ein> 3,3 Regler. 2 CD4050 Converter 1 für TFT ILI9341
Und wie ist das genau verdrahtet? Wirklich?
> und einer für denn SD Karten Slot.
Ah sieh an, noch ein SPI-Teilnehmer.
Wenn der fest verdrahtet ist gehört der auch in den Schaltplan, auch
wenn CS per Pullup auf VCC hängt und keine Karte im Slot ist.
Rudolph R. schrieb:> Und wie ist das genau verdrahtet? Wirklich?
Ich habe dafür auch noch mal ein Schaltplan angefertigt. Ich verwende
anstatt des AMS1117 3.3V Regler ein kleinen DC-DC Step Down Regler(max 1
A) wo die Spannung auf 3,35 Volt eingestellt ist.
Hinter/Vor denn Pin Header steht die Bezeichnung was der Pin bedeutet
die Zahl in der Klammer dahinter steht für die Zahl am Pin Header bsp:
SCK(2) mit 2 ist dann gemeint beim Pin Header wo die Zahl 2 steht.
Rudolph R. schrieb:> Ah sieh an, noch ein SPI-Teilnehmer.
Naja. Also die MISO ist gar nicht am Controller angeschlossen. Und CS
auch nicht.
Rudolph R. schrieb:> Wenn der fest verdrahtet ist gehört der auch in den Schaltplan, auch> wenn CS per Pullup auf VCC hängt und keine Karte im Slot ist.
Sorry. vergessen.
Also nochmal was andere ich habe auf mein TFT Display eine Lade
Animation gebastelt. Dort sind acht Punkte die weiß sind. Jede 100
ms(über overflow) macht er denn nächsten Punkt schwarz und denn
vorherigen weiß. So habe ich eine kleine Lade Animation. Das heißt ja
auch das alle 100 ms die CS Leitung low gelegt wird.
Wenn ich nun die Webseite aufrufe dann bleibt das TFT stehen. Komisch
ist jedoch auch, das die Animation bereits läuft bevor überhaupt der
ENC28J60 Initialisiert ist, und während der ENC28J60 über das SPI
Initialisiert(Mac Adresse / Server) werden SPI Befehle ausgeführt. Und
das TFT bleibt nicht stehen erst wenn die ethernet_arp_request()
Funktion anschlägt bleibt es stehen.
Lg Jan.
Ich tipp auf einen falsch angeschlossenen Pegelwandler, so dass CS high
nichts bewirkt, aber habe nur flüchtig drüber gelesen... Das SD
cardmodule von catalex hat diesen Fehler und hat mich erst mal ein paar
Stunden gekostet.
Hallo Leute,
Nach vielen Debuggen mit dem Display und denn ENC28J60, habe ich nun das
Problem gefunden.
Und zwar was das ganze kein Problem der Hardware oder am SPI Bus.
Sondern das Problem lag im Code. Ich habe meine Lade Animation die ich
vorher fürs Display programmiert habe auf dem Display gezeigt. Und habe
nach und nach denn Code von der HTTP Webseite entfernt bis ich denn
Fehler gefunden habe:
Folgender Code:
Das Problem ist das <font color='red'>. Wenn ich dieses aus dem Code
entferne dann läuft das Display normal weiter und auch der ENC läuft
ohne Probleme weiter. Das Display läuft auch weiter wenn ich die Seite
aufrufe.
Kann mir jemand vielleicht erklären warum das grade mit dem <font
color='red>zu Problemen führen kann? Kann mir es selber nicht erklären.
Lg Jan.
Hallo,
pauschal könnte man vermuten, daß irgendein Speicher verbotenerweise
beschrieben wird. Dies fällt anscheinend nur an dieser Stelle auf.
Vermutlich ist aber sonst ein Fehler dafür verantwortlich: falsche
Variablendeklaration, Arrayzugriff außerhalb des definierten Bereichs,
Überlauf... Dazu müßte man schon genauer das Programm untersuchen.
MfG
Christian S. schrieb:> daß irgendein Speicher
Hallo,
Es scheint doch nicht an den <font> zu legen sondern. An der Buffersize.
Diese habe ich auf 900 festgelegt(Standard Wert von der Library). Ich
habe die einfach mal Spaßeshalber auf 1500(bytes) gesetzt. Und auf
einmal ging alles wieder ohne Probleme.
Vielleicht wahr der Speicher von 900 Bytes voll. Und das hat zu irgend
einer Kettenreaktion geführt. Die dann dafür sorgte das der SPI Bus lahm
gelegt wurde.
Lg Jan.