¿Cómo configuro ambos módulos CAN en el PIC DSPIC33EP128GM604?

6

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.

    
pregunta Adil Malik

1 respuesta

4

Argh, finalmente encontré lo que estaba mal. La inicialización del DMA para el módulo CAN (o de otro modo) incluye:

  1. Apuntando al registro de periféricos - > Lo había hecho correctamente

  2. Apuntando a los buffers en uso --- > Yo también lo había hecho correctamente

  3. Seleccionando el periférico requerido como la fuente de interrupción para el DMA - > Hice esto correctamente para CAN1 ( DMA1REQ = 70; ), ¡pero no lo cambié cuando copié el código para configurar el DMA para CAN2 que era IRQ 71 y no 70! ¡Cambiar esto a DMA1REQ = 71 para CAN2 lo solucionó todo!

respondido por el Adil Malik

Lea otras preguntas en las etiquetas