cancel
Showing results for 
Search instead for 
Did you mean: 

CANBus RX interrupts of HAL

wu ryan
Associate II

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__);

 }

}

4 REPLIES 4
T J
Lead

ABOM enable

use a transceiver, you need two physical CanBus controllers on the bus for correct operation, not loopback

T J
Lead

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.

RN
Senior

can you post your tx code ?

also error check UART TRANSMIT .

T J
Lead
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;
            }
    }
}