SPI PIC16F886 muy sensible con NRF24l01 +

2

En primer lugar, han pasado 2 años desde que toqué cualquier cosa excepto mbed o ardunio, así que hay una gran posibilidad de que haya hecho algo tonto para causar los problemas que estoy viendo.

Tengo un PIC16F886 en una placa de pruebas con una tapa de 1nF en Vdd y GND. Conectado al SPI hay un NRF24l01 + en una placa de conexiones, tengo un adaptador serie a USB en el EUSART y el PICkit2 conectado a los puertos ICSP. Estoy usando una versión modificada de la biblioteca nrf de la serie de tutoriales diyembedded.com.

El PIC se está ejecutando desde INTOSC a 4MHz y SPI es 4Mhz / 64 (62500, muy lento). La configuración se muestra en la siguiente imagen:

MiproblemaeslainterfazconelNRF:elbusSPIesmuytemperamentalysensiblealtacto.CuandomecomunicoconelNRF,siemprepuedoleersuregistrodeESTADOcomo0x0E,sinembargo,laCONFIGURACIÓNesmásamenudoquenosiempre0x00,aveces0xC5o0xC6ymuyraramente0x08(elresultadoesperosegúnlahojadedatos).SimetounasondadealcanceenelpuertoMOSIenlafoto(comosemuestraenlaimagendearriba),entoncesobtengo0x08demaneraconsistente,sinembargo,latrazaeshorrible(veracontinuación)yconfrecuenciatienepicosgrandes,amboscanalesconfiguradosa2V/sqybasedetiempo10uS.ElrastreoenelMISOesclaro,nítidoydeamplitudcompleta.

¿Alguien tiene algún pensamiento? ¿Es este chip demasiado sensible para ser usado en una tabla de pruebas de esta manera? ¿He arruinado algo básico en el PIC configurado para causar algunos problemas terribles para el SPI? Me encantaría crear mis propios PCB, pero por varias razones no es una opción ahora, por lo que me gustaría seguir con el tablero.

¡Gracias!

Código abajo para completar:

Main.c

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF       
#pragma config PWRTE = OFF      
#pragma config MCLRE = OFF   
#pragma config CP = OFF      
#pragma config CPD = OFF     
#pragma config BOREN = OFF   
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

// CONFIG2
#pragma config BOR4V = BOR21V
#pragma config WRT = OFF     

//general defines
#define _XTAL_FREQ 4000000

//SPI Pin
#define  nCS   RC1 //csn pin for nrf


//main libraries
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "../libraries/SPILibrary16F886.h"
#include "../libraries/nrf24l01.h"

/***
  Serial port set to 9600 baudrate
***/
void enableSerialPort(){
  //init SPBRGH/SPBRG/BRGH/BRG16
  TXSTAbits.BRGH = 1; //0 for 8 MHz
  BAUDCTLbits.BRG16 = 0;
  SPBRGH = 0;
  SPBRG = 25; //12 for 8MHz
  //clear SYNC, set SPEN
  TXSTAbits.SYNC = 0;
  RCSTAbits.SPEN = 1;
  //set TXEN
  TXSTAbits.TXEN = 1;
}

/***
  putch() required for printf() to work

  currently works by polling the TRMT bit so blocks main thread
***/
void putch(char c){
  while(TRMT == 0)continue;
    TXREG = c;
}

int main(int argc, char** argv) {

  unsigned char status = 0, config = 0;

  //setup oscilator
  OSCCONbits.IRCF = 0b110; //111 = 8Mhz

  //main variables
  enableSerialPort();

  TRISCbits.TRISC0 = 0; //set CE for nrf to ouput
  TRISCbits.TRISC1 = 0; // set CSN for nrf to output
  TRISCbits.TRISC2 = 1; //set IRQ for nrf to input

  nCS = 1; //set CSN bit

  __delay_ms(100);

  if(!initSPI(1, 64, 'm')){ //set up SPI
    printf("SPI enabled\n");
  }

  SPIOn();

  nrf24l01_initialize_debug(false, 1, false); //initialize the 24L01 to the debug configuration as TX, 1 data byte, and auto-ack disabled

  //main loop start
  for(;;){

    status = nrf24l01_get_status();
    config = nrf24l01_get_config();

    printf("S = %x, C = %x\n", status, config);
    __delay_ms(200);


  }//main loop end

  return(EXIT_SUCCESS);
}

