SPI esclavo por software con PIC

#1
Me he topado con la necesidad de implementar el protocolo SPI por software ya que el 16F616 no cuenta con el modulo MSSP y como lo quiero solo para recibir datos decidió hacerlo por software y para probar que esta bueno he usado un 18F con SPI en modo hardware para enviarle datos en la simulación de proteus si funciona pero cuando lo armo no funciona, unicamente si hago el envio también por software si funciona, talvez me puedan echar una manita aquí esta el código del esclavo

ESCLAVO a 8 Mhz oscilador interno:
Código:
#bit PORTA1 = 05.1
#bit PORTA2 = 05.2
#bit PORTA3 = 05.3
#bit PORTA4 = 05.4
#bit PORTA5 = 05.5

int xbit=0;
int recibido=0;

#int_ext
void interrupcion(){ 
  if( !PORTA4 ){  //ENABLE
    if( PORTA3 ){ //Data IN
      bit_set(recibido,7-xbit); 
    }
    xbit++;
  }
}

En la rutina principal
     ext_int_edge(0,L_TO_H); 
     enable_interrupts(INT_EXT); 
     enable_interrupts(GLOBAL); 
     while(1){     
          if( xbit >= 8 ){ 
            //dato leido bla bla bla...
           xbit = 0;
           recibido = 0;
         }
     } 

El codigo del Maestro pues simple un par de lineas
#use spi(MASTER,BITS=8,MODE=0,FORCE_HW)  //ya probe con mode 1 ..2 ..3 y tampoco
para enviar:
spi_xfer(123);
 
#2
Tal vez se te están yendo los tiempos, es decir si el SPI por hard trabaja a una frecuencia de clock muy alta, tal vez no le das tiempo al SPI por soft para entrar en la interrupción, leer el bit y llamar a la función bit_set.

¿Probaste con una comunicación más lenta?
 
#3
Si tambien pense eso pero el 16F616 esta a 8Mhz con oscilador interno y el de hardware esta a 16Mhz y su spi dividido en 64 setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64); asi que en teoria tendria que darle tiempo.
 
#4
Si tambien pense eso pero el 16F616 esta a 8Mhz con oscilador interno y el de hardware esta a 16Mhz y su spi dividido en 64 setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64); asi que en teoria tendria que darle tiempo.
Si y tal vez no.

Hablamos de 250kHz (4uS) y pensá que tu código como está implementado, por c/bit tiene que entrar a la interrupción, en el peor de los casos llamar a la función set, para luego retornar. Como decís el clock del 16F616 es 8MHz (125nS) => tenés solo 32 clk's para resolver c/bit.

Tal vez podrías optimizar el código para entrar solo una vez en la interrupción y después resolverlo con una función, que estar entrando y saliendo de la interrupción una y otra vez por c/bit.
 
Arriba