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-27 03:22 AM
Also check the Rs pin voltage level of the transceiver:
From its datasheet:
2023-12-27 07:25 PM
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);
}
2023-12-27 07:39 PM
The issue persists even after changing the bitrate as you mentioned
2023-12-27 09:21 PM
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.
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-28 07:35 PM
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.
2023-12-29 06:43 AM
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
2024-01-02 08:25 PM
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.
2024-01-03 12:18 AM
The picture is not sufficient as it des not provide any information. The schematics of the transceiver module is needed.
2024-01-03 12:54 AM
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.