2017-02-20 09:49 PM
Hi,
I am trying to implement CAN Bus communication between two STMF072 boards and find that the communication will be lost randomly. While this situation occurs, the MCU routine loop also be stop just like chip hang-up.
The model is STM32F072-Discovery and here is my code.
===========================================================================
#include 'stm32f0xx_hal.h'
#include 'usb_device.h'
#include 'usbd_cdc_if.h'
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
uint32_t Timer_100ms = 0;
uint32_t Timer_Routing = 0;
uint32_t Flag_CAN_RX_item = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
void broadcast1(void)
{
TxMessage.DLC = 0;
HAL_CAN_Transmit_IT(&hcan);
}
void broadcast2(void)
{
TxMessage.DLC = 8;
TxMessage.Data[0] = 1;
TxMessage.Data[1] = 1;
TxMessage.Data[2] = 1;
TxMessage.Data[3] = 1;
TxMessage.Data[4] = 1;
TxMessage.Data[5] = 1;
TxMessage.Data[6] = 1;
TxMessage.Data[7] = 1;
HAL_CAN_Transmit_IT(&hcan);
}
void responding(void)
{
if (RxMessage.DLC == 8)
{
TxMessage.DLC = 1;
TxMessage.Data[0] = 1;
HAL_CAN_Transmit_IT(&hcan);
}
}
int main(void)
{
/* 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_CAN_Init();
MX_USB_DEVICE_Init();
if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
Timer_Routing = HAL_GetTick();
Timer_100ms = Timer_Routing;
/* Infinite loop */
while (1)
{
if (Flag_CAN_RX_item)
{
responding();
Flag_CAN_RX_item = 0;
}
// delay 100ms
if ((Timer_Routing - Timer_100ms) > 100)
{
#if 0
broadcast1();
#else
broadcast2();
#endif
// act LED to show routine loop
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
Timer_100ms = Timer_Routing;
}
Timer_Routing = HAL_GetTick();
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI48;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* CAN init function */
static void MX_CAN_Init(void)
{
CAN_FilterConfTypeDef sFilterConfig;
hcan.Instance = CAN;
hcan.Init.Prescaler = 9;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_13TQ;
hcan.Init.BS2 = CAN_BS2_2TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
sFilterConfig.FilterNumber = 1;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
hcan.pTxMsg->StdId = 0x3FC;
hcan.pTxMsg->ExtId = 0x01;
hcan.pTxMsg->RTR = CAN_RTR_DATA;
hcan.pTxMsg->IDE = CAN_ID_EXT;
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pins : PC8 PC9 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef *CanHandle)
{
// active LED to show CAN RX
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
Flag_CAN_RX_item = 1;
/* Receive */
if (HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler */
}
=====================================================
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
I write broadcast1() for one board and broadcast2() for the other, and build the related FW using #if in main().
Also, I try to trice this issue by debug mode viaKeil. When the issue is reproduced, code stop in Error_Handler() and it should be called only byHAL_CAN_Receive_IT() while main while routine. Are there any ideas?
Thanks for your reading.
#can #stm32f02017-02-20 11:28 PM
Hi
Weng.Frank
,No obvious idea on what is going wrong with your implementation (and may be hardware).
But I suggest you to test the example available in the STM32F0 packageSTM32Cube_FW_F0_V1.7.0\Projects\STM32072B_EVAL\Examples\CAN\CAN_Networking.
If this is not working for you also, so I recommend you check your HW.
If it gives you expected results, then try to compare your own implementation with the one in the provided example.
Hope this help you.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2017-02-21 05:58 AM
your filters are enabled but no bits are checked in the mask of 0x0000... ( not this problem, just pointing that out)
I did it differently, I doidnt use the
HAL_CAN_Transmit at all.
I initialized the CAN BUS within CubeMX, similarly to what you have done.
but I don't call the TX_IT , I poll the flags:
you must check that the fifos are not busy before you initiate the TX ( there are three fifos available, just checking one here, you should check all three)
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1) fifo busy ? { 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
}
�?�?�?
2017-07-05 12:39 PM
Hi ,
I am trying to run the CAN example on Nucleo-64 board (STM32F072). If I compile and download the project in processor, the program goes in the HAL_ERROR state and hangs up. I am new to CAN communication, and I have also tried the above code example on the same processor but it does not work for me.
I would really appreciate if someone can give me a link or example code for STM32F072 processor so that I can test the CAN communication.
Thanks
2017-07-06 08:34 PM
I had to pull up the Rx pin with a 1k resistor to stop it hanging.
but this is not needed if you have a CAN transceiver connected to the Rx pin.
did you check the correct pins are mapped ?
2017-07-07 07:59 AM
I have the PCAN USB connected, so that I can transmit and receive the packets from my PC. I have made sure the pins are mapped properly but it
gives me the time out error in checking the CAN MASTER STATUS REGISTER BIT (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)).
Here is my CAN init function:
/* CAN init function */
void MX_CAN_Init(void){ static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage; hcan.Instance = CAN; hcan.pTxMsg = &TxMessage; hcan.pRxMsg = &RxMessage; hcan.Init.Prescaler = 2; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SJW = CAN_SJW_3TQ; hcan.Init.BS1 = CAN_BS1_3TQ; hcan.Init.BS2 = CAN_BS2_4TQ; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = ENABLE; hcan.Init.AWUM = ENABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = ENABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{GPIO_InitTypeDef GPIO_InitStruct;
if(canHandle->Instance==CAN) { /* Peripheral clock enable */ __HAL_RCC_CAN1_CLK_ENABLE(); /**CAN GPIO Configuration PB8 ------> CAN_RX PB9 ------> CAN_TX */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_CAN; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}
}2017-07-07 05:50 PM
2017-07-11 08:36 AM
Thanks Marsh.nick for providing the example code.
It seems the hardware I have has some issues as it is not behaving normally. I will try to confirm that by using another hardware and see if I my code works on that.