2017-03-27 09:54 AM
Hi everyone, I�m using a STM32F103 with SW4STM32 and CubeMX and I`m struggeling with the CAN Communication. When I`ll try to transmit Data with HAL_CAN_Transmit then I get a timeout error. Like I read here in other threads it could be a bug from the HAL library but I dont`t know how to solve this problem. Or it could be a problem with my code. So I hope someone can help me.
Here is my code. If you need some other parts of it I`ll post it too.
Thanks for your support
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_SPI1_Init(); MX_USART1_UART_Init(); MX_CAN_Init();/* USER CODE BEGIN 2 */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */ HAL_GPIO_WritePin(GPIOD, USBEnable_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, canRS_Pin, GPIO_PIN_SET); HAL_UART_Receive_IT(&huart1,&Rx_data, 1); printf('welcome\r\n');uint16_t SOC = 5500;
uint16_t BatVoltage = 590; uint16_t cellVoltageMax = 3900; uint16_t cellVoltageMin = 3800; uint8_t tempMax = 50; uint8_t tempMin = 47;while (1)
{ printf('Test\r\n');hcan.pTxMsg->Data[0] = 0b01110000;
hcan.pTxMsg->Data[1] = (uint8_t) (SOC/1000); hcan.pTxMsg->Data[2] = (uint8_t) ((BatVoltage & 0b111111111111) >> 4); hcan.pTxMsg->Data[3] = (uint8_t) (((BatVoltage << 12) | ((cellVoltageMax & 0b0001111000000000) >> 1)) >> 8); hcan.pTxMsg->Data[4] = (uint8_t) (((cellVoltageMax & 0b0000000111110000) >> 1) | ((cellVoltageMin & 0b0001110000000000) >> 10)); hcan.pTxMsg->Data[5] = (uint8_t) (((cellVoltageMin & 0b0000001111110000) >> 2) | (tempMax >> 6)); hcan.pTxMsg->Data[6] = (uint8_t) ((tempMax << 2) | (tempMin >> 6)); hcan.pTxMsg->Data[7] = (uint8_t) (tempMin << 2);printf('Data[0]: %d\r\n', hcan.pTxMsg->Data[0]);
if (HAL_CAN_Transmit(&hcan, 10) != HAL_OK)
{ /* Transmition Error */ //Error_Handler(); printf('CAN Transmit Error\r\n'); } printf('%d\r\n', HAL_CAN_GetState(&hcan)); HAL_Delay(1000); /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */}
/** System Clock Configuration
*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;/**Initializes the CPU, AHB and APB busses clocks
*/ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); }/**Initializes the CPU, AHB and APB busses clocks
*/ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{ Error_Handler(); }HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_1);
/**Configure the Systick interrupt time
*/ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);/**Configure the Systick
*/ 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; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage;hcan.Instance = CAN1;
hcan.pTxMsg = &TxMessage; hcan.pRxMsg = &RxMessage;hcan.Init.Prescaler = 4;
hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SJW = CAN_SJW_2TQ; hcan.Init.BS1 = CAN_BS1_12TQ; hcan.Init.BS2 = CAN_BS2_5TQ; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = ENABLE; hcan.Init.AWUM = ENABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = DISABLE; 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(); }hcan.pTxMsg->StdId = 0x100;
hcan.pTxMsg->ExtId = 0x0; hcan.pTxMsg->RTR = CAN_RTR_DATA; hcan.pTxMsg->IDE = CAN_ID_STD; hcan.pTxMsg->DLC = 8;}
#can-timeout #can #stm32f1032017-04-08 07:38 AM
okay, thanks for this information. I hope I can read it soon :)
2017-04-08 12:48 PM
The private messaging doesn't get the same level of scrutiny, but lacks formatting. You could use that, pastebin or email.
2017-04-09 11:25 AM
Are you using the HAL Library together with the Standard Peripherals Library ?
I tought it would not work together
2017-04-09 06:43 PM
not sure,
I just followed my nose from the cube examples.
did it help you ?
I looked back at MBED yesterday, the CAN code looks almost identical to this.
2017-04-13 09:05 AM
your checkCanTxMsg function dont work. I think you created the data types on your own ?
unfortunately your init configuration doesnt work in my project.
I noticed that there are different HAL_CAN_Transmit functions in the HAL Library, so in the F3 library is a cancel command before it goes into timeout state. I added this to the transmit function of the F1 lib what solved the mailbox problem but it doesnt send any can messages yet. So I think there is a problem with setting the ack bit but I cant find the part of code where is is set.
2017-04-13 07:35 PM
Hi, my code has a 64 element TxBuffer which is packed in the foreground with messages.
so my flag
canTxMsgTableEMPTY
will become false and the next element message will be sent if the fifos are empty.
all you need to do is this:
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1) is the line idle ?
{
CAN->sTxMailBox[0].TDTR = // (2) length
CAN->sTxMailBox[0].TDLR = // (3) 4bytes
CAN->sTxMailBox[0].TDHR = // (3) 4bytes
CAN->sTxMailBox[0].TIR = ((uint32_t)YourMsgID << 21 | CAN_TI0R_TXRQ); // (4)// send it now if the line is idle
}
2017-04-17 01:54 PM
is this the part where it transmits the message? so can i replace it with the corresponding part in the HAL_CAN_Transmit function or should I try it separately in the main file?
2017-04-17 06:42 PM
2017-04-20 05:49 AM
Finally I got it. I made some hardware changes, a new twisted pair cable and another dsub plug. Then PCAN shows me some minor problems which I solved with modifying the baud rate and then it works correctly. Now I´m trying to filter some CAN messages.
Thank you very much for your help, nick
2018-05-02 10:06 AM
https://community.st.com/0D50X00009XkX9PSAV
I have reply this question in Chinese
use google translate ,man