Autor Tema: interrupcion slave SPI pic16f819  (Leído 3139 veces)

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

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
interrupcion slave SPI pic16f819
« en: 26 de Agosto de 2017, 20:43:51 »
Hola compañeros, bueno estoy tratando de programar un pic16f819 como slave en una comunicación SPI y requiero que el pic reaccione a la interrupción cuando el buffer se llene.
El programa que tengo es bien básico, toma los 8 bits que debieran llegar por SPI y los lleva al puerto GPIO para ser observados por leds.

El código es el siguiente:

; Configuracion SLAVE
    LIST P=16F819
    INCLUDE <p16f819.INC>
    __CONFIG _CP_OFF&_CPD_OFF&_MCLRE_OFF&_BODEN_OFF&_WDT_OFF&_PWRTE_ON&_HS_OSC

;...................... INICIO DEL PROGRAMA ................
     
    org 0             
    goto CONFIGURACION_GLOBAL           
    org 4                  ; direccion que apunta las interrupcciones 
    goto RUTINA_INTERRUPCION
    org 5

CONFIGURACION_GLOBAL:
    bcf STATUS, RP0
    bcf STATUS, RP1
    clrf PORTB
    bsf STATUS, RP0      ; accedo al banco 1
    movlw b'00000000'    ; puerto A como salida para leds
    movwf TRISA
   
    bsf TRISB,1         ; SDI in
    bcf TRISB,2         ; SDO out
    bsf TRISB,4         ; SCK in
    bsf TRISB,5         ; SS in
   
    bcf STATUS,RP0       ; vuelvo al banko 0
   
CONFIGURACION_SPI:
    bsf STATUS, RP0      ; accedo al banco 1
   
    clrf SSPSTAT
    bcf SSPSTAT,SMP
    bcf SSPSTAT,CKE 
   
    bcf STATUS,RP0       ; vuelvo al banko 0
   
    movlw b'01110000'
    movwf SSPCON
   
CONFIGURACION_INTERRUPCION:
   
    bsf STATUS,RP0       ; vuelvo al banko 1
    bsf PIE1,SSPIE       ; activo interrupcion SSP
   
    bcf STATUS,RP0       ; vuelvo al banko 0
    bcf PIR1,SSPIF       ; limpio bandera
    bsf INTCON,PEIE      ; habilitar interrupciones perifericos
   
    bsf INTCON,GIE       ; habiltar interrupciones globales
    goto INICIO
 
RUTINA_INTERRUPCION:   
    movfw SSPBUF        ; muevo lo que almaceno el buffer al registro W
    movwf PORTA         ; llevo los datos de registro W al puerto A para ver en los leds
    bcf PIR1,SSPIF      ; limpio bandera
    nop
    retfie

INICIO:
    nop
    GOTO INICIO     
   
    END


Cualquier ayuda me sera útil.  :)
Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:interrupcion slave SPI pic16f819
« Respuesta #1 en: 27 de Agosto de 2017, 00:40:24 »
Seria bueno que plantees cual es el problema, pero aca te dejo algunas cosas que veo:


- A pesar que en este ejemplo no afecte en nada, Te falta el codigo de salvar y reestablecer el contexto ( STATUS, W y PCLATH si lo usas) Esto te lo da microchip en el datasheet, busca por W_TEMP

- No uses nunca ORG 5, no es necesario y aca no hay problema, pero si pasas a un PIC18 donde el GOTO ocupa 2 lugares ( ej el de la interrupcion ocuparia 0x04 y 0x05 ) estarias sobreescribiendolo.

- Estas intentado poner el dato en el PORTA cuando nunca modificaste el registro ADCON1 para pasarlos a digitales

De los 3 errores, los 2 primeros no van a afectar a tu programa, no verias ningun cambio, pero es algo que deberias tener siempre en cuenta. El ultimo seguramente sea tu problema.

PD: No revise la configuracion del SPI, supongo que esta correctamente configurado.

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Re:interrupcion slave SPI pic16f819
« Respuesta #2 en: 27 de Agosto de 2017, 19:02:14 »
Gracias por responder

El problema es que el programa no responde a la interrupción.

