cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Normal Mode Communication between 2 boards

PranavGurav
Associate II

Hello, I am trying to implement a Normal Mode CAN communication using the STM32F407 discovery board and sn65hvd230 transceiver. It works fine for Loopback mode but when I change to Normal mode I get a Bit Dominant error. I am setting the bit rate to 500kbits.

Here is my code.

Do I need to make any changes in the configuration??

 

#include <string.h>

#include <stdio.h>

#include "stm32f4xx_hal.h"

#include "main.h"

 

void Error_handler(void);

void UART2_Init(void);

void SystemClock_Config_HSE(uint8_t clockFrequency);

void CAN1_Init(void);

void GPIO_Init(void);

void CAN1_Tx(void);

 

void CAN_Filter_Config(void);

UART_HandleTypeDef huart2;

CAN_HandleTypeDef hcan1;

CAN_RxHeaderTypeDef RxHeader;

uint8_t receivedMessage[5];

int datacheck = 0;

int main(void) {

 

HAL_Init();

 

SystemClock_Config_HSE(SYS_CLOCK_FREQ_50_MHZ);

 

UART2_Init();

GPIO_Init();

CAN1_Init();

 

CAN_Filter_Config();

if (HAL_CAN_ActivateNotification(&hcan1,CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_BUSOFF) != HAL_OK) {

Error_handler();

}

if (HAL_CAN_Start(&hcan1) != HAL_OK) {

Error_handler();

}

CAN1_Tx();

 

while (1){

if(datacheck){

for (int i=0; i<receivedMessage[1]; i++)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13|GPIO_PIN_15);

HAL_Delay(receivedMessage[0]);

}

 

datacheck = 0;

}

}

 

return 0;

}

 

void SystemClock_Config_HSE(uint8_t clockFrequency) {

RCC_OscInitTypeDef Osc_Init;

RCC_ClkInitTypeDef Clock_Init;

uint8_t flash_latency = 0;

 

Osc_Init.OscillatorType = RCC_OSCILLATORTYPE_HSE;

Osc_Init.HSEState = RCC_HSE_ON;

Osc_Init.PLL.PLLState = RCC_PLL_ON;

Osc_Init.PLL.PLLSource = RCC_PLLSOURCE_HSE;

 

switch (clockFrequency) {

case SYS_CLOCK_FREQ_50_MHZ:

Osc_Init.PLL.PLLM = 4;

Osc_Init.PLL.PLLN = 50;

Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;

Osc_Init.PLL.PLLQ = 2;

Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK

| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;

Clock_Init.APB1CLKDivider = RCC_HCLK_DIV2;

Clock_Init.APB2CLKDivider = RCC_HCLK_DIV1;

flash_latency = 1;

break;

 

case SYS_CLOCK_FREQ_84_MHZ:

Osc_Init.PLL.PLLM = 4;

Osc_Init.PLL.PLLN = 84;

Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;

Osc_Init.PLL.PLLQ = 2;

 

Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK

| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;

Clock_Init.APB1CLKDivider = RCC_HCLK_DIV2;

Clock_Init.APB2CLKDivider = RCC_HCLK_DIV1;

flash_latency = 2;

break;

 

case SYS_CLOCK_FREQ_120_MHZ:

Osc_Init.PLL.PLLM = 4;

Osc_Init.PLL.PLLN = 120;

Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;

Osc_Init.PLL.PLLQ = 2;

 

Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK

| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;

Clock_Init.APB1CLKDivider = RCC_HCLK_DIV4;

Clock_Init.APB2CLKDivider = RCC_HCLK_DIV2;

flash_latency = 3;

break;

 

default:

return;

}

 

if (HAL_RCC_OscConfig(&Osc_Init) != HAL_OK) {

Error_handler();

}

 

if (HAL_RCC_ClockConfig(&Clock_Init, flash_latency) != HAL_OK) {

Error_handler();

}

 

/*Configure the systick timer interrupt frequency (for every 1 ms) */

uint32_t hclk_freq = HAL_RCC_GetHCLKFreq();

HAL_SYSTICK_Config(hclk_freq / 1000);

 

/**Configure the Systick

*/

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

 

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

 

}

