2017-07-07 10:40 AM
Hi everyone,
I'm trying to receive a msg via CAN-bus in interrupt mode with STM32F105 mcu. I set the CAN filter so that only 0x0106 and 0x010A IDs are allowed. This is the first time I use this microcontroller so I'm not completely sure of the code. Can you help me?
/* Main Code*/
int main(void)
{/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();/* Configure the system clock */
SystemClock_Config();/* Initialize all configured peripherals */
MX_GPIO_Init(); MX_ADC1_Init(); MX_CAN1_Init(); MX_IWDG_Init(); MX_RTC_Init(); MX_SPI1_Init(); MX_TIM1_Init(); MX_TIM2_Init(); MX_UART4_Init(); MX_UART5_Init();/* USER CODE BEGIN 2 */
/* Initialize CAN Filter */ CAN_FilterConfTypeDef sFilterConfig; sFilterConfig.FilterNumber=0; sFilterConfig.FilterMode=CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale=CAN_FILTERSCALE_16BIT; sFilterConfig.FilterIdHigh=0x010A; sFilterConfig.FilterIdLow=0x0106; sFilterConfig.FilterMaskIdHigh=0x0000; sFilterConfig.FilterMaskIdLow=0x0000; sFilterConfig.FilterFIFOAssignment=0; sFilterConfig.FilterActivation=ENABLE; sFilterConfig.BankNumber=0; HAL_CAN_ConfigFilter(&hcan1,&sFilterConfig); if (HAL_CAN_ConfigFilter(&hcan1,&sFilterConfig) != HAL_OK) { Error_Handler(); }HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3); /* USER CODE END 2 *//* Infinite loop */
/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
/* Counts time, if no msg arrives after a certain time, assume something is broken and set arbitrarily to 75% the duty cycle */ HAL_CAN_Receive_IT(&hcan1,CAN_FIFO0);//other code..
HAL_Delay(delay);
} /* USER CODE END 3 */}
/* CAN1 init function */
static void MX_CAN1_Init(void){hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 11; 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) { Error_Handler(); }}
And in the interrupt section
void CAN1_RX0_IRQHandler(void)
{ /* USER CODE BEGIN CAN1_RX0_IRQn 0 *//* USER CODE END CAN1_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan1); /* USER CODE BEGIN CAN1_RX0_IRQn 1 *///my own code
HAL_Delay(delay);
/* USER CODE END CAN1_RX0_IRQn 1 */#stm32f105-can-bus2017-07-08 05:16 AM
I only enable the interrupt once. I catch the data before HAL does, so the interrupt stays active.
This saves a lot of reconfiguration which all takes some time.
do you get one frame ?
what is your current setting for these ?
sFilterConfig.FilterMaskIdHigh
sFilterConfig.FilterMaskIdlow
did you empty the fifos ?
I think this one should be enabled
hcan1.Init.ABOM = DISABLE
3.3 offline recoveryWhen TEC is equal to 255, the bxCAN is in the offline state, while the BOFF bit of the CAN_ESR register is set to '1'. In offline state, bxCAN can not receive and send messages.
According to the ABOM bits of the CAN_MCR register settings, bxCAN can automatically or in the request of the software, the recovery from the offline state (into the error of the active state). In these two cases, the bxCAN must wait for a recovery process described by a CAN standard (detected on the RX CAN pin 11 times the 128 successive hidden bits).
If the ABOM bit is' 1 ', bxCAN will automatically start the recovery process after entering the offline state.
If the ABOM bit is' 0 ', the software must first request the bxCAN to enter and then exit the initialization mode, and then the recovery process is turned on.2017-07-08 05:38 AM
Would you suggest then to remove HAL_CAN_Receive_IT from while(1) section like this?
HAL_CAN_Receive_IT(&hcan1,CAN_FIFO0);
while(1) {
//code
}
My board generates a PWM signal and its duty cycle is based on what I get via CAN. If nothing is received after a certain time, I assume something's wrong and I set the duty cycle to 75%. While testing my board, I saw no variation whatsoever in the duty cycle so my guess is that the MCU is not reading any message.
Both MaskIDHigh and MaskIDLow are set to 0xFF<<5 as Clive One told me.
I should enable the ABOM field and see what happens.
2017-07-08 05:43 AM
To enable only once, you must be sure to catch the data before the interrupt is satisfied, check my code above,
Yes please be sure, Both MaskIDHigh/Low are 0x7FF <<5, is that correct ?
2017-07-08 05:51 AM
Yes it's correct, those fields have the value you wrote.