www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AD7798 & PIC SPI


Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
; ==========================================
; Ports Init.
; ==========================================
  clrf  PORTA
  clrf  PORTB
  clrf  PORTC
    BSF   STATUS, RP0 ; auf Bank 1 umschalten
    MOVLW   0x06        ; PCFG3..0 = '0110' (ADC's -> OFF)
    MOVWF   ADCON1
  movlw  B'11100110'  ; PortA SoftwareI²C
  movwf  TRISA
  movlw  B'00000000'  ; PortB LED's
  movwf  TRISB
  movlw  B'10001000'  ; RS232 & SPI
  movwf  TRISC
  bcf     STATUS, RP0  ; Bank 0

; ==========================================
; SPI-Bus initialisieren
; ==========================================
    clrf  SSPCON
  clrf  SSPSTAT
  
; ==========================================
; RS232 initialisieren
; ==========================================
  bcf    NewData
  clrf  ZeichenIN
  clrf  ZeichenOUT
    BSF     STATUS,RP0     ; Bank1
    MOVLW   0x20            ; Sender: RS232
    MOVWF   TXSTA           ;
    BCF     STATUS,RP0      ; Bank 0
     MOVLW   0x90            ; Empfänger: RS232
    MOVWF   RCSTA           ; 
    BSF     STATUS,RP0      ; Bank1
  MOVLW   D'64'      ; Set Baud rate 9,6 kBPS bei 10 MHz
    MOVWF   SPBRG
     BSF     TXSTA, BRGH     ; BRGH=1
     BCF     STATUS,RP0      ; Bank 0

  M_RS232Out '$'
  M_RS232Out 'H'
  M_RS232Out 'M'
  M_RS232Out '#'
  M_RS232Out 'B'
  M_RS232Out 'O'
  M_RS232Out 'O'
  M_RS232Out 'T'
  M_RS232Out 'I'
  M_RS232Out 'N'
  M_RS232Out 'G'
  M_RS232Out ';'

; ==========================================
; Lampentest und Status
; ==========================================
  bsf    LED_ERR
  bsf    LED_RTX
  
  M_wait D'250'
  M_wait D'250'
  M_wait D'250'
  M_wait D'250'

  bcf    LED_ERR

  M_wait D'250'

; ==========================================
; BUS-Systeme und andere Transmitter einschalten
; ==========================================
    clrf    PIR1               ; alle Interruptflags löschen
    clrf    PIR2  
  bsf     SSPCON, SSPEN   ; MSSP-Modul Ein
  BSF     STATUS,RP0      ; Bank1
    BSF     PIE1,RCIE       ; Enable receive interrupts
  ;BcF    PIE1,SSPIE    ; Enable SSP interrupts
    BCF     STATUS,RP0      ; Bank 0
  BSF    INTCON, PEIE
  BSF    INTCON, GIE    ; Enable global interrupts

  M_RS232Out '$'
  M_RS232Out 'H'
  M_RS232Out 'M'
  M_RS232Out '#'
  M_RS232Out 'R'
  M_RS232Out 'E'
  M_RS232Out 'A'
  M_RS232Out 'D'
  M_RS232Out 'Y'
  M_RS232Out ';'
  
  bcf    LED_RTX

Die SPI Funktion:
;*****************************************************
; SPI Datenverkehr
;*****************************************************
SPI_Data
  movf    SPIout,W                ; move outbyte into w
    movwf   SSPBUF                  ; place data in send buffer
SPIloop
    bsf     STATUS,RP0              ; set to bank 1
    btfss   SSPSTAT,BF              ; has data been received?
     goto    SPIloop                ; loop if not received yet
    bcf     STATUS,RP0              ; set to bank 0
    movf    SSPBUF,W                ; empty the receive buffer
  movwf  SPIin
  M_RS232Out '$'
  M_RS232Out 'H'
  M_RS232Out 'M'
  M_RS232Out '#'    
  M_RS232Out SPIin  
  M_RS232Out ';'
    return

(RS232 Only funktioniert)

Ich lieg doch richtig das ich z.B. die ID des ADC's mit folgenden Zeilen 
auslesen kann?
movlw B'01100000'  ; Sage Comm. Register das ich das ID_Register lesen möchte
movwf SPIout
call SPI_Data


Wär super wenn mir jmd helfen kann :)


Stefan

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry der Init teil war der alte,

muss natürlich bei TRISC
movlw  B'10011000'  ; RS232 & SPI
heissen

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>movlw B'01100000'  ; Sage Comm. Register das ich das ID_Register lesen möchte
>movwf SPIout
>call SPI_Data

Und was machst du DANACH ?

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dannach erstmal garnichts mehr, weil ich als antwort  egal wobei immer 
nur das ascii char " bekomme (32)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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 !

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm...

