Skip to main content
Visitor II
December 22, 2023
Solved

CAN Normal Mode Communication between 2 boards

  • December 22, 2023
  • 6 replies
  • 4673 views

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);

}

 

    This topic has been closed for replies.
    Best answer by mƎALLEm

    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

     

     

     

    6 replies

    Visitor II
    December 27, 2023

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

     

    Technical Moderator
    December 27, 2023

    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.

     

     

    Visitor II
    December 27, 2023

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

     

    Visitor II
    December 27, 2023
    #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);
    }
    Visitor II
    December 27, 2023

    This is

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

    it.c file

    Visitor II
    December 27, 2023

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

     

    Visitor II
    January 3, 2024

    I am also curious about how its working.I have attached the photo of the transceiver which is bought from amazon I think its the counterfeit one.

    Technical Moderator
    January 3, 2024

    The picture is not sufficient as it des not provide any information. The schematics of the transceiver module is needed.

    Visitor II
    January 3, 2024

    I don't have a reference to any other schematic other than the schematic present in the datasheet by Texas Instrument. I have only one the Texas Instrument datasheet.