void GPIO_Init(void){

GPIO_InitTypeDef GPIO_InitStruct;

__HAL_RCC_GPIOD_CLK_ENABLE();

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);

GPIO_InitStruct.Pin = GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 

GPIO_InitStruct.Pin = GPIO_PIN_15;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

}

void CAN1_Init(void) {

// settings related to CAN controller

hcan1.Instance = CAN1;

hcan1.Init.Mode = CAN_MODE_NORMAL ;

hcan1.Init.AutoBusOff = DISABLE;

hcan1.Init.AutoRetransmission = ENABLE;

hcan1.Init.AutoWakeUp = DISABLE;

hcan1.Init.ReceiveFifoLocked = DISABLE;

hcan1.Init.TimeTriggeredMode = DISABLE;

hcan1.Init.TransmitFifoPriority = DISABLE;

 

// settings related to CAN bit timings

hcan1.Init.Prescaler = 5;

hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;

hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;

hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;

if (HAL_CAN_Init(&hcan1) != HAL_OK) {

Error_handler();

}

}

 

void CAN_Filter_Config(void) {

CAN_FilterTypeDef can1FilterInit;

can1FilterInit.FilterActivation = ENABLE;

can1FilterInit.FilterBank = 0;

can1FilterInit.FilterFIFOAssignment = CAN_RX_FIFO0;

can1FilterInit.FilterIdHigh = 0x0000;

can1FilterInit.FilterIdLow = 0x000;

can1FilterInit.FilterMaskIdHigh = 0x0000;

can1FilterInit.FilterMaskIdLow = 0x0000;

can1FilterInit.FilterMode = CAN_FILTERMODE_IDMASK;

can1FilterInit.FilterScale = CAN_FILTERSCALE_32BIT;

if (HAL_CAN_ConfigFilter(&hcan1, &can1FilterInit) != HAL_OK) {

Error_handler();

}

}

void CAN1_Tx(void) {

CAN_TxHeaderTypeDef TxHeader;

 

char initializationMessage[50];

uint32_t TxMailbox;

uint8_t message[5] = { 'H', 'E', 'L', 'L', 'O' };

 

TxHeader.StdId = 0x60;

TxHeader.IDE = CAN_ID_STD;

TxHeader.RTR = CAN_RTR_DATA;

TxHeader.DLC = 5;

sprintf(initializationMessage, "Start Message Transmission\r\n");

HAL_UART_Transmit(&huart2, (uint8_t*) initializationMessage,strlen(initializationMessage), HAL_MAX_DELAY);

if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, message, &TxMailbox)!= HAL_OK) {

Error_handler();

}

}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {

 

 

char message[50];

if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, receivedMessage)

!= HAL_OK) {

Error_handler();

}

// HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13, GPIO_PIN_SET);

if(RxHeader.DLC==5){

datacheck = 1;

}

}

 

void Error_handler(void) {

while (1);

}

 

1 ACCEPTED SOLUTION

Accepted Solutions

When you are using a chip and you face an issue you need to start with looking at its datasheet as you may find some answers there.

You are using SN65HVD230 transceiver: datasheet at this link: https://www.ti.com/lit/ds/symlink/sn65hvd230.pdf?ts=1703754810632&ref_url=https%253A%252F%252Fwww.google.fr%252F

Now, regarding your question about Rs pin. This is it: (look at the datasheet page 5)

SofLit_0-1703755095576.png

This is the Rs pin description in the datasheet:

SofLit_0-1703755833731.png

 

 

 

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.

View solution in original post

19 REPLIES 19
PranavGurav
Associate II

NormalModeWaveform.pngThis is the waveforms I am getting by connecting logic analyser on the CAN_Tx pin.

 

Hello,

First, provide more details about your bus connections. Did you connect a second node on the bus to communicate with your board?

Second, please provide your schematics.

And in next time, please use this feature to insert the code to enhance the readability of yours:

SofLit_0-1703665582040.png

 

then:

SofLit_1-1703665582141.png

Thank you.

 

 

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.

Please provide more details on your configuration as requested. The waveform does not help.

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.

