I am trying to write bare metal programming for STM32F407, How to configure registers the steps to initialize the CAN1 to transmit the message

26 views Asked by At

I was trying the code to initalize the CAN to transmit the message but the data was loaded in the variable and it was loaded to TxmailBox but at receiver side is was not getting the data. I have set the CAN baudrate at 500000b/s. I will atach my tried code

#include "stm32f407xx.h"
#include "RCCconfig.h"

#define PRESCALER                    6
#define TIME_QUANTA_SEGMENT_1        8
#define TIME_QUANTA_SEGMENT_2                7


// CAN Details
#define CAN_ID 0x123
#define CAN_DLC 2

static uint8_t data[CAN_DLC]  =  {0};

void CAN1_Init(void)
{
    // Enable CAN1 in APB1 Bus and clock of GPIO D
    RCC->APB1ENR |= (1<<25);
    RCC->AHB1ENR |= (1<<3);
    
    // Configure CAN1 Pin
    //CAN1_TX PD1
    GPIOD->MODER  |= (2<<2);
    GPIOD->AFR[1] |= (9<<4);
    
    
    //CAN1_RX PD0
    GPIOD->MODER  |= (2<<0);
    GPIOD->AFR[1] |= (9<<4);
    
    //CAN1 Initialization
    CAN1->MCR |= (1<<0);
    while((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
    
    CAN1->MCR |= CAN_MCR_TXFP; // Transmit FIFO priority
  CAN1->MCR &= ~CAN_MCR_INRQ; // Request normal mode
  while((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK); // Wait for normal mode
    
    //CAN Baudrate setting
    //CAN Baudrate at 500000 b/s
    CAN1->BTR = 0; // Reset the BTR register
    CAN1->BTR |= (PRESCALER - 1); // Set the BRP field (note the -1, as BRP is zero-based)
    CAN1->BTR |= ((TIME_QUANTA_SEGMENT_1 - 1) << 16); // Set the TS1 field (note the -1, as TS1 is zero-based)
    CAN1->BTR |= ((TIME_QUANTA_SEGMENT_2 - 1) << 20); // Set the TS2 field (note the -1, as TS2 is zero-based)
}

void CAN1_Transmit(uint8_t data[CAN_DLC])
{
    volatile uint8_t *mailbox_data;
    uint32_t mailbox_data_temp = 0;
    int i;

    // Wait for an empty transmit mailbox
    while ((CAN1->TSR & CAN_TSR_TME0) == 0);

    // Set up the ID and DLC of the message
    CAN1->sTxMailBox[0].TIR = (CAN_ID << 3);
    CAN1->sTxMailBox[0].TDTR = CAN_DLC;

    // Load the data into the mailbox byte by byte
    mailbox_data = (volatile uint8_t *)&mailbox_data_temp;
    for (i = 0; i < CAN_DLC; i++) {
        mailbox_data[i] = data[i];
    }
    CAN1->sTxMailBox[0].TDLR = mailbox_data_temp;

    // Request a transmission
    CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;
}




int main (void)
{
    SysClockConfig ();

    CAN1_Init();
    
    // Load data
    data[0] = 0x65; // Replace with your data
    data[1] = 0xAA; // Replace with your data
    
    while (1)
    {
        // Transmit the data over CAN1
        CAN1_Transmit(data);
    }
    
}


I need a help that wether the CAN-init is written correctly or need an updated code of it correction. Check if the Baudrate is set to 500000 b/s. write registers step by step which is used and which bit to set.

0

There are 0 answers