STM32F407 can communication normal mode not working
Hello dear friends,
It's been a week since I worked on the CAN transceiver and couldn't make it work. I have set up the chip rcc, bit rate, and receive interrupt of CAN, set the receive filter, and the receiver id in transmission, with no success. I have used only a single board and connected Tx to Rx (PD0 PD9) through a jumper. I have checked that there no frame on the CAN Analyzer.
The code is attached. Help me what had make it not
#include "Mcu.h"
#include "stm32f4xx.h"
void CAN1_Init(void);
void CAN1_Tx(uint8_t tr);
uint8_t CAN1_Rx(void);
void TIM4_ms_Delay(uint32_t delay);
uint8_t k = 0;
uint8_t rec = 0;
void GPIO_Init(){
// Enable GPIOB clock signal
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
// Configuring PD0 and PD1 in alternate function mode
GPIOD->MODER |= GPIO_MODER_MODE1_1 | GPIO_MODER_MODE0_1 ;
// Selecting AF9 for PD0 and PD1 (See Page 272 of dm00031020)
GPIOD->AFR[1] |= (GPIO_AFRL_AFSEL0_3 | GPIO_AFRL_AFSEL0_1 | GPIO_AFRL_AFSEL1_0 | GPIO_AFRL_AFSEL1_3);
}
void CAN1_Init(){
/* 1. Setting Up the Baud Rate and Configuring CAN1 in
* Loop Back Mode -------------------------------------------------------*/
// Enable clock for CAN1
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
// Entering CAN Initialization Mode and wait for acknowledgment
CAN1->MCR |= CAN_MCR_INRQ;
while (!(CAN1->MSR & CAN_MSR_INAK)){}
//Set Loop back mode for CAN1
CAN1->BTR &= ~CAN_BTR_LBKM;
//Setting the Re synchronization jump width to 1
CAN1->BTR &= ~CAN_BTR_SJW;
//Setting the no. of time quanta for Time segment 2
// TS2 = 4-1;
CAN1->BTR &= ~(CAN_BTR_TS2);
CAN1->BTR |= (CAN_BTR_TS2_1 | CAN_BTR_TS2_0);
//Setting the no. of time quanta for Time segment 1
// TS1 = 3-1;
CAN1->BTR &= ~(CAN_BTR_TS1);
CAN1->BTR |= (CAN_BTR_TS1_1);
//Setting the Baud rate Pre-scalar for CAN1
// BRP[9:0] = 16-1
CAN1->BTR |= ((16-1)<<0);
// Exit the Initialization mode for CAN1
// Wait until the INAK bit is cleared by hardware
CAN1->MCR &= ~CAN_MCR_INRQ;
while (CAN1->MSR & CAN_MSR_INAK){}
//Exit Sleep Mode
CAN1->MCR &= ~ CAN_MCR_SLEEP;
while (CAN1->MSR & CAN_MSR_SLAK);
/* 2. Setting up the Transmission----------------------------------------*/
CAN1->sTxMailBox[0].TIR = 0;
//Setting up the Std. ID
CAN1->sTxMailBox[0].TIR = (0x01 << 21);
CAN1->sTxMailBox[1].TIR = (0x02 << 21);
CAN1->sTxMailBox[2].TIR = (0x03 << 21);
CAN1->sTxMailBox[3].TIR = (0x04 << 21);
CAN1->sTxMailBox[0].TDHR = 0;
// Setting Data Length to 1 Byte.
CAN1->sTxMailBox[0].TDTR = 1;
/* 3. Configuring the Filters--------------------------------------------*/
//Enter Filter Initialization mode to configure the filters
CAN1->FMR |= CAN_FMR_FINIT;
// Configuring the Number of Filters Reserved for CAN1
// and also the start bank for CAN2
CAN1->FMR |= 14<<8;
// Select the single 32-bit scale configuration
CAN1->FS1R |= CAN_FS1R_FSC13;
// Set the receive ID
//CAN1->sFilterRegister[13].FR1 = 0x0; // Accept any message ID
CAN1->sFilterRegister[0].FR1 = (0x01 << 21);
CAN1->sFilterRegister[1].FR1 = (0x02 << 21);
CAN1->sFilterRegister[2].FR1 = (0x03 << 21);
CAN1->sFilterRegister[3].FR1 = (0x04 << 21);
// Select Identifier List mode
CAN1->FM1R &= ~CAN_FM1R_FBM13; // Use mask mode
//Activating filter 13
//CAN1->FA1R |= CAN_FA1R_FACT13;
CAN1->FA1R |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
//Exit filter Initialization Mode
CAN1->FMR &= ~CAN_FMR_FINIT;
}
void CAN1_Tx(uint8_t tr){
// Put the Data to be transmitted into Mailbox Data Low Register
CAN1->sTxMailBox[0].TDLR = tr;
// Request for Transmission
CAN1->sTxMailBox[0].TIR |= 1;
}
uint8_t CAN1_Rx(){
// Monitoring FIFO 0 message pending bits FMP0[1:0]
while(!(CAN1->RF0R & 3)){}
// Read the message ID from the FIFO 0 mailbox
uint32_t RIR = CAN1->sFIFOMailBox[0].RIR;
uint8_t RxD = (CAN1->sFIFOMailBox[0].RDLR) & 0xFF;
// Extract message ID from RIR
uint32_t msgID = RIR >> 21;
// Releasing FIFO 0 output mailbox
CAN1->RF0R |= 1 << 5;
return msgID;
}
int main()
{
GPIO_Init();
CAN1_Init();
while (1)
{
// Main program loop, no need for delay here
// Main program loop, no need for delay here
CAN1_Tx(k);
rec = CAN1_Rx();
k += 1;
if (k > 25)
k = 0;
}
}
