Receive CAN msg in interrupt mode with STM32F105 mcu
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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-bus- Labels:
-
CAN
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 10:47 AM
sFilterConfig.FilterMode=CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale=CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh=0x10A << 5; // Standard ID top 11-bits
sFilterConfig.FilterIdLow=0x106 << 5;
sFilterConfig.FilterMaskIdHigh=0x7FF << 5; // It is a MASK, remember something AND'd with zero is ZERO
sFilterConfig.FilterMaskIdLow=0x7FF << 5;
>>
This is the first time I use this microcontroller so I'm not completely sure of the code.
Reading and understanding the relevant parts of the Reference Manual will help considerably.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 12:49 PM
Thinking this is nonsense. What on earth is the baud rate here?
hcan1.Init.Prescaler = 11;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_1TQ;
hcan1.Init.BS2 = CAN_BS2_1TQ;
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 12:53 PM
This is code automatically generated with STM32CubeMX. The baudrate I wanted to set is 1Mbps and with the program I mentioned before I set the Prescaler so that the Time for One Bit is 1031ns
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 2:06 PM
If the APB is clocking at 36 MHz you've achieved 1.091 Mbps
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 2:23 PM
The APB frequence is 32Mhz, after checking some documentation online my choice is Prescaler=4, Time Quanta in Bit Segment 1=6 and Time Quanta in Bit Segment 2=1.
If I'm not mistaken, thanks to the HAL_Receive_IT function when a msg arrives the micro checks the can's routine which is CAN1_RX0_IRQHandler, isn't it? The way I used these functions is correct?
Thanks for your patience, I realize these questions may be stupid but as I mentioned before this is my very first time programming a microcontroller, so I still have to learn many things
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-07 7:06 PM
I have this for my receive interrupt:
void CEC_CAN_IRQHandler(void)
{ /* USER CODE BEGIN CEC_CAN_IRQn 0 */ CAN_IRQFlag = true; checkCanRxFifos();/* USER CODE END CEC_CAN_IRQn 0 */
HAL_CAN_IRQHandler(&hcan); /* USER CODE BEGIN CEC_CAN_IRQn 1 *//* USER CODE END CEC_CAN_IRQn 1 */
}checkCanRxFifos
is how I pull the data from the fifos, before HAL upsets my flags...
void checkCanRxFifos(void){ int readCanBytecount; char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1; if(canFifo1FullFlag){ { readCanBytecount = (CAN->sFIFOMailBox[1].RDTR &0x0f); canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDLR; canRxMsgTopWord [canRxMsgIN] = CAN->sFIFOMailBox[1].RDHR;canRxMsgID [canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
CAN->RF1R |= CAN_RF1R_RFOM1; // release FIFOcanRxMsgLength [canRxMsgIN] = readCanBytecount; // was 0x10+ to signify FIFO1
++ canRxMsgIN &= 0x3F; // 16 entries only canRxMsgTableEMPTY = false; if( canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;}
CAN->IER |= CAN_IER_FMPIE1; // (11) Set FIFO1 message pending IT enable }char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
if(canFifo0FullFlag){ { readCanBytecount = (CAN->sFIFOMailBox[0].RDTR &0x0f);canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDLR;
canRxMsgTopWord [canRxMsgIN] = CAN->sFIFOMailBox[0].RDHR;uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
CAN->RF0R |= CAN_RF0R_RFOM0; // release FIFOif ( canRxMsgTableFULL){
canRxMsgTableOverflow = true; // now dump new frame... }else{ canRxMsgID [canRxMsgIN] = canRxmsgID; canRxMsgLength [canRxMsgIN] = readCanBytecount; // to signify FIFO0 ++ canRxMsgIN &= 0x3F; // 16 entries only canRxMsgTableEMPTY = false; if( canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true; } // show data//length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]);
// for( int i = 0; i < readCanBytecount; i++){// // canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i]; // canRxpointerIN &= 0xFF;// if (canRxpointerIN == canRxpointerOUT ) CanRxbufferOverrun = true;// //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]);// }//sprintf(string + length -2,'\n\r'); // remove 2 bytes, the last comma and space
//canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0; } CAN->IER |= CAN_IER_FMPIE0; // (11) Set FIFO1 message pending IT enable }// if (length >0) puts(string);}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-08 2:37 AM
I think the code you posted is already implemented inside the functions called in HAL_CAN_IRQHandler(&hcan1) inside the interrupt section. When I tested my board it seems like it never executes the interrupt routine, and I think that's because of my lines of code. The problem is there are some examples but they refer to the STM32F103 and I don't know if they're valid for the STM32F105 too
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-08 3:09 AM
I run this before the while(1)
//init interrupts;
__HAL_CAN_ENABLE_IT (&hcan, CAN_IT_FMP1);
__HAL_CAN_ENABLE_IT (&hcan, CAN_IT_FMP0);- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-07-08 3:52 AM
These enable are already present in the HAL_CAN_Receive_IT function, so I don't think that's what doesn't allow me to receive any message
