Estoy tratando de recibir marcos CAN en un STM32F412G-DISCOVERY con un transceptor SN65HVD233, transmitido desde un dispositivo USB2CAN. Ambos están conectados en un bus de unos 15 cm de largo con dos resistencias de 120 Ω en cada extremo.
Conecté un osciloscopio para leer los pines RX y TX en la placa STM32 antes de que el transceptor los transforme. Cuando configuro el controlador CAN en modo silencioso y envío un marco CAN desde el USB2CAN usando:
$ cansend can0 '144#25'
Veo en el osciloscopio en el pin RX el cuadro completo (el amarillo es el RX de la placa, el azul es el TX):
NB: el cursor indica el intervalo de tiempo de un bit (2 µs, la tasa de bits es de 500 kb/s).
(La HAL_CAN_Receive
llamada sigue agotando el tiempo de espera, pero ese es otro problema). Pero cuando pongo el controlador en modo normal, esto es lo que mido:
Y aquí está el código:
hcan1.pTxMsg = &g_out_msg;
hcan1.pRxMsg = &g_in_msg;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 12;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_1TQ;
hcan1.Init.BS2 = CAN_BS2_1TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
fatal_error("failed to init HAL CAN.");
CAN_FilterConfTypeDef sFilterConfig;
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
fatal_error("failed to setup CAN filter.");
HAL_StatusTypeDef can_status;
if ((can_status = HAL_CAN_Receive(&hcan1, CAN_FIFO0, 20000)) != HAL_OK)
fatal_error("failed to receive frame: %d", can_status);
Parece que el emisor (USB2CAN) intentó escribir un recesivo (1) para el 2do bit del ID mientras que el receptor (STM32) envió un dominante (0): el emisor detectó esa colisión y dejó de emitir.
¿Por qué el controlador STM32 CAN envió ese bit dominante que detuvo la comunicación?
Un desajuste de tiempo.
El STM32 emite un indicador de error. ¿Por qué otra razón transmitiría algo directamente después de los primeros bits?
Se supone que el cuadro de error tiene una longitud de 6 bits, pero en su imagen el ancho de los cursores no cabe en el cuadro tx 6 veces. Lo que significa que los controladores no usan la misma tasa de bits.
Lesenk
Lesenk
Lesenk