Yes, I tried connecting the second node but also got the same error. I have selected PB8 as CAN_Rx and PB9 as CAN_Tx. Also using sn65hvd230 transceiver which I believe has a 120 ohms terminating resistor.

 

PranavGurav
Associate II

My doubt is why am i getting this error for normal mode while its working fine with Loopback mode.

 

PranavGurav
Associate II
#include <string.h>
#include <stdio.h>
#include "stm32f4xx_hal.h"
#include "main.h"

void Error_handler(void);
void UART2_Init(void);
void SystemClock_Config_HSE(uint8_t clockFrequency);
void CAN1_Init(void);
void GPIO_Init(void);
void CAN1_Tx(void);
void CAN1_Rx(void);

void CAN_Filter_Config(void);
UART_HandleTypeDef huart2;
CAN_HandleTypeDef hcan1;

int main(void) {

	HAL_Init();

	SystemClock_Config_HSE(SYS_CLOCK_FREQ_50_MHZ);

	UART2_Init();
	GPIO_Init();
	CAN1_Init();

//	CAN_Filter_Config();
	if (HAL_CAN_Start(&hcan1) != HAL_OK) {
		Error_handler();
	}
	CAN1_Tx();
	CAN1_Rx();
	while (1)
		;

	return 0;
}

void SystemClock_Config_HSE(uint8_t clockFrequency) {
	RCC_OscInitTypeDef Osc_Init;
	RCC_ClkInitTypeDef Clock_Init;
	uint8_t flash_latency = 0;

	Osc_Init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	Osc_Init.HSEState = RCC_HSE_ON;
	Osc_Init.PLL.PLLState = RCC_PLL_ON;
	Osc_Init.PLL.PLLSource = RCC_PLLSOURCE_HSE;

	switch (clockFrequency) {
	case SYS_CLOCK_FREQ_50_MHZ:
		Osc_Init.PLL.PLLM = 4;
		Osc_Init.PLL.PLLN = 50;
		Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;
		Osc_Init.PLL.PLLQ = 2;
		Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
				| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		Clock_Init.APB1CLKDivider = RCC_HCLK_DIV2;
		Clock_Init.APB2CLKDivider = RCC_HCLK_DIV1;
		flash_latency = 1;
		break;

	case SYS_CLOCK_FREQ_84_MHZ:
		Osc_Init.PLL.PLLM = 4;
		Osc_Init.PLL.PLLN = 84;
		Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;
		Osc_Init.PLL.PLLQ = 2;

		Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
				| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		Clock_Init.APB1CLKDivider = RCC_HCLK_DIV2;
		Clock_Init.APB2CLKDivider = RCC_HCLK_DIV1;
		flash_latency = 2;
		break;

	case SYS_CLOCK_FREQ_120_MHZ:
		Osc_Init.PLL.PLLM = 4;
		Osc_Init.PLL.PLLN = 120;
		Osc_Init.PLL.PLLP = RCC_PLLP_DIV2;
		Osc_Init.PLL.PLLQ = 2;

		Clock_Init.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
				| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		Clock_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		Clock_Init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		Clock_Init.APB1CLKDivider = RCC_HCLK_DIV4;
		Clock_Init.APB2CLKDivider = RCC_HCLK_DIV2;
		flash_latency = 3;
		break;

	default:
		return;
	}

	if (HAL_RCC_OscConfig(&Osc_Init) != HAL_OK) {
		Error_handler();
	}

	if (HAL_RCC_ClockConfig(&Clock_Init, flash_latency) != HAL_OK) {
		Error_handler();
	}

	/*Configure the systick timer interrupt frequency (for every 1 ms) */
	uint32_t hclk_freq = HAL_RCC_GetHCLKFreq();
	HAL_SYSTICK_Config(hclk_freq / 1000);

	/**Configure the Systick
	 */
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

	/* SysTick_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}
void GPIO_Init(void) {
	GPIO_InitTypeDef GPIO_InitStruct;
	__HAL_RCC_GPIOD_CLK_ENABLE();
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
	GPIO_InitStruct.Pin = GPIO_PIN_13;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = GPIO_PIN_15;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

void UART2_Init(void) {
	huart2.Instance = USART2;
	huart2.Init.BaudRate = 115200;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	if (HAL_UART_Init(&huart2) != HAL_OK) {
		//There is a problem
		Error_handler();
	}

}

void CAN1_Init(void) {
//	settings related to CAN controller
	hcan1.Instance = CAN1;
	hcan1.Init.Mode = CAN_MODE_NORMAL;
	hcan1.Init.AutoBusOff = ENABLE;
	hcan1.Init.AutoRetransmission = ENABLE;
	hcan1.Init.AutoWakeUp = DISABLE;
	hcan1.Init.ReceiveFifoLocked = DISABLE;
	hcan1.Init.TimeTriggeredMode = DISABLE;
	hcan1.Init.TransmitFifoPriority = DISABLE;

//	settings related to CAN bit timings
	hcan1.Init.Prescaler = 5;
	hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
	hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
	hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
	if (HAL_CAN_Init(&hcan1) != HAL_OK) {
		Error_handler();
	}
}

void CAN_Filter_Config(void) {
	CAN_FilterTypeDef can1FilterInit;
	can1FilterInit.FilterActivation = ENABLE;
	can1FilterInit.FilterBank = 0;
	can1FilterInit.FilterFIFOAssignment = CAN_RX_FIFO0;
	can1FilterInit.FilterIdHigh = 0x0000;
	can1FilterInit.FilterIdLow = 0x000;
	can1FilterInit.FilterMaskIdHigh = 0x0000;
	can1FilterInit.FilterMaskIdLow = 0x0000;
	can1FilterInit.FilterMode = CAN_FILTERMODE_IDMASK;
	can1FilterInit.FilterScale = CAN_FILTERSCALE_32BIT;
	if (HAL_CAN_ConfigFilter(&hcan1, &can1FilterInit) != HAL_OK) {
		Error_handler();
	}
}
void CAN1_Tx(void) {
	CAN_TxHeaderTypeDef TxHeader;

	char initializationMessage[50];
	uint32_t TxMailbox;
	uint8_t message[5] = { 'H', 'E', 'L', 'L', 'O' };

	TxHeader.StdId = 0x65D;
	TxHeader.IDE = CAN_ID_STD;
	TxHeader.RTR = CAN_RTR_DATA;
	TxHeader.DLC = 5;
//	message[0]=100;
//	message[1]=10;

	sprintf(initializationMessage, "Start Message Transmission\r\n");
	HAL_UART_Transmit(&huart2, (uint8_t*) initializationMessage,
			strlen(initializationMessage), HAL_MAX_DELAY);
	if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, message, &TxMailbox)
			!= HAL_OK) {
		Error_handler();
	}
	while (HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox));
	sprintf(initializationMessage, "Message Transmitted\r\n");
	HAL_UART_Transmit(&huart2, (uint8_t*) initializationMessage,
			strlen(initializationMessage), HAL_MAX_DELAY);
}
void CAN1_Rx(void) {
	CAN_RxHeaderTypeDef RxHeader;
	uint8_t rcvd_msg[5];

	char msg[50];

	//we are waiting for at least one message in to the RX FIFO0
	while (!HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0));

	if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, rcvd_msg)
			!= HAL_OK) {
		Error_handler();
	}

	sprintf(msg, "Message Received : %s\r\n", rcvd_msg);

	HAL_UART_Transmit(&huart2, (uint8_t*) msg, strlen(msg), HAL_MAX_DELAY);

}

void Error_handler(void) {
	while (1);
}

This is


#include "stm32f4xx_hal.h"
extern CAN_HandleTypeDef hcan1;
void  SysTick_Handler (void)
{
	HAL_IncTick();
	HAL_SYSTICK_IRQHandler();
}


it.c file

PranavGurav
Associate II

connection.pngI am referring this connection to set up the CAN bus

 

My first preliminary remarks:

- Where is the config of CAN1_TX and CAN1_Rx GPIOs in your code?

- The bitrate is OK but try to change BS1 and BS2:

	hcan1.Init.TimeSeg1 = CAN_BS1_7TQ;
	hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;

 

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.