Skip to main content
ss201040303
Visitor II
September 21, 2022
Question

STM32F103c8 bxCAN Transmit Problem.

  • September 21, 2022
  • 1 reply
  • 1071 views

I am tried to send a simple message over CAN, but I got the broken Frame when transmitting, I capture it on a Logic Analyzer(Pic Below), it seems that it is Transmitting but not Correctly.

Did I did somting wrong or Did I miss Someting?0693W00000SvvccQAB.pngAnd here is my Code:

int main(void)
{
 /* USER CODE BEGIN 1 */
 
 
 /* USER CODE END 1 */
 
 /* MCU Configuration--------------------------------------------------------*/
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
 
 NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 
 /* System interrupt init*/
 /* SysTick_IRQn interrupt configuration */
 NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
 
 /** DISABLE: JTAG-DP Disabled and SW-DP Disabled
 */
 LL_GPIO_AF_DisableRemap_SWJ();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 /* USER CODE BEGIN 2 */
 
 /***LED GPIO***/
 		 RCC->APB2ENR |= (1 << IOPBEN);
 
 		 GPIOB->BRR |= (1 << 8)|(1 << 9);
 
 		 GPIOB->CRH &= ~((CLEAR_BITS << MODE8)|(CLEAR_BITS << CNF8)|(CLEAR_BITS << MODE9)|(CLEAR_BITS << CNF9));
 
 		 GPIOB->CRH |= (OUT50M << MODE8)|(GPIO_PP << CNF8)|(OUT50M << MODE9)|(GPIO_PP << CNF9);
 
 		//GPIOB->ODR |= (1 << 8)|(1 << 9);
 /***LED GPIO***/
 
 /***UART CONSOLE***/
 		serialInit(9600);
 		serialPrintln("Init.");
 /***UART CONSOLE***/
 
 	/*INIT*/
 
 	//RCC Config
 	RCC->APB1ENR |= (1 << CANEN);				// Enable CAN clock
 	RCC->APB2ENR |= (1 << AFIOEN); 	// Enable AFIO clock
 
 	RCC->APB2ENR |= (1 << IOPAEN); 	// Enable GPIOA clock
 
 	serialPrintln("CAN RCC Config.");
 
 	//clear A11, A12
 	GPIOA->CRH &= ~(0xFF000UL); 			// Configure PA12(0b0000) and PA11(0b0000)
 
 	//Config A11, A12
 	GPIOA->CRH |= (INPUT << MODE11)|(IN_PP_PD << CNF11)|(OUT50M << MODE12)|(AFIO_PP << CNF12);
 
 	//PA12 PULL-UP (CAN_TX)
 	GPIOA->ODR |= (1 << 12)|(1 << 11);
 
 
 	serialPrintln("CAN GPIO Config.");
 
 	//CAN init
 
 	CAN1->MCR |= (1 << INRQ); //init CAN
 
 
 	serialPrintln("CAN Init.");
 
 	while (!(	CAN1->MSR & (1 << INAK ) )); //Wait for CAN INIT
 
 	serialPrintln("CAN in Init mode.");
 
 	GPIOB->ODR |= (1 << 9);
 
 	//CAN1->MCR = 0x41UL;
 	CAN1->MCR &= ~(1 << SLEEP);
 	CAN1->MCR |= (1 << ABOM);
 	CAN1->MCR &= ~(1 << DBF);
 
 	//CAN Set bitrate
 	CAN1->BTR = 0x1A000B;
 	serialPrintln("Set CAN Bitrate.");
 
 	CAN1->MCR &= ~(1 << INRQ); //CAN1 to normal mode
 
 	 // Wait for normal mode
 	 	 for (uint16_t wait_ack = 0; wait_ack < 1000; wait_ack++) {
 	 	 if ((CAN1->MSR & 0x1UL) == 0) {
 	 	 can1 = 1;
 	 	 break;
 	 	 }
 	 	 //LL_mDelay(1000);
 	 	 }
 
 	 	 if (can1) {
 	 		serialPrintln("CAN1 initialize ok");
 	 		GPIOB->ODR |= (1 << 8);
 	 	 	 } else {
 	 		serialPrintln("CAN1 initialize fail!!");
 	 	 }
 
 	 	 //CAN Trasmit
 
 	 	 CAN1->sTxMailBox[0].TIR &= ~(0x7FF << STID);
 	 	 serialPrintln("clear Identifier Bits.");
 
 
 	 	 CAN1->sTxMailBox[0].TIR |= (0x148 << STID);
 	 	 serialPrintln("Set Identifier");
 
 	 	 CAN1->sTxMailBox[0].TIR &= ~((1 << IDE)|(1 << RTR));
 	 	 serialPrintln("Set Standard Identifire, Data Frame");
 
 	 	 CAN1->sTxMailBox[0].TDTR &= ~(0x0F << DLC);
 	 	 serialPrintln("Clear DLC Bits.");
 
 	 	 CAN1->sTxMailBox[0].TDTR |= (0x08 << DLC);
 	 	 serialPrintln("Set DLC.");
 
 	 	 CAN1->sTxMailBox[0].TDLR = 0x42;
 	 	 CAN1->sTxMailBox[0].TDLR = (0x96 << 8);
 	 	 CAN1->sTxMailBox[0].TDLR = (0x02 << 16);
 	 	 CAN1->sTxMailBox[0].TDLR = (0x46 << 24);
 	 	 CAN1->sTxMailBox[0].TDHR = 0x55;
 	 	 CAN1->sTxMailBox[0].TDHR = (0x43 << 8);
 	 	 CAN1->sTxMailBox[0].TDHR = (0x4B << 16);
 	 	 CAN1->sTxMailBox[0].TDHR = (0x2E << 24);
 	 	 serialPrintln("Load Mailbox0");
 
 	 	 CAN1->sTxMailBox[0].TIR |= (1 << TXRQ);
 	 	 serialPrintln("Mailbox0 Transmit Request");
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

This topic has been closed for replies.

1 reply

mƎALLEm
ST Technical Moderator
September 22, 2026

Hello,

It’s a bad idea to start with baremetal coding. 

Start with HAL, validate your application then optimize it with baremetal coding. 

Not obvious to follow all your “shift” and “mask” operations!

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.