SPI en problemas dsPIC33 y PPS

1

He estado intentando que SPI funcione en mi dsPic33FJ64MC802 durante unos días, por lo que necesito ayuda desesperadamente porque no parece que salga nada de SCK1 o SDO de acuerdo con el o-scope.

Esto es lo que estoy tratando de lograr:

  
  • SPI en modo maestro
  •   
  • no te importa sdi
  •   
  • debería poder ver sck o sdo en el oscope
  •   

Lo que noté que puede estar mal:

  
  • reconfigurar los pines no parece funcionar (he intentado desbloquearlos sin éxito)
  •   

Nunca encontré un ejemplo completo de SPI para la pic33 en línea, así que esto es lo que tengo de varios ejemplos:

#include "SPIUtils.h"
#include<spi.h>

// this may not be needed, I'm not sure
_FOSC(IOL1WAY_OFF);

unsigned int datard ;
void __attribute__((__interrupt__,auto_psv)) _SPI1Interrupt(void)
{
    IFS0bits.SPI1IF = 0;
}

void __attribute__((__interrupt__,auto_psv)) _SPI2Interrupt(void)
{
     IFS2bits.SPI2IF = 0;
     SPI1STATbits.SPIROV = 0; /* Clear SPI1 receive overflow
     flag if set */
}

// For dsPic33FJ64MC802 on a pic microstick
void SPITransmit() {
    //__builtin_disi(20); // need to disable interupts first?
    // PPS needs to first unlock the pins before re-assignment
   __builtin_write_OSCCONL(0x46); // unlock sequence - step 1
   __builtin_write_OSCCONH(0x57); // unlock sequence - step 2
    _IOLOCK = 0;

    // Pins can now change - though, these don't change in the SFR debugger window... why?
    _RP0R = 8;              // configure sck1 as output on pin 4 /RB0/RP0
    _RP1R = 7;              // configure sdo as output on pin 5 /RB1/RP1
    RPINR20bits.SCK1R = 4;  //configure sck1 as input on pin 4
    RPINR20bits.SDI1R = 6;  // configure SDI for input on pin 6

    // these change as expected in the debugger
    TRISBbits.TRISB0 = 0; //sck pin 4 as output
    TRISBbits.TRISB1 = 0; //sdo pin 5 as output
    TRISBbits.TRISB2 = 1; //sdi pin 6 as input

    /* Holds the information about SPI configuartion */
    unsigned int SPICONValue = 0;
    /* Holds the information about SPI Enable/Disable */
    unsigned int SPISTATValue = 0;

    /* Turn off SPI modules */
    CloseSPI1();
    CloseSPI2();
    TMR1 = 0;

    /* Configure SPI1 interrupt */
    ConfigIntSPI1(SPI_INT_EN & SPI_INT_PRI_6);

    /* Configure SPI1 module to transmit 16 bit timer1 value in master mode */
    SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT & ENABLE_SDO_PIN & SPI_MODE16_ON &
            SPI_SMP_OFF & SPI_CKE_OFF & SLAVE_ENABLE_OFF & CLK_POL_ACTIVE_HIGH &
            MASTER_ENABLE_ON & SEC_PRESCAL_7_1 & PRI_PRESCAL_64_1;
    SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR;

    // what is this third parameter..? the tools library does not mention it.
    // is this the problem? The two parameter OpenSPI1 is not available
    OpenSPI1(SPICONValue, SPISTATValue, 0);

    SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT & ENABLE_SDO_PIN & SPI_MODE16_ON &
            SPI_SMP_OFF & SPI_CKE_OFF & SLAVE_ENABLE_OFF & CLK_POL_ACTIVE_HIGH &
            MASTER_ENABLE_OFF & SEC_PRESCAL_7_1 & PRI_PRESCAL_64_1;
    SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR;
    OpenSPI2(SPICONValue, SPISTATValue, 0);

    // for the moment, I only care about monitoring data out and the clk in the
    // o-scope
    while (1) {
        // repeadtedly send out 10101..
        WriteSPI1(0xAAAA);
        while (SPI1STATbits.SPITBF);
    }

    // don't care about the input
//    while (!DataRdySPI2());
//    datard = ReadSPI2();
//    if (datard <= 600) {
//        PORTBbits.RB0 = 1;
//    }

    /* Turn off SPI module and clear IF bit */
    CloseSPI1();
    CloseSPI2();

    __builtin_write_OSCCONL(0x46); // unlock sequence - step 1
    __builtin_write_OSCCONH(0x57); // unlock sequence - step 2
    _IOLOCK = 1; // re-lock the ports
}

y utilízalo así:

#include <p33FJ64MC802.h>
#include <stdint.h>
#include <xc.h>
#include "main.h"
#include "BlinkLed.h"
#include "SPIUtils.h"
int main()
{
    //BlinkLedOnPortB(2, 8);
    SPITransmit();
    return 0;
}

No puedo decir qué demonios estoy haciendo mal. Esta es la foto microscópica.

    
pregunta roboto1986

1 respuesta

1

No necesita volver a asignar su periférico SPI dentro de SPITransmit (), esto solo debe hacerse una vez dentro de su main (), por ejemplo. Además, solo puede usar el periférico SPI una vez que la asignación de pines esté bloqueada. Lo que intentas hacer es transmitir mientras la asignación de pines está desbloqueada, por lo tanto, en esencia, tus pines no se han reasignado correctamente.

Prueba la sugerencia a continuación.

#include <p33FJ64MC802.h>
#include <stdint.h>
#include <xc.h>
#include "main.h"
#include "BlinkLed.h"
#include "SPIUtils.h"
int main()
{
    // PPS needs to first unlock the pins before re-assignment
    __builtin_write_OSCCONL(0x46); // unlock sequence - step 1
    __builtin_write_OSCCONH(0x57); // unlock sequence - step 2
    _IOLOCK = 0;

    // Pins can now change - though, these don't change in the SFR debugger window... why?
    _RP0R = 8;              // configure sck1 as output on pin 4 /RB0/RP0
    _RP1R = 7;              // configure sdo as output on pin 5 /RB1/RP1
    RPINR20bits.SCK1R = 4;  //configure sck1 as input on pin 4
    RPINR20bits.SDI1R = 6;  // configure SDI for input on pin 6

    __builtin_write_OSCCONL(0x46); // unlock sequence - step 1
    __builtin_write_OSCCONH(0x57); // unlock sequence - step 2
    _IOLOCK = 1; // re-lock the ports

    //BlinkLedOnPortB(2, 8);
    SPITransmit();
    return 0;
}
    
respondido por el Tinez

Lea otras preguntas en las etiquetas