Estoy usando un PIC32MX534F064L , y recién comencé a trabajar con el módulo CAN. Lo primero que intenté fue usar los ejemplos de Microchip. Ninguno de ellos funcionó. El problema básico es estas líneas:
CANSetOperatingMode(CAN1, CAN_NORMAL_OPERATION);
while(CANGetOperatingMode(CAN1) != CAN_NORMAL_OPERATION);
El while
en la segunda línea nunca se completa.
Te lo explicaré. El módulo CAN del PIC32 debe configurarse en el siguiente orden:
- Habilitar el módulo CAN.
- Cambie el módulo CAN al modo de operación "configuración".
- Configure el módulo CAN.
- Cambie el módulo CAN al modo de operación "normal".
Los pasos 2 y 4 son un poco más complicados. En lugar de simplemente establecer un registro que cambiaría el modo, hay un proceso de dos pasos. Establece un registro ( C1CON.REQOP
) para solicitar que el modo de operación ( C1CON.OPMOD
) cambiará, y cuando el módulo CAN está listo para cambiar, lo hace.
De todos modos, aquí está el código. Estoy seguro de que acabo de olvidar algo, pero el rastreo de Internet y el intento de varios ejemplos no han tenido resultados.
#include <plib.h>
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
#define SYS_FREQ (80000000L)
#define CAN_BUS_SPEED 250000
BYTE CAN1MessageFifoArea[2 * 8 * 16];
int main(void)
{
CAN_BIT_CONFIG canBitConfig;
CAN_OP_MODE mode;
int i;
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
CANEnableModule(CAN1,TRUE);
while(C1CONbits.ON == 0);
CANSetOperatingMode(CAN1, CAN_CONFIGURATION);
while(CANGetOperatingMode(CAN1) != CAN_CONFIGURATION);
canBitConfig.phaseSeg2Tq = CAN_BIT_3TQ;
canBitConfig.phaseSeg1Tq = CAN_BIT_3TQ;
canBitConfig.propagationSegTq = CAN_BIT_3TQ;
canBitConfig.phaseSeg2TimeSelect = TRUE;
canBitConfig.sample3Time = TRUE;
canBitConfig.syncJumpWidth = CAN_BIT_2TQ;
CANSetSpeed(CAN1,&canBitConfig,SYS_FREQ,CAN_BUS_SPEED);
CANAssignMemoryBuffer(CAN1,CAN1MessageFifoArea,(2 * 8 * 16));
CANConfigureChannelForTx(CAN1, CAN_CHANNEL0, 8,
CAN_TX_RTR_DISABLED, CAN_LOW_MEDIUM_PRIORITY);
CANConfigureChannelForRx(CAN1, CAN_CHANNEL1, 8,
CAN_RX_FULL_RECEIVE);
CANConfigureFilter (CAN1, CAN_FILTER0, 0x8004001, CAN_EID);
CANConfigureFilterMask (CAN1, CAN_FILTER_MASK0, 0x3FFFFFFF,
CAN_EID, CAN_FILTER_MASK_IDE_TYPE);
CANLinkFilterToChannel (CAN1, CAN_FILTER0, CAN_FILTER_MASK0, CAN_CHANNEL1);
CANEnableFilter (CAN1, CAN_FILTER0, TRUE);
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
CANEnableModuleEvent(CAN1, CAN_RX_EVENT, TRUE);
// The code gets stuck in the while and never finishes.
C1CONbits.CANBUSY = 1;
CANSetOperatingMode(CAN1, CAN_NORMAL_OPERATION);
while(CANGetOperatingMode(CAN1) != CAN_NORMAL_OPERATION);
// This code is never reached
i=0;
while(1)
++i;
}