Error de confirmación del bus CAN

0

Estoy utilizando un programa de bus CAN STM32F429 con TJA1041A como transceptor CAN. El problema es que los mensajes no se reconocen y adjunto el código adjunto para futuras consultas. Estoy usando PCAN-View para ver los mensajes. ¿Hay fallas en este código?

int main(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

    // SystemInit();

    GPIO_InitTypeDef GPIO_InitDef;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    GPIO_InitDef.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
    GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
    GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitDef);

    /* Connect CAN pins to AF */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); // CAN2_RX
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); // CAN2_TX

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
    GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;

    /* Connect PD5 and PD7 pins for CAN transceiver to enable and
       standby. */

    GPIO_Init(GPIOD, &GPIO_InitDef);
    GPIO_SetBits(GPIOD, GPIO_Pin_5|GPIO_Pin_7);

    RCC_ClocksTypeDef     RCC_Clocks;
    CAN_InitTypeDef       CAN_InitStructure;
    CAN_FilterInitTypeDef CAN_FilterInitStructure;

    RCC_GetClocksFreq(&RCC_Clocks);

    CAN_DeInit(CAN2);

    CAN_StructInit(&CAN_InitStructure);

    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal ;

    /* Quanta 1+14+6 = 21, 21 * 4 = 84, 42000000 / 84 = 5000000 */
    /* CAN Baudrate = 500 kbit/s (CAN clocked at 42 MHz). Prescale = 4 */

    /* Requires a clock with integer division into APB clock */

    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 1 + 6 + 7  = 14,  1 + 14 + 6 = 21,
                                             // 1 + 15 + 5 = 21
    CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
    CAN_InitStructure.CAN_Prescaler = 4; // Quanta by Baudrate - 125 kbit/s.

    CAN_Init(CAN2, &CAN_InitStructure);

    /* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // IdMask or IdList

    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit; // 16 or 32

    CAN_FilterInitStructure.CAN_FilterIdHigh      = 0x0000; // Everything, otherwise 11-bit in top bits

    CAN_FilterInitStructure.CAN_FilterIdLow       = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0x0000;

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // Rx
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

    //CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN1 [ 0..13]

    //CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_FilterInitStructure.CAN_FilterNumber = 14; // CAN2 [14..27]

    CAN_FilterInit(&CAN_FilterInitStructure);
    CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

    CanTxMsg TxMessage;

    // Transmit */
    TxMessage.StdId = 0x321;
    TxMessage.ExtId = 0x00;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 8;

    TxMessage.Data[0] = 0x02;
    TxMessage.Data[1] = 0x11;
    TxMessage.Data[2] = 0x11;
    TxMessage.Data[3] = 0x11;

    while(1)
    {
        uint32_t i;
        int j = 0;
        uint8_t TransmitMailbox = 0;

        TxMessage.Data[4] = (j >>  0) & 0xFF; // Cycling
        TxMessage.Data[5] = (j >>  8) & 0xFF;
        TxMessage.Data[6] = (j >> 16) & 0xFF;
        TxMessage.Data[7] = (j >> 24) & 0xFF;
        j++;

        TransmitMailbox = CAN_Transmit(CAN2, &TxMessage);

        i = 0;
        while (  (CAN_TransmitStatus(CAN2, TransmitMailbox) != CANTXOK) &&
                 (i != 0xFFFF)
              ) // Wait on transmit
        {
            i++;
            CAN2RX(); // Pump RX
        }
    }
}
    
pregunta user2870154

1 respuesta

1

Si su código está enviando un mensaje, debe obtener ACK. Ponga un alcance en las líneas y vea si el problema no está enviando, o un problema eléctrico que impida los niveles de señal correctos.

Los dos errores habituales que las personas cometen para no obtener ACK son si se olvidan de conectar al menos otro dispositivo al bus y se olvidan de colocar las resistencias de terminación en el bus. Si desea que otro dispositivo envíe ACK, tiene que haber otro dispositivo. A pesar de que es descaradamente obvio, es un pedo cerebral sorprendentemente común según mis observaciones.

En cuanto a los terminadores, no son opcionales. Sí, funcionan para reducir los reflejos de los extremos del bus y, en ese sentido, se puede depurar un bus corto sin ellos. Sin embargo, también juntan las líneas del autobús para que el autobús se encuentre en estado recesivo cuando no hay nada que lo conduzca activamente. Esto no es opcional. Esto es muy parecido a que la resistencia de pull-up en un bus de colector abierto no es opcional. Los terminadores son resistencias de acoplamiento en lugar de pull-up, pero no pueden omitirse por el mismo motivo.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas