CAN Normal Mode Communication between 2 boards
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);
}