Estoy simulando en ISIS una comunicación entre dos pics 16f819. El master se que funciona por que el programa esta validado con una simulación previa entre un pic 16f819 y un MCP23S08 (interface SPI a 8 Bits).

Configure el registro ADCON1 para que sea el puerto PORTA digital, pero aun sigue sin funcionar  :(

Ademas, la configuración SPI es igual a la que tiene el maestro ....... así que creo que debiera estar bien, pues el pic master me funciona ok.
 

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:interrupcion slave SPI pic16f819
« Respuesta #3 en: 27 de Agosto de 2017, 19:09:29 »
Citar
Ademas, la configuración SPI es igual a la que tiene el maestro ....... así que creo que debiera estar bien, pues el pic master me funciona ok.

Acabo de ver el programa y ahí esta tu problema.

Esta puesto como Maestro y no esclavo.

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Re:interrupcion slave SPI pic16f819
« Respuesta #4 en: 27 de Agosto de 2017, 19:29:35 »
Y cuales serian los registros que están mal configurados???

En etiqueta CONFIGURACION_SPI tengo este codigo:

CONFIGURACION_SPI:
    bsf STATUS, RP0      ; accedo al banco 1
   
    clrf SSPSTAT
    bcf SSPSTAT,SMP
    bcf SSPSTAT,CKE 
   
    bcf STATUS,RP0       ; vuelvo al banko 0
   
    movlw b'01110000'
    movwf SSPCON

Lo primero que hago es setear el registro SSPSTAT a 0x00......lei el datsheet y solo son los bits 7 y 6 los que afectan a la comunicación SPI (los demás son para los de I2C)..... entonces hice bit 7 = 0 y con eso hago que sea Slave (o no??).

Los demás registros son para el flanco del reloj y frecuencia.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:interrupcion slave SPI pic16f819
« Respuesta #5 en: 27 de Agosto de 2017, 20:18:10 »
No leiste el datasheet si me estas preguntando eso.

Citar
entonces hice bit 7 = 0 y con eso hago que sea Slave (o no??).

Datasheet:

Citar
bit 7 WCOL: Write Collision Detect bit

Deteccion de colision ( en caso de que sea maestro e intentes poner datos en el buffer cuando esta lleno ), no se como llegaste a la conclusion de que poner a 0 el bit 7 lo haces esclavo.

Tenes la definicion de los bits de esos 2 registros (SSPSTAT y SSPCON ) seguidos en el datasheet.
Y en el del SSPCON tenes que los bits 3 al 0 se define que va a hacer el modulo. Si es SPI maestro con sus distintas frecuencias, o si es esclavo con pin SS ( Slave Select ) o sin ese pin. O si lo usas para I2C.

De alli obtenes:

Código: ASM
  1. movlw b'01110101'
  2.     movwf SSPCON

Que segun el datasheet:
Citar
0101 = SPI Slave mode, clock = SCK pin. SS pin control disabled. SS can be used as I/O pin.

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Re:interrupcion slave SPI pic16f819
« Respuesta #6 en: 27 de Agosto de 2017, 23:41:45 »
Gracias KILLERJC estaba mal configurado el registro, ahora funciona bien.  8)

Leeré los que me haz citado anteriormente

Citar
A pesar que en este ejemplo no afecte en nada, Te falta el codigo de salvar y reestablecer el contexto ( STATUS, W y PCLATH si lo usas) Esto te lo da microchip en el datasheet, busca por W_TEMP

Nunca había leído eso.

PD: Si puedes me podrias decir en que caso debiera poner atención sobre lo que me haz recomendado, para tenerlo en cuenta en futuros proyectos??

Muchas gracias por tu ayuda y/o recomendaciones  ((:-))

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:interrupcion slave SPI pic16f819
« Respuesta #7 en: 28 de Agosto de 2017, 14:00:07 »
Voy a usar las etiquetas de tu programa

Usualmente tenes codigo dentro de INICIO, el cual las instrucciones usan W y el registro STATUS, cuando ocurre una interrupcion el micro guarda la direccion y salta a la interrupcion, realiza toda la interrupion y luego vuelve donde quedo.

