2018-08-10 03:05 AM
This is my RX callback,it only can run one time, anything I set wrong?
I use it in LOOPBACK mode.
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
Response=(uint8_t *)&hcan->pRxMsg->Data;
HAL_UART_Transmit(&huart4,Response, 8, 5);
HAL_CAN_Receive_IT(hcan,CAN_FIFO0);
}
static void MX_CAN_Init(void)
{
hcan.Instance = CAN;
hcan.Init.Prescaler = 2;
hcan.Init.Mode = CAN_MODE_LOOPBACK;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_14TQ;
hcan.Init.BS2 = CAN_BS2_5TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
2018-08-10 03:25 AM
ABOM enable
use a transceiver, you need two physical CanBus controllers on the bus for correct operation, not loopback
2018-08-11 01:38 PM
maybe you could purchase a USB Can Transceiver, then work your receiver code first.
I used a CanDo unit from UK, set it to transmit every second, it took two days to get the RxTx interrupts all working correctly.
2018-08-11 07:54 PM
can you post your tx code ?
also error check UART TRANSMIT .
2018-08-11 08:19 PM
void checkCanTxMsgs(void) {
// this is a non-ordered packet transmitter.
//int canMsgCounter =0;
if(!canTxMsgTableEMPTY) {
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // non-ordered packet transmitter
{
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1)
{
if (showRxCanFrames)
sendCanTxFrametoConsole();
CAN->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
CAN->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID[canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); // (4) // send it now if the line is idle
// destroy old data to be sure we only transmit fresh data
// not needed
canTxMsgLength[canTxMsgOUT] = 0;
canTxMsgBottomWord[canTxMsgOUT] = 0;
canTxMsgTopWord[canTxMsgOUT] = 0;
canTxMsgID[canTxMsgOUT++] = 0;
canTxMsgOUT &= 0x3F; // 64 buffer elements
canTxMsgTableFULL = false;
canTxMsgOverrun = false;
//canMsgCounter ++;
}
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL)
if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) // (1)
{
if (showRxCanFrames)
sendCanTxFrametoConsole();
CAN->sTxMailBox[1].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
CAN->sTxMailBox[1].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[1].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[1].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI1R_TXRQ); // (4) // send it now if the line is idle
// destroy old data to be sure we only transmit fresh data
// not needed
canTxMsgLength[canTxMsgOUT] = 0;
canTxMsgBottomWord[canTxMsgOUT] = 0;
canTxMsgTopWord[canTxMsgOUT] = 0;
canTxMsgID[canTxMsgOUT++] = 0;
canTxMsgOUT &= 0x3F; // 64 buffer depth
canTxMsgOverrun = false;
canTxMsgTableFULL = false;
//canMsgCounter ++;
}
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL)
if ((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) // (1)
{
if (showRxCanFrames)
sendCanTxFrametoConsole();
CAN->sTxMailBox[2].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
CAN->sTxMailBox[2].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[2].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
CAN->sTxMailBox[2].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI2R_TXRQ); // (4) // send it now if the line is idle
// destroy old data to be sure we only transmit fresh data
// not needed
canTxMsgLength[canTxMsgOUT] = 0;
canTxMsgBottomWord[canTxMsgOUT] = 0;
canTxMsgTopWord[canTxMsgOUT] = 0;
canTxMsgID[canTxMsgOUT++] = 0;
canTxMsgOUT &= 0x3F; // 64 buffer elements
canTxMsgOverrun = false;
canTxMsgTableFULL = false;
//canMsgCounter ++;
}
if (canTxMsgOUT == canTxMsgIN) canTxMsgTableEMPTY = true;
}
}
}