Hallo,
ich habe folgendes Problem.
Über den Mikrocontroller PIC32MX695F512H möchte ich einen Slave über SPI
configurieren. Dazu lese ich die Daten aus einem Register (I) und muss
einen Wert inkrementieren und diesen wiederum in ein anderes Register
(II) schreiben. Dies geschieht in einer Schleife, bis ein passender Wert
erreicht ist.
Schaue ich mir die Resultate an, so scheint der Microcontroller zwar
richtig zu funktionieren, allerdings scheint der Slave nicht so schnell
auf die Änderung reagieren zu können, wie eine while schleife iteriert
wird.
Folglich wird zB 10x derselbe (I) Wert eingelesen und darauf mit einem
Inkrement von (II) reagiert. Sobald sich nun (I) ändert (nach ca. 10-20
Zyklen) so ist der Wert als wäre der aktuelle (II) Wert verwendet
worden.
Was kann ich tun?
(Mit 100mal ausgeführten For-Schleifen lässt sich das machen,
find ich aber unelegant.)
vor allem hast du vergessen das Datenblatt deines Controllers zu lssen.
Normalerweise muss man der SPI noch sagen, dass sie den Transfer starten
soll. Via bescreiben eines Steuerregisters.
Weiterhin sollte im Datenblatt stehen, wieviele Takte die SPI braucht,
um die Daten rauszuschreiben. so lange solltest du auf jeden fall nix
neues über die SPI versenden.
Dann solltest du das Datenblatt des anderen Controllers studieren und
schauen, ob er mit der SPI-Freuqenz überhaupt klar kommt und beide
Controller so konfigurieren, dass es zusammen passt.
Jan S. schrieb:> allerdings scheint der Slave nicht so schnell> auf die Änderung reagieren zu können
Und was steht dazu im Datenblatt des (unbekannten) Slave?
Mein Kristallkugel ist nämlich grad zur Reparatur.
SPI enthält kein Handshake. Deshalb muß man die Timings im Datenblatt
lesen und einhalten.
Peter
Also es handelt sich um einen Capacitance-to-Digital Converter den
AD7147, welcher automatisch Kapazität misst.
(http://www.analog.com/static/imported-files/data_sheets/AD7147.pdf)
der Teil zu SPI ist auf Seite 33ff.
Der Microcontroller Enthält folgendes zu SPI.
(http://ww1.microchip.com/downloads/en/DeviceDoc/DS-61106F.pdf)
Ich will es im Normalen Master Mode betreiben.(32 Bit)
Was ich momentan nicht mache ist, aktiv in diese Register zu schreiben.
Ich kann mittels einer Bibliotheksfunktion mit dem CDC kommunizieren.
Das hat bisher wunderbar für alles geklappt. Allerdings nun mit dieser
Schleife macht das eben Probleme.
Ich bin mir nich sicher ob es an der Kommunikation oder nur daran liegt,
dass der AD zu langsam auf den neuen Registerwert reagiert und somit
seine Messwerte noch nicht abgeändert hat. (BIAS-Addition)
Ich komm ehrlich gesagt mit deiner Fehlerbeschreibung aus dem
Eröffnungsposting nicht klar.
Kannst du nicht den Codeausschnitt zeigen und auch ein paar echte Daten
dazu. Dazu dann: Was ist an den Daten falsch, wie sollten sie richtig
aussehen und was ist deine Theorie was da passiert.
Deine ganze Fehlerbschreibung im Eröffnungsposting klingt für mich nach:
Warum vergleichst du nicht den Wert aus (I) mit demselben Wert aus dem
unmittelbar vorhergehenden Durchgang und unternimmst nichts, soalnge die
beiden gleich sind (oder eine voreingestellte ANzahl Durchläufen
abgearbeitet wurde). Aber ich bin mir nicht sicher, ob ich dir das
vorschlagen soll, weil ich eben die Fehlerbeschreibung nicht 100%
verstanden habe.
Das mit der update rate ist, wann ein neues CDC-Resultat gemessen wird.
Da ich ja eben dieses Register auslese, kann das zusammenhängen.
Wie könnte ich diese Zeit mit einem Microcontroller abwarten?
wait oder sleep ??
Also ich hab mal n bisschen Zeit gebraucht, um das alles zu analysieren.
Irgendwie gabs ständig anderes Verhalten.
nun schaut euch diesen Code mal an. Das ist noch nicht mal
die Funktion die ich machen will, aber irgendwas scheint an dem
vergleich
nicht zu funktionieren. Die UARTFunktionen senden das alles an einen PC.
Dort wird das mit HTERM aufgefangen.
1
intstageresult;
2
shorti=0;
3
// for nur, da am Anfang Mistwerte und nicht die wirklichen kommen
4
for(i=0;i<100;i++){
5
readViaSPIfromCDC_single(STAGE0,&stageresult);
6
sendPackageViaUART(UART1A,stageresult);
7
UARTSendDataByte(UART1A,'\n');
8
}
9
10
//1111 signalisiert den Beginn der Schleife
11
sendPackageViaUART(UART1A,0x1111);
12
UARTSendDataByte(UART1A,'\n');
13
// ist der Wert also > 0x8000, dann soll einfach der Datenstrom unendlich lange ausgegeben werden.
14
while(stageresult>0x8000){
15
16
readViaSPIfromCDC_single(STAGE0,&stageresult);
17
sendPackageViaUART(UART1A,stageresult);
18
UARTSendDataByte(UART1A,'\n');
19
}
20
//2222 signalisiert ende der schleife.
21
sendPackageViaUART(UART1A,0x2222);
Und hier nun, was in dem HTERM ausgegeben wird im Anhang.
Oben sind noch Werte aus der For Schleife,
zwischen 1111 und 2222 findet ihr einen Eintrag.
Manchmal ist da auch keiner. Das variiert.
Jedenfalls stellen wir fest das 0x87.. > 0x8000
Dieser Wert bleibt auch nach der Schleife erhalten.
Jedoch springt er entweder garnicht rein (sieht man hier nicht)
oder eben nur einmal!!
Was funktioniert hier nicht?
Darf man mit HEXwerten nicht vergleichen??
Hier sieht man wie der offset hochgezählt wird,
da der CDC mit der Änderung nicht mitkommt.
Mit der for-Schleife geht es. (während 1000x auslesen, reicht die Zeit
für den CDC sich anzupassen)
Wie geht es eleganter? (Sleep/wait??)