El problema es que seguramente tanto W como STATUS sean modificados en la interrupcion, y cuando vuelva de la misma deberia tener los mismos valores de cuando se fueron, para que el programa siga sin problemas. Esto es lo que hace el codigo ese que te digo. Usa instrucciones que no modifican ninguna bandera del STATUS y W asi de esa forma se guardan y cuando se va a salir de la interrupcion los vuelve a poner para que el programa que este en INICIO funcione tal y cual venia haciendolo.

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Re:interrupcion slave SPI pic16f819
« Respuesta #8 en: 31 de Agosto de 2017, 15:28:19 »
Gracias por la información y explicación. :)

KILLERJC, me gustaría si pudieras ayudarme a entender acerca del vector y la prioridad de interrupción.

Tengo entendido que el vector a punta a la dirección de memoria de programa 0x04. Mi duda es: ¿Todas las interrupciones del microcontrolador van hacia esa dirección??.

Mi otra duda es acerca de la importancia de la interrupción que se ejecute. Si tengo activada 3 interrupciones, como la de A/D, externa y la del buffer para slave del SPI.... ¿Cual tiene la prioridad para la CPU en caso de que ocurran las 3 interrupciones simultáneamente??

De antemano, Gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:interrupcion slave SPI pic16f819
« Respuesta #9 en: 31 de Agosto de 2017, 15:48:59 »
Citar
Tengo entendido que el vector a punta a la dirección de memoria de programa 0x04. Mi duda es: ¿Todas las interrupciones del microcontrolador van hacia esa dirección??.

Voy a hacer un resumen de varios micros ( para que veas que cada uno es diferente):

- PIC16F poseen unicamente 2 vectores, el de reset y el de interrupcion, todas las interrupciones que ocurran van a saltar al 0x04, es tu deber luego saber cual es.
- PIC18F tiene 3 vectores, 1 de reset, y 2 de interrupcion (alta y baja prioridad), el de alta guarda por si solo los registros W y STATUS, asi como otros. El de baja tambien, pero si tenes alta y baja, el de alta siempre tiene mas importancia. Aca cuando configuras la interrupcion te pide que indiques si es de alta o baja, las direcciones si no mal recuerdo son 0x008 y 0x0018 (alta y baja respectivamente)
- dsPIC/PIC24/ARM(ST/NXP/etc)/ATtiny/ATmega poseen vectores de reset para cada modulo. Es decir una direccion de flash para cada modulo. En los ARM/dsPIC/PIC24/PIC32 ya tenes prioridades, en la cual le das un numero y segun ese numero si ocurren juntas o mientras se ejecuta una aparece alguna de mayor prioridad se deja esa interrupcion y entra a la de mayor prioridad.

Citar
Mi otra duda es acerca de la importancia de la interrupción que se ejecute. Si tengo activada 3 interrupciones, como la de A/D, externa y la del buffer para slave del SPI.... ¿Cual tiene la prioridad para la CPU en caso de que ocurran las 3 interrupciones simultáneamente??

En el caso del PIC16F vos sos quien le va a dar prioridad a que va a atender. Ejemplo

Código: ASM
  1. BTFSC FLAG_INT, ADIF
  2. CALL ADC_INT        ;Aca dentro trato la interrupcion y limpio el flag
  3. BTFSC FLAG_INT, SPI
  4. CALL SPI_INT         ;Aca dentro trato la interrupcion y limpio el flag      
  5. BTFSC FLAG_INT, EXT
  6. CALL EXT_INT        ;Aca dentro trato la interrupcion y limpio el flag

A pesar que los nombres estan mal, es para que se entienda, esto es lo que vos vas a hacer en tu interrupcion. En este caso vas a tener que el ADC va a ejecutarse primero, luego el SPI y luego el externo. Si es que ocurren todos simultaneamente.

Puede ocurrir por ejemplo que solo se active la interrupcion externa, cuando llega al CALL EXT_INT, aparece una interrupcion del SPI. En este caso ( ya paso la parte del software ) al momento de salir, el flag del SPI sigue en 1, ya que no se limpio, al momento de ejecutarse el RETFIE, el CPU detecta la condicion del flag del SPI y lo envia nuevamente al vector de interrupcion, ejecutando ahora si la parte del SPI.

Si seguis la norma de que lo que se realiza en la interrupcion debe ser lo mas rapido posible ( no deberia haber bucles extensos, ni funciones pesadas ), no deberias tener problemas.


 

anything