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.