5 votos

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

Así que estoy en medio de mi primer PIC proyecto, y ha sido cuanto menos interesante. El problema que estoy teniendo es la configuración de los módulos CAN. El PIC que estoy usando tiene dos módulos ECAN. Usando los ejemplos de código proporcionados, he configurado 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 intento usar el mismo código con CAN2 (el segundo módulo del PIC). Transmite algunos datos, pero no el que he configurado en el búfer; todo lo que veo es 0x0000 en todo el paquete.

Mi código procede en su mayor parte de las notas de aplicación de ECAN, con algunos retoques de configuración. CAN1 funciona bien, pero CAN2 no. Cuando pido a ambos módulos que transmitan (CAN1 primero y luego CAN2), sólo CAN1 funciona, pero CAN2 no se mueve en absoluto (no tengo ni idea de por qué). Cuando apago CAN1 y sólo pido CAN2 para transmitir, como se mencionó anteriormente, funciona, pero sólo transmite 0 (parece que no está hablando con el DMA correctamente, a pesar de que estoy usando el mismo código probado y comprobado que he utilizado para CAN1).

Configurar DMA1 para transmisión CAN:

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

Ajustar la velocidad del bus CAN (Esta es una función de la biblioteca de periféricos):

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

Envía 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 utilizando el mismo código para ambos módulos. Sólo cambio los 1's por los 2's para los nombres de las direcciones. Por ejemplo, C1TR01CON para CAN1 se convierte en C2TR01CON para CAN2, etc.

0 votos

Estás utilizando dos motores DMA separados para los dos módulos CAN, ¿verdad?

0 votos

Sí, un DMA diferente para cada módulo.

1 votos

Después de horas y horas de prueba y error parece que he reducido a un fallo de dirección DMA (?). Cualquier DMA, cuando se configura para CAN2 parece generar una gran cantidad de basura mediante la lectura de la memoria intermedia especificada desde una extraña ubicación desplazada. No tengo ni idea de lo que está pasando: Por ejemplo, si cambio los bytes en el búfer en relación con los paquetes de datos, en lugar de la parte CAN ID del mensaje se ve afectada. Completamente perdido.

4voto

disappearedng Puntos 163

Argh, finalmente encontré lo que estaba mal. Inicializar el DMA para el módulo CAN (o de otro tipo) incluye:

  1. Apuntando al Registro de Periféricos --> lo había hecho correctamente

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

  3. Seleccionar el periférico requerido como fuente de interrupción para el DMA --> Lo había hecho 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! Cambiando esto a DMA1REQ = 71 para CAN2 ¡todo arreglado!

0 votos

Hola adil, estoy teniendo dificultades para configurar mi periférico ecan para DSPIC33EP64GS804, ¿es posible que usted comparta el código ECAN?

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X