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

}

 

19 REPLIES 19

Also check the Rs pin voltage level of the transceiver:

From its datasheet:

SofLit_0-1703676134606.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.

Here is my CAN_Tx and CAN_Rx GPIOs configuration in msp.c file.


#include "main.h"

void HAL_MspInit(void)
{
 //Here will do low level processor specific inits.
	//1. Set up the priority grouping of the arm cortex mx processor
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

	//2. Enable the required system exceptions of the arm cortex mx processor
	SCB->SHCSR |= 0x7 << 16; //usage fault, memory fault and bus fault system exceptions

	//3. configure the priority for the system exceptions
	HAL_NVIC_SetPriority(MemoryManagement_IRQn,0,0);
	HAL_NVIC_SetPriority(BusFault_IRQn,0,0);
	HAL_NVIC_SetPriority(UsageFault_IRQn,0,0);
}

 void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
	 GPIO_InitTypeDef gpio_uart;
	 //here we are going to do the low level inits. of the USART2 peripheral

	 //1. enable the clock for the USART2 peripheral as well as for GPIOA peripheral
	 __HAL_RCC_USART2_CLK_ENABLE();
	 __HAL_RCC_GPIOA_CLK_ENABLE();

	 //2 . Do the pin muxing configurations
	 gpio_uart.Pin = GPIO_PIN_2;
	 gpio_uart.Mode =GPIO_MODE_AF_PP;
	 gpio_uart.Pull = GPIO_PULLUP;
	 gpio_uart.Speed = GPIO_SPEED_FREQ_LOW;
	 gpio_uart.Alternate =  GPIO_AF7_USART2; //UART2_TX
	 HAL_GPIO_Init(GPIOA,&gpio_uart);

	 gpio_uart.Pin = GPIO_PIN_3; //UART2_RX
	 HAL_GPIO_Init(GPIOA,&gpio_uart);
	 //3 . Enable the IRQ and set up the priority (NVIC settings )
	 HAL_NVIC_EnableIRQ(USART2_IRQn);
	 HAL_NVIC_SetPriority(USART2_IRQn,15,0);

}

 void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
 {
	 GPIO_InitTypeDef GPIO_InitStruct;
	__HAL_RCC_CAN1_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStruct.Pin=GPIO_PIN_8 | GPIO_PIN_9;
	GPIO_InitStruct.Mode=GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull= GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate=GPIO_AF9_CAN1;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);

	HAL_NVIC_SetPriority(CAN1_TX_IRQn,15, 0);
	HAL_NVIC_SetPriority(CAN1_RX0_IRQn,15, 0);
	HAL_NVIC_SetPriority(CAN1_RX1_IRQn,15, 0);
	HAL_NVIC_SetPriority(CAN1_SCE_IRQn,15, 0);

	HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
	HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
	HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
	HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
 }

 

The issue persists even after changing the bitrate as you mentioned Screenshot from 2023-12-28 09-08-30.png

As I am new to embedded I dont have any idea about the Rs Pin of the Transceiver can you give me more details to move forward.

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.

Thank you @SofLit for your guidance. I was able to fix the issue by simply changing the voltage supply to 5V to the transceiver. Earlier I used to supply 3V to the transceiver. This is the transceiver I am using. It has no Rs pin to it.TransceiverTransceiver

But according to the datasheet it's a 3.3V transceiver! Are you sure? or are you using another tranceiver?

https://www.ti.com/product/SN65HVD230

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.
PranavGurav
Associate II

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.

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

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.
PranavGurav
Associate II

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.