SPILibrary16f886.c

#include <xc.h>
#include "SPILibrary16F886.h"
void SPIOn(){
  SSPEN = 1;
  SSPIE = 1;
}

int initSPI(int mode, int clockDivide, char masterSlave){
  //set up SPI master or slave
  if(masterSlave == 'm'){
    if(clockDivide == 4)
      SSPCON = SSPCON & 0b11110000; //master, clock/4
    else if(clockDivide == 16){
      SSPCON = SSPCON & 0b11110000; //master clock/16
      SSPCON = SSPCON | 0b00000001;
    }
    else if(clockDivide == 64){
      SSPCON = SSPCON & 0b11110000; //master clock/64
      SSPCON = SSPCON | 0b00000010;
    }
    else{
      return 1; //error code 1
    } 

  }
  if(masterSlave == 's'){
    SSPCON = SSPCON & 0b11110000; //clear the lsb
    SSPCON = SSPCON | 0b00000100; //nSS enabled in slave mode
    SMP = 0;
  }
  //set up SPI mode
  if(mode == 1){
    CKE = 1;
    CKP = 0;  
  }
  else if(mode == 2){
    CKE = 0;
    CKP = 0;
  }
  else if(mode == 3){
    CKE = 1;
    CKP = 1;
  }
  else if(mode == 4){
    CKE = 0;
    CKP = 1;
  }
  else
    return 2;   //error code 2

  //set up interrupts
  SSPIE = 1;
  TRISC3 = 0; // 0 = output for sck
  return 0;
} 

unsigned char writeSPIByte(unsigned char data)
{
  SSPSTATbits.BF = 0;
  unsigned char i;
  SSPBUF = data;
  while(SSPSTATbits.BF == 0){}
  return SSPBUF;
} 
unsigned char readSPIByte(void){
  writeSPIByte(0x00);
  return SSPBUF;
} 

void writeSPIWord(unsigned short int setting)
{
    writeSPIByte(setting >> 8);
    writeSPIByte(setting);
}
void readSPIWord(){
  readSPIByte();
  readSPIByte();
}
void SPIOff(){
  SSPEN = 0;
}

ACTUALIZACIÓN 1:

Entonces, basado en los comentarios de jippie (¡¿Agregué un menú desplegable a MISO ?! y un límite de 100 nF en Vdd-Gnd) Ahora puedo hacer que nrf lea continuamente 0xE para el registro ESTATUS y luego 0x8 para el registro CONFIG. He intentado leer otros registros, incluido EN_AA que tiene la dirección 0x01 (es decir, el siguiente después de CONFIG que tiene la dirección 0x00) y todavía devuelve 0x8. Mi teoría es que la línea MOSI es un desorden (traza amarilla en la imagen de arriba). el nrf está simplemente cambiando el ESTADO seguido de la CONFIGURACIÓN independientemente de la instrucción realmente enviada porque todo lo que está recibiendo son 16 pulsos de reloj y con 0s en el pin MOSI. También he manejado RC5 (el pin MOSI) como una salida normal y tiene un rango completo cuando no está conectado a nada, por lo que el pin funciona bien desde ese punto de vista.

    
pregunta SimonBarker

1 respuesta

2

Resuelto!

Con un poco de ayuda de aquí y del foro de microchips parece que me olvidé de borrar mi bit TRISC5 y hacer MOSI y salir en la sección 13.2.2 de la hoja de datos, recuerdo haberlo leído, pero por alguna razón pensé que al igual que el SDI, el módulo MSSP estableció el SDO TRIS. Tiene sentido que no lo haga, ya que es posible que solo desee registrar los datos y no usar MOSI.

    
respondido por el SimonBarker

Lea otras preguntas en las etiquetas