Hallo,
ich krame mich nun schon eine Zeit durch dieses Problem.
Ich habe einen 16F876 µC und einen AD7798 (3x16Bit SD-ADC) der an einen
Drucksensor angeschlossen ist.
Nun möchte ich den 16Bit ADC-Wert auslesen, alle versuche bislang selbst
die ID des IC's auszulesen gingen schief. (Per USART/RS232)
Mein bisheriger code siegt wie folgt aus:
Init:
>dannach erstmal garnichts mehr
Du hast SPI nicht verstanden :(
Was glaubst du wie die ID aus dem Chip kommt ?
Mit dem senden des Befehls ? Geht nicht. Den muss er ja
erstmal empfangen. Danach musst du die ID aus dem Chip
rausholen !
>oder lieg ich da total falsch?
Nicht ganz ;)
Denk nach! Du stellst eine Frage. Kommt die Antwort
schon während du die Frage stellst ? Nein, sie kommt
erst danach.
movlw B'01100000' ; Sage Comm. Register das ich das ID_Register lesen
möchte
movwf SPIout
call SPI_Data
movlw B'11111111' ; Dummy write to clock out the answer
movwf SPIout
call SPI_Data
ja sowas hatte ich auch schon versucht, Ohne erfolg.
Ich lassen nun den PIC nur als Schnittstellenwandler RS232 <-> SPI
arbeiten.
Ich bekomme bei egal was ich per SPI sende die antwort ascii 34
UI> 96
HM> 34
UI> 0
HM> 34
UI> 96
HM> 34
UI> 255
HM> 34
HM -> Höhenmesser
UI -> UserInterface
es musst also noch etwas anderes sein?!
Nur so aus Neugier: Welchen Drucksensor verwendest Du?
Hast Du den Drucksensor am AD-Wandler angeschlossen? Versuch es doch mal
mit einem Potentiometer an Stelle des Sensors. So kannst Du die
verschiedenen Werte simulieren ohne auf schlechtes Wetter warten oder
ohne auf den Hausberg steigen zu müssen.
Muss der A/D-Wandler irgendwie speziell initialisiert werden?
das mit dem poti wäre ne möglichkeit wenn ich nen falschen wert
bekommen würde ja. aber ich hab ja irgend ein anderes Problem, der ADC
hat mehrere register die anfangs beschrieben werden müssten zur
taktrate des SD-ADC's kalibrierung ect.
hab eben mal in mühevoller arbeit den adc abgelötet und bekomme
trotzdem noch 34 - muss also softwaremäßig sein das prob.
Als Drucksensor verwendet ich den MPXA4100(A6U) von Motorola.
also ich habs bislang net hinbekommen per Hardware SPI Schnittstelle,
nun versuche ichs über ne eigen Softwareschnittstelle, ist das Konzept
soweit ok?
1
SPI_out
2
movfw SPIout ; SPI daten zum schreiben in den Buffer legen
3
movwf SPIBuffer
4
bcf INTCON, GIE ; Interrupts aus
5
clrf temp ; Temp. Register leeren (Zählreg)
6
SPI_outLoop
7
rlf SPIBuffer, 1; SPIBuffer nach und nach nach links verschieben das MSB landet dabei im Carray
8
btfsc STATUS, C ; Ist das Carrybit = 1 ?
9
bsf SPIo ; ja, SPI übermittelt auch eine 1
10
btfss STATUS, C ; Ist das Carrybit = 0 ?
11
bcf SPIo ; ja, SPI übermittelt auch eine 0
12
bcf SPIclk ; clock 0
13
nop ; Kurz warten
14
bsf SPIclk ; Clock geht wieder auf HI
15
incf temp,1 ; Weiteres bit wurde übertragen
16
movwf temp
17
sublw D'8' ; wurden 8 bit übertragen?
18
btfsc STATUS, Z
19
goto SPI_outLoop
20
bsf INTCON, GIE ; Interrupts wieder an
21
return
22
23
SPI_in
24
bsf LED_RTX
25
bcf INTCON, GIE ; Interrupts aus
26
clrf SPIBuffer ; Buffer leeren
27
clrf temp ; Temp. Zählregister leeren
28
SPI_inpreLoop
29
btfsc SPIi ; Ist SDI 0 ? (ADC= RDY)
30
goto SPI_inpreLoop
31
SPI_inLoop
32
bcf SPIclk ; Clock 0
33
nop
34
nop
35
nop ; warten
36
btfsc SPIi ; Sendet ADC ein Hi signal?
37
bsf SPIBuffer,0 ; ja, Bit = 1
38
rlf SPIBuffer,1 ; Buffer nach Links verschieben, da vom MSB zum LSB gesendet wird
Arbeite zwar normalerweise nicht mit PICs, im Datenblatt steht
allerdings unter 9.1 "SCK (Master mode) must have TRISC<3> cleared" also
nicht gesetzt d.h. beim ADC kommt z.Z. kein Takt an.
> movlw B'10011000' ; RS232 & SPI> movwf TRISC
den code hatte ich überarbeitet und viele kleine fehlerchen tz
ausgemärzt. ich hatte ihn nun soweit das mal etwas anderes ankam aber
nie das was ich "haben" wollte.
Mein Init mit Hardware SPI sieht wie folgt aus nun:
Ist denn der Rest so initialisiert wie im Datenblatt?
CKE = 0 getestet? Z.Z. müsste auf der falschen Flanke übertragen werden.
Wo wird der ADC selektiert oder liegt /CS immer auf Low, Pull-Up?
Pseudocode:
1
InitPorts()
2
SPIInit(mode)
3
4
SelectADC()
5
6
dummy=SPITransceive(ADCReadIDReg)
7
res=SPITransceive(0x00)
8
9
DeselectADC()
U.U. auch mal "SS must have TRISA<5> set and register
ADCON1 (see Section 11.0: A/D Module) must be
set in a way that pin RA5 is configured as a digital
I/O" umsetzen.
ADC Datenblatt Seite 6 (kleingedruckte):
SCLK active edge is falling SCLK
PIC Datenblatt seite 64:
SSPSTAT CKE: SPI Clock Edge Select
(Figure 9-4, Figure 9-5 and Figure 9-6),CKP = 1
1 = Data transmitted on falling edge of SCK
0 = Data transmitted on rising edge of SCK
Also CKP = 1; CKE = 1
CKP wäre:
CKP: Clock Polarity Select bit/
In SPI mode/
1 = Idle state for clock is a high level
0 = Idle state for clock is a low level
Hab alle möglichkeiten mit SMP,CKE,CKP durchgetestet....
werde nun mal das mit dem SlaveSelect testen, wobei das normalerweise ja
nicht sein kann, man weiss ja nie
EDIT, Das SlaveSelect wird nur im Slave Modus verwendet
ich glaub ich habs :-)
da hab ich wohl was überlesen ...
To reset or reconfigure SPI
mode, clear bit SSPEN, re-initialize the SSPCON registers,
and then set bit SSPEN.
ich hab immer alles gleichzeitig gemacht, nun erst alles bis auf sspen
dann sspen.
zumindest überträgt er nun die ID (48) was stimmen könnte ....
Danke erstmal :)