Así que estoy en medio de mi primer proyecto PIC , y ha sido interesante, como mínimo. El problema que tengo es configurar los módulos CAN. El PIC que estoy usando tiene dos módulos ECAN. Usando los ejemplos de código provistos, configuré CAN1 (módulo 1) para transmitir un mensaje, y funciona absolutamente bien. Puedo ver la señal en el pin de E / S designado.
El problema es cuando trato de usar el mismo código con CAN2 (el segundo módulo en el PIC). Transmite algunos datos, pero no el que configuré en el búfer; Todo lo que veo es 0x0000 en todo el paquete.
Mi código es principalmente de las notas de la aplicación ECAN, con mis pocos ajustes de configuración. CAN1 funciona bien, pero CAN2 no. Cuando le pido a ambos módulos que transmitan (primero CAN1 y luego CAN2), solo funciona CAN1, pero CAN2 no se mueve en absoluto (no tengo idea de por qué). Cuando desactivo CAN1 y solo le pido a CAN2 que transmita, como se mencionó anteriormente, funciona, pero solo transmite 0 (parece que no está hablando correctamente con el DMA, aunque estoy usando el mismo código probado y comprobado que Utilicé para CAN1).
Configure DMA1 para CAN transmitir:
DMA1CONbits.SIZE = 0x0;
DMA1CONbits.DIR = 0x1; //From peripheral to DMA
DMA1CONbits.AMODE = 0x2;
DMA1CONbits.MODE = 0x0;
DMA1REQ = 70;
DMA1CNT = 7; //Data length
DMA1PAD = (volatile unsigned int) &C1TXD; //Point to peripheral register
DMA1STAL = (unsigned int) &CAN1MsgBuf; //Point to buffer
DMA1STAH = (unsigned int) &CAN1MsgBuf; //Point to buffer
DMA1CONbits.CHEN = 0x1; //Enable
Establezca la velocidad del bus CAN (Esta es una función de biblioteca periférica):
CAN1Initialize(CAN_SYNC_JUMP_WIDTH2 &
CAN_BAUD_PRE_SCALE(4),
CAN_WAKEUP_BY_FILTER_DIS &
CAN_PHASE_SEG2_TQ(3) &
CAN_PHASE_SEG1_TQ(3) &
CAN_PROPAGATIONTIME_SEG_TQ(3) &
CAN_SEG2_FREE_PROG &
CAN_SAMPLE1TIME); //CAN-IN
Enviar los datos:
C1TR01CONbits.TXEN0 = 0x1;
C1TR01CONbits.TX0PRI = 0x3;
/* At this point the ECAN1 module is ready to transmit a message. Place the ECAN module in
Normal mode. */
C1CTRL1bits.REQOP = 0;
while (C1CTRL1bits.OPMODE != 0)
;
/* Write to message buffer 0. */
/* CiTRBnSID = 0bxxx1 0010 0011 1100
IDE = 0b0
SRR = 0b0
SID<10:0>= 0b100 1000 1111 */
unsigned int ID = 0xB1;
CAN1MsgBuf[0][0] = ID<<2;
/* CiTRBnEID = 0bxxxx 0000 0000 0000
EID<17:6> = 0b0000 0000 0000 */
CAN1MsgBuf[0][1] = 0x0000;
/* CiTRBnDLC = 0b0000 0000 xxx0 1111
EID<17:6> = 0b000000
RTR = 0b0
RB1 = 0b0
RB0 = 0b0
DLC = 0b1111 */
CAN1MsgBuf[0][2] = 0x0008;
/* Write message data bytes */
CAN1MsgBuf[0][3] = 0xabcd;
CAN1MsgBuf[0][4] = 0xabcd;
CAN1MsgBuf[0][5] = 0xabcd;
CAN1MsgBuf[0][6] = 0xabcd;
/* Request message buffer 0 transmission */
C1TR01CONbits.TXREQ0 = 0x1;
/* The following shows an example of how the TXREQ bit
can be polled to check if transmission is complete. */
while (C1TR01CONbits.TXREQ0 == 1)
;
/* Message was placed successfully on the bus. */
Estoy usando el mismo código para ambos módulos. Solo cambio el 1 al 2 para los nombres de las direcciones. Por ejemplo, C1TR01CON para CAN1 se convierte en C2TR01CON para CAN2, etc.