Autor Tema: Para gurus del SPI. ¿Bug en Isis o fallo mio?.  (Leído 2905 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado crosstalk

  • PIC10
  • *
  • Mensajes: 21
Para gurus del SPI. ¿Bug en Isis o fallo mio?.
« en: 25 de Octubre de 2008, 15:42:29 »
¿ Que tal estamos ?

Esto va a ser algo largo. Asi que sin mas entro en el tema.

Microchip tiene un tutorial sobre el modulo SPI, que podeis ver aqui:
http://ww1.microchip.com/downloads/en/DeviceDoc/spi.pdf

En resumen, el documento muestra como comunicar dos PIC's, Master y esclavo, y el soft correspondiente para cada uno. Ambos son 16F876.
El master corre un contador, cuyo valor se envia al esclavo. El esclavo pasa el valor recibido en el buffer SSPBUF a un puerto libre y configurado como output.
El valor recibido por el esclavo puede visualizarse mediante 8 leds conectados a ese puerto.

He implementado este tutorial en Isis. Aqui os muestro la pantalla:



Como se puede ver, he cambiado los micros; un 877A para el master y un 873A para el esclavo. ¿Por que?.....pues porque es lo que voy a utilizar  :mrgreen:
Tambien se puede ver que los relojes estan a 5000 Hz. Asi se puede ver tranquilamente el monitoreo de actividad SPI. El fichero completo lo teneis como adjunto (dosmicros_dsn.bin). Logicamente hay que quitarle la extension bin y dejarlo como DSN.

Los fuentes de master y eslave son estos:

Para el master:

Código: ASM
  1. ; Master.asm
  2.  
  3.         list p=16F877A
  4. #include "p16F877A.inc"
  5.  
  6.         __CONFIG _CP_OFF&_DEBUG_OFF&_WRT_OFF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC
  7.  
  8. Ctr0            EQU 0x20                ; Variable con datos - SPI
  9. Dly0            EQU 0x21                ; Variable funcion Delay (L-byte)
  10. Dly1            EQU 0x22                ; Variable funcion Delay (H-byte)
  11. #define         CS  0x02                ; PORTA,2 chip select
  12.  
  13.         ORG 0                                           ; Comienzo del codigo en direccion 0
  14.         nop                                             ; FOR ICD. No implementations speed side effects.
  15. ; ****************Apoyo al SPI
  16. ; El pin RA2 del master se usa para soporte de la linea "Select Slave"
  17. ; La configuracion del puerto sera, por tanto "output, no analog"
  18.         BANKSEL TRISA           ; Selecciona banco de TRISA: BANK 1
  19.         movlw 0x00                      ; Preparar PortA, todo output.
  20.         movwf TRISA             ; Hacerlo.
  21.         movlw 0x06                      ; A/D DESACTIVADO
  22.         movwf ADCON1            ; Todo el portA es I/O digital
  23.        
  24. ; El puerto C contiene el modulo SPI
  25.         BANKSEL TRISC           ; Selecciona banco de TRISC (BANK 1)
  26.         movlw 0x10                      ; SCK=output , SDI=input, SDO=output, others=output
  27.         movwf TRISC                     ; Hacerlo
  28.        
  29.         movlw 0x40                      ; 0100 0000. Sampled at middle
  30.                                         ; SMP=0,Input data sampled at middle of data output time
  31.                                         ; CKE=1,Data transmitted on rising edge of SCK
  32.         movwf SSPSTAT           ;
  33.         BANKSEL SSPCON          ; BANK 0
  34.         movlw 0x22                      ; 0010 0001. SCK, SDO, SDI, and SS as serial port pins. CKP=LOW, SPI Master Mode, fosc/16
  35.         movwf  SSPCON           ;  
  36.  
  37. ; **************** Envio de datos a traves del modulo SPI del Master.
  38.  
  39. Send_DT
  40.         bcf  PORTA,CS           ; Enable Chip Select    
  41.         movf Ctr0,W             ; Counter a W.
  42.         movwf SSPBUF            ; y a SSPBUF. Debe poner BF a 1
  43.         BANKSEL SSPSTAT         ; BANK 1
  44. Char1          
  45.         btfss SSPSTAT,BF        ; esperando Buffer Full
  46.         goto Char1                      ; si no, otra vez
  47.         BANKSEL SSPBUF          ; BANK0
  48.         movf SSPBUF,W           ; leer desde SSPBUF. Debe poner BF a 0
  49.         bsf PORTA,CS            ; Disable Chip Select Output (high)
  50.  
  51. ; **************** conteo
  52. Update_Test_Counter
  53.         incf Ctr0,F             ; Incremento contador
  54. Delay
  55.         movlw 0x01                      ;  Delay
  56.         movwf Dly1                      ;
  57.         movlw 0x0F                      ;
  58.         movwf Dly0                      ;
  59. DlyLoop
  60.         decfsz Dly0,F           ;
  61.         goto DlyLoop            ;
  62.         decfsz Dly1,F           ;
  63.         goto DlyLoop            ;
  64.         ; Done Delay            ;
  65. DoAgain
  66.         goto Send_DT            ; Repetir envio de siguiente dato,
  67.         end


Para el esclavo:
Código: ASM
  1. ; SPItstS0.asm
  2. ; SLAVE Rev 0
  3. ; Demonstrates SPI connection between 2 PICs
  4. ; Master sends data (a counter), Slave receives and outputs to LEDs
  5. ; on PORTB
  6.         list p=16F873A
  7. #include "p16F873A.inc"
  8.         __CONFIG _CP_OFF&_DEBUG_OFF&_WRT_OFF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC
  9.  
  10. slvdat          EQU 0x21        ; Variable esclavo con datos - SPI
  11. #define CS 0x20                 ; PORTA,5 (HW SS pin)
  12.         ORG 0
  13.         nop                             ; FOR ICD
  14.                                                 ; Set up soporte SPI
  15.         BANKSEL TRISA           ; BANCO 1
  16.         movlw CS                        ; pin Chip Select
  17.         movwf TRISA             ; ...como input
  18.         movlw 0x06                      ; A/D off
  19.         movwf ADCON1            ;
  20.                         ; Set up puerto output (leds)
  21.         BANKSEL TRISB           ; BANCO 1
  22.         movlw 0x00                      ; pins PORTB....
  23.         movwf TRISB             ; ...como output
  24. ; ****************Setup del modulo SPI del Master.
  25.  
  26.                                                 ; Set up SPI
  27.         BANKSEL TRISC           ; BANCO 1
  28.         movlw 0x18                      ; SCK input, SDI input. 0001 1000
  29.         movwf TRISC             ; SDO output, otros output
  30.         movlw 0x40                      ; 0100 0000. Sampled at middle, CKE=1
  31.         movwf SSPSTAT           ;  
  32.         BANKSEL SSPCON          ; BANCO 0
  33.         movlw 0x24                      ; 0010 0100. SCK, SDO, SDI, and SS as serial port pins. CKP=LOW, SPI Slave Mode, /SS Required
  34.         movwf SSPCON            ; SSP on
  35.  
  36.         movlw 0xAA;
  37.         movwf slvdat;
  38. Chk4Dat
  39.  
  40.         movlw SSPSTAT           ; test
  41.         movwf FSR                       ; ....
  42.         btfss INDF,BF           ; de BF
  43.         goto Chk4Dat            ; si no 1, repetir test
  44.         BANKSEL SSPBUF          ; BANCO 0
  45.         movf SSPBUF,W           ; SSPBUF (dato) a W
  46.         BANKSEL PORTB           ; BANK 0
  47.         movwf PORTB             ; W a PORTB (leds)
  48.  
  49. DoAgain
  50.         movf slvdat,W           ; dato esclavo a W
  51.         movwf SSPBUF            ; ....y a SSPBUF.
  52.         goto Chk4Dat            ; Receive Next Byte
  53.         end


Algunos detalles importantes:

- Proteus 7.2 sp6
- La comunicacion SPI se hace con polaridad de reloj 0 (CKP=0) y flanco de reloj 1 (CKE=1).
- El compilador es MPASMWIN de Microchip.
- La linea de comandos en la ventana "Source/Code Generation Tool..." de Isis para el compilador MPASMWIN es ** "%1" /q ** , el source es ASM y el objeto, HEX.
- El monitor SPI esta configurado como "monitor"
- En la ventana "Debug/Configure diagnostics....." se ha seleccionado el modo "debug" para ambos modulos SPI.

Y ahora.....el problema:

El esclavo deberia mandar el valor 0xAA  siempre (lineas 36-37 y 50-51 de codigo del esclavo y segunda linea del log de simulacion). En su lugar, el master recibe 0xD5. En el log de simulacion (lo he modificado algo para se vea mejor) he marcado en ROJO dos de las lineas que no me encajan.  Si el esclavo pone en bajo (0) la linea SDO y el master la muestrea como tal (0).....¿por que el registro SSPSR recibe un (1) ???????????? :shock: :shock: :shock: :( :( :(
El esclavo recibe bien los datos siempre (contador)

Ahi va el log:

PC=0x001C. Slave mode: reset.
PC=0x0017. Slave mode: Slave select SS pin active. MSSP started immediately (CKE set). SSPSR=0xAA (170).
PC=0x0014. Master mode: stat write of  00000002 (2).
PC=0x0016. Master mode: drive SDO (L).
 
PC=0x0017. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0017. Master mode: sample data (SDI=1). SSPSR=0bD5 (213).      1101 0101
PC=0x00lA. Slave mode: sample bit 0. SDI=0. SSPSR=0b02 (2).                  0
PC=0x0016. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0016. Master mode: drive SDO (L).
PC=0x0018. Slave mode: drive SDO (H).
 
PC=0x0016. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0016. Master mode: sample data (SDI=1). SSPSR=0bAB (171).       1010 1011
PC=0x0017. Slave mode: sample bit 1. SDI=0, SSPSR=0b04 (4).             0
PC=0x0017. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0017. Master mode: drive SDO (L).
PC=0x0019. Slave mode: drive SDO (L).
 
PC=0x00l 6. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0016. Master mode: sample data (SDI=0). SSPSR=0b57 (87).       0101 0111
PC=0x0017. Slave mode: sample bit 2. SDI=0. SSPSR=0b08 ( 8 ).                0
PC=0x0016. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0016. Master mode: drive SDO (L).
PC=0x00lA. Slave mode: drive SDO (H).
 
PC=0x0017. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0017. Master mode: sample data (SDI=1). SSPSR=0bAE (174).       1010 1110
PC=0x00l 8. Slave mode: sample bit 3. SDI=0. SSPSR=0bl0 (16).                0
PC=0x0016. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0016. Master mode: drive SDO (L).
PC=0x00l 7. Slave mode: drive SDO (L).

PC=0x0016. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0016. Master mode: sample data (SDI=0). SSPSR=0b5D (93).       0101 1101
PC=0x00l 9. Slave mode: sample bit 4. SDI=0. SSPSR=0b20 (32).                0
PC=0x00l 7. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0017. Master mode: drive SDO (L).
PC=0x0017. Slave mode: drive SDO (H).

PC=0x00l 6. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0016. Master mode: sample data (SDI=1). SSPSR=0bBA (186).      1011 1010
PC=0x00lA. Slave mode: sample bit 5. SDI=0. SSPSR=0b40 (64).                0
PC=0x0016. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0016. Master mode: drive SDO (H).
PC=0x0018. Slave mode: drive SDO (L).
 
PC=0x0017. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0017. Master mode: sample data (SDI=0). SSPSR=0b75 (117).       0111 0101
PC=0x0017. Slave mode: sample bit 6. SDI=1, SSPSR=0b81 (129).                1
PC=0x0016. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0016. Master mode: drive SDO (L).
PC=0x0019. Slave mode: drive SDO (H).

PC=0x0016. Master mode: clock edge (L->H).                      SAMPLE
PC=0x0016. Master mode: sample data (SDI=1). SSPSR=0bEA (234).      1110 1010
PC=0x0017. Slave mode: sample bit 7. SDI=0. SSPSR=0b02 (2).                0
PC=0x00l 7. Master mode: clock edge (H->L).                      TRANSMIT
PC=0x0017. Master mode: drive SDO (L).
PC=0x0017. Master mode: transmission complete.
PC=0x001A. Slave mode: drive SDO (L).
PC=0x001A. Slave mode: reception complete. RSR=0x02 (2) transferred to SSPBUF.
PC=0x001C. Slave mode: slave Select (SS) pin inactive. MSSP has been reset.
PC=0x001C. Slave mode: reset.


Perdon por el tochazo, pero es que con menos no podia explicarlo.

Saludos a todos.






« Última modificación: 25 de Octubre de 2008, 16:31:49 por crosstalk »