2021-08-26 10:14 AM
I am running CAN1 on a STM32F415 processor to communicate with an ECU and several other 415's on the bus. I have the SCE handler set up to store last error codes (LEC). I don't seem to be having any problems with the receive but the transmit side is getting frame and bit recessive errors. It happens every few seconds when I only have one module on the bus (5-6% bus loading) , but as I increase the modules and traffic (30-40% bus load), the TEC starts climbing and the higher addressed modules start getting into bus off range and must reset. I do have the bus properly terminated at each end and the ECU on the bus isn't having any issues.
-250kBps CAN speed
-Are the recessive errors due to being trumped by higher priority messages?
-Do the frame errors mean that my bus timing is slightly off?
I do have an oscilloscope and can look at outgoing messages from my device, but wasn't sure I would catch anything since it is intermittent at low traffic rates. I also have PCAN usb to can adapter to watch messages. I did hook up just the PCAN monitor and the module so they were the only things on the bus. It still gets occassional Tx errors.
[CAN Init Routine]
//*****************CAN 1 SETUP*********************
GPIO_InitTypeDef GPIO_InitStructure;
uint32_t filter_id, filter_mask;
filter_id=0x20000;
filter_mask=0x00000000;
/* CAN1 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//GPIO setup
//CAN Setup CANRX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//CAN Setup CANTX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//Connect GPIO pins to peripheral
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1);
// CAN1 register init
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
// CAN1 cell init
CAN_InitStructure.CAN_TTCM = DISABLE; // time-triggered communication mode = DISABLED
CAN_InitStructure.CAN_ABOM = DISABLE; // automatic bus-off management mode = DISABLED
CAN_InitStructure.CAN_AWUM = DISABLE; // automatic wake-up mode = DISABLED
CAN_InitStructure.CAN_NART = DISABLE; // non-automatic retransmission mode = DISABLED
CAN_InitStructure.CAN_RFLM = DISABLE; // receive FIFO locked mode = DISABLED
CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority = DISABLED
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
// CAN1 Baudrate = 250kbps
// APB2 Clock is divided by 4, so 168/4=42MHz
// CAN_Prescaler value= CAN_clock/(required_Baudrate*total_number_of_tq)
// In present case, total_number_of_tq=CAN_SJW_1tq+CAN_BS1_3tq+CAN_BS2_2tq=6*tq
// so CAN_Prescaler= 42MHz/(250kbps*6)=28
CAN_InitStructure.CAN_Prescaler = 28;
if(CAN_Init(CAN1, &CAN_InitStructure)==CANINITOK)
{
}
filter_id= CAN_DEVICETYPEADDRESS;
filter_mask=0X1FCC0000; //This mask ignores the last 4 digits and bottom 2 bits of the 6th nibble
uint16_t CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow;
CAN_FilterIdHigh = ((filter_id & 0x07FF0000) >> 13) | ((filter_id & 0x0000FFFF) >> 13) ; // STID[10:0] & EXTID[17:13]
CAN_FilterIdLow = ((filter_id & 0xFFFF) << 3) & 0xFFF8; // EXID[12:5] & 3 Reserved bits
CAN_FilterMaskIdHigh = ((filter_mask & 0x07FF0000) >> 13) | ((filter_mask & 0x0000FFFF) >> 13) ;
CAN_FilterMaskIdLow = ((filter_mask & 0xFFFF) << 3) & 0xFFF8;
// CAN filter init
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterIdHigh;
CAN_FilterInitStructure.CAN_FilterIdLow = CAN_FilterIdLow;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = CAN_FilterMaskIdHigh;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = CAN_FilterMaskIdLow;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);