hab den teil aus dem microchip appnotes, dafür (zum lesen)
sollte ja der folgende teil sein?

...
    btfss   SSPSTAT,BF              ; has data been received?
     goto    SPIloop                ; loop if not received yet
    bcf     STATUS,RP0              ; set to bank 0
    movf    SSPBUF,W                ; empty the receive buffer
...

oder lieg ich da total falsch?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?!

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ich habs bislang net hinbekommen per Hardware SPI Schnittstelle, 
nun versuche ichs über ne eigen Softwareschnittstelle, ist das Konzept 
soweit ok?
SPI_out
  movfw  SPIout    ; SPI daten zum schreiben in den Buffer legen
  movwf  SPIBuffer
  bcf    INTCON, GIE  ; Interrupts aus
  clrf  temp    ; Temp. Register leeren (Zählreg)
SPI_outLoop
  rlf    SPIBuffer, 1; SPIBuffer  nach und nach nach links verschieben das MSB landet dabei im Carray
  btfsc  STATUS, C  ; Ist das Carrybit = 1 ?
   bsf  SPIo    ; ja, SPI übermittelt auch eine 1
  btfss  STATUS, C  ; Ist das Carrybit = 0 ?
   bcf  SPIo    ; ja, SPI übermittelt auch eine 0
  bcf    SPIclk    ; clock 0
  nop          ; Kurz warten
  bsf    SPIclk    ; Clock geht wieder  auf HI
  incf  temp,1    ; Weiteres bit wurde übertragen
  movwf  temp
  sublw  D'8'    ; wurden 8 bit übertragen?
  btfsc  STATUS, Z  
   goto   SPI_outLoop
  bsf    INTCON, GIE  ; Interrupts wieder an
  return
  
SPI_in
  bsf    LED_RTX
  bcf    INTCON, GIE  ; Interrupts aus
  clrf  SPIBuffer  ; Buffer leeren
  clrf  temp    ; Temp. Zählregister leeren
SPI_inpreLoop
  btfsc  SPIi    ; Ist SDI 0 ? (ADC= RDY)
   goto  SPI_inpreLoop
SPI_inLoop
  bcf    SPIclk    ; Clock 0
  nop
  nop
  nop          ; warten
  btfsc  SPIi    ; Sendet ADC ein Hi signal?
   bsf  SPIBuffer,0  ; ja, Bit = 1
  rlf    SPIBuffer,1  ; Buffer nach Links verschieben, da vom MSB zum LSB gesendet wird
  bsf    SPIclk    ; Clock wieder 1
  incf  temp,1    ; Weiteres bit wurde empfangen
  movwf  temp
  sublw  D'8'    ; wurden 8 bit empfangen?
  btfsc  STATUS, Z  
   goto   SPI_inLoop
  movfw  SPIBuffer  ; Buffer in Ausgabebyte schreiben
  movwf  SPIin
  bsf    INTCON, GIE  ; Interrupts wieder an
  bcf    LED_RTX
  return  

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
...
  movlw  B'10010000'  ; RS232 & SPI
  movwf  TRISC
...
...
  movlw  B'00110010'  
  movwf  SSPCON
  BSF     STATUS,RP0      ; Bank1
  clrf  SSPSTAT
  movlw  B'01000000'
  movwf  SSPSTAT
...


Sende/Empfangsroutine:
;*****************************************************
; SPI Datenverkehr
;*****************************************************
SPI_Data
  bsf    LED_RTX
  movlw  D'255'
  movwf  loops
  movlw  D'255'
  movwf  loops2
  movfw    SPIout                ; move outbyte into w
    movwf   SSPBUF                  ; place data in send buffer
  bcf    INTCON, GIE
SPIloop
    bcf     STATUS,RP0              ; set to bank 0
  decf  loops,1
  movfw  loops
  sublw  '0'
  btfsc  STATUS,Z
   decf  loops2,1
  movfw  loops2
  sublw  '0'
  btfsc  STATUS,Z
   goto  SPIError

    bsf     STATUS,RP0              ; set to bank 1
    btfss   SSPSTAT,BF              ; has data been received?
     goto    SPIloop                ; loop if not received yet
    bcf     STATUS,RP0              ; set to bank 0
    movf    SSPBUF,W               ; empty the receive buffer
  movwf  SPIin
  bcf    LED_RTX
  bcf    INTCON, GIE
    return
SPIError
  bsf    LEDCON, LEDERREN
  bsf    LEDCON, BLINKERREN
  goto  SPIloop

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
InitPorts()
SPIInit(mode)

SelectADC()

dummy = SPITransceive(ADCReadIDReg)
res = SPITransceive(0x00)

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.

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan R. (stefanr86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.