2023-12-22 02:57 AM - last edited on 2023-12-27 12:48 AM by SofLit
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);
}
Solved! Go to Solution.
2023-12-28 01:19 AM - edited 2023-12-28 01:30 AM
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)
This is the Rs pin description in the datasheet:
2023-12-26 09:28 PM - edited 2023-12-26 09:30 PM
This is the waveforms I am getting by connecting logic analyser on the CAN_Tx pin.
2023-12-27 12:26 AM - edited 2023-12-27 12:27 AM
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:
then:
Thank you.
2023-12-27 12:47 AM
Please provide more details on your configuration as requested. The waveform does not help.
2023-12-27 12:58 AM - edited 2023-12-27 01:07 AM
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.
2023-12-27 12:59 AM
My doubt is why am i getting this error for normal mode while its working fine with Loopback mode.
2023-12-27 01:01 AM
#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);
}
2023-12-27 01:08 AM
This is
#include "stm32f4xx_hal.h"
extern CAN_HandleTypeDef hcan1;
void SysTick_Handler (void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
it.c file
2023-12-27 01:15 AM
I am referring this connection to set up the CAN bus
2023-12-27 03:17 AM
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;