Become a leader in the IoT community!

Join our community of embedded and IoT practitioners to contribute experience, learn new skills and collaborate with other developers with complementary skillsets.

Step 1 of 5

CREATE YOUR PROFILE *Required

OR
Step 2 of 5

WHAT BRINGS YOU TO DEVHEADS? *Choose 1 or more

Connect & collaborate 🤝with other tech professionals
Learn & Grow 📚
Contribute Experience & Expertise 🔧
Step 3 of 5

WHAT'S YOUR INTEREST OR EXPERTISE? *Choose 1 or more

Hardware Design 💡
Embedded Software 💻
Edge Networking
Step 4 of 5

Personalize your profile

Step 5 of 5

Read & agree to our COMMUNITY RULES

  1. We want this server to be a welcoming space! Treat everyone with respect. Absolutely no harassment, witch hunting, sexism, racism, or hate speech will be tolerated.
  2. If you see something against the rules or something that makes you feel unsafe, let staff know by messaging @admin in the "support-tickets" tab in the Live DevChat menu.
  3. No age-restricted, obscene or NSFW content. This includes text, images, or links featuring nudity, sex, hard violence, or other graphically disturbing content.
  4. No spam. This includes DMing fellow members.
  5. You must be over the age of 18 years old to participate in our community.
  6. You agree to our Terms of Service (https://www.devheads.io/terms-of-service/) and Privacy Policy (https://www.devheads.io/privacy-policy)
By clicking "Finish", you have read and agreed to the our Terms of Service and Privacy Policy.

Issue with CAN Protocol on STM32F103C8T6

Hello @here, i am currently trying to set up my CAN protocol using stm32f103c8t6. I intend to use it in loop back mode just for test, I am having issues, the frequency is 72MHz and my bus(APB1ENR) is 36MHz, my baudrate is 250kb/s. After initialization, it gets stuck at
CAN1->MCR &= ~CAN_MCR_INRQ;
while (CAN1->MSR & CAN_MSR_INAK) ; // Wait for normal mode

void CAN1_Init()
{
RCC->APB2ENR |= 1 << 2; // enabling GPIOA clock RCC->APB1ENR &= ~(1 << 25); // enabling CAN1 clock RCC->APB1ENR |= 1 << 25; // enabling CAN1 clock delay_ms(1000); RCC->APB2ENR |= 1 << 0; // enabling AFIOEN clock GPIOA->CRH &= ~(0x0F << 12); // CAN_RX PA11 GPIOA->CRH |= (0x0B << 12); // GPIOA->CRH &= ~(0x0F << 16); // CAN_TX PA12 GPIOA->CRH |= (0x0B << 16); // // CAN1->MCR &= ~(1 << 0); // Enter initialization mode CAN1->MCR |= (1 << 0); while ((CAN1->MSR & 0x01) != 1)
;

CAN1->MCR &= ~(1 << 1); // EXIT FROM SLEEP MODE while ((CAN1->MSR & 0X02) != 0)
;

CAN1->BTR |= (1 << 30); // ENABLE LOOP BACK MODE CAN1->BTR &= ~(1 << 31); CAN1->MCR &= ~(1 << 6); // AUTO BUSS OFF DISABLE CAN1->MCR &= ~(1 << 4); // AUTO RETRANSMISSION ENABLED CAN1->MCR &= ~(1 << 5); // DISABLE AUTO WAKEUP CAN1->MCR &= ~(1 << 3); // RECEIVED FIFO DISABLED CAN1->MCR &= ~(1 << 7); // TIME TRIGERRED DISABLE CAN1->MCR &= ~(1 << 2); // PRIORITY DRIVEN BY IDENTIFIER // Next is the settigs for the CAn trigger CAN1->BTR &= ~(3 << 24); // SETTING SJW TO 1 CAN1->BTR |= (0 << 24); CAN1->BTR &= ~(0x3FF << 0); // PRESCALER IS 9, BUT 8 IS SENT for 250kbs CAN1->BTR |= (8 << 0); CAN1->BTR &= ~(0x0F << 16); CAN1->BTR |= (12 << 16); // TIMER SEGMENT 1 TO BE DECIMAL 13 CAN1->MCR &= ~(1 << 7); // Time Triggered Disable CAN1->BTR &= ~(0x07 << 20); CAN1->BTR |= (1 << 20); // TIMER SEGMENT 2 TO BE DECIMAL 2 CAN1->MCR &= ~CAN_MCR_INRQ;
while (CAN1->MSR & CAN_MSR_INAK)
; // Wait for normal mode
}
I will appreciate if someone can assist

  1. m.alarab#0000

    i also re-write the code by changing the order of the operation.
    i was not able to test it because i don’t have the hardware, but you can make the test from your side

    i used defined macros in stm32f1xx.h and stm32f103xb.h
    these files should already be in your project

    i think using these defined macros give a more readable code, and will be easier to modify
    if you write like this to optimise your code, using defined macros have no impact on the binary size because the macros are processed before compiling : so in both case the compiler receive the same code

  2. m.alarab#0000

    here is y code :

    void CAN1_Init()
    {
    // enabling GPIOA clock
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);
    // enabling CAN1 clock
    //it is just 1 bit, no need to clear before set
    //CLEAR_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);
    SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);
    delay_ms(1000);
    // enabling AFIOEN clock
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);

    // CAN_RX PA11
    //this pin AF or input ?
    MODIFY_REG(GPIOA.CRH, GPIO_CRH_MODE11_Msk, 0);
    // CAN_TX PA12
    MODIFY_REG(GPIOA.CRH, GPIO_CRH_MODE12_Msk, 0xB);

    // Enter initialization mode
    SET_BIT(CAN1->MCR, CAN_MCR_INRQ);
    while ((CAN1->MSR & CAN_MSR_INAK) != 1);

    //Exit from sleep mode
    CLEAR_BIT(CAN1->MCR, CAN_MCR_SLEEP);
    while ((CAN1->MSR & CAN_MSR_SLAK) != 0U);

    // TIME TRIGERRED DISABLE
    CLEAR_BIT(CAN1->MCR, CAN_MCR_TTCM);
    // AUTO BUSS OFF DISABLE
    CLEAR_BIT(CAN1->MCR, CAN_MCR_ABOM);
    // DISABLE AUTO WAKEUP
    CLEAR_BIT(CAN1->MCR, CAN_MCR_AWUM);
    // AUTO RETRANSMISSION ENABLED
    CLEAR_BIT(CAN1->MCR, CAN_MCR_NART);
    // RECEIVED FIFO DISABLED
    CLEAR_BIT(CAN1->MCR, CAN_MCR_RFLM);
    // PRIORITY DRIVEN BY IDENTIFIER
    CLEAR_BIT(CAN1->MCR, CAN_MCR_TXFP);
    // ENABLE LOOP BACK MODE
    SET_BIT(CAN1->BTR, CAN_BTR_LBKM);
    CLEAR_BIT(CAN1->BTR, CAN_BTR_SILM);

    WRITE_REG(CAN1->BTR, 0 |
    (0 << CAN_BTR_SJW_Pos) | //// SETTING SJW TO 1 (12 << CAN_BTR_TS1_Pos) | // TIMER SEGMENT 1 TO BE DECIMAL 13 (1 << CAN_BTR_TS2_Pos) | // TIMER SEGMENT 2 TO BE DECIMAL 2 (9-1) | CAN_BTR_LBKM); // PRESCALER IS 9, BUT 8 IS SENT for 250kbs CLEAR_BIT(CAN1->MCR, CAN_MCR_INRQ);
    while ((CAN1->MSR & CAN_MSR_INAK) != 0U);
    }

  3. afuevu_#0000

    Hey @m.alarab thanks man, it worked I just tried it, i will observe what you did differently, I appreciate

  4. afuevu_#0000

    @m.alarab for some reason this setting the can rx pin as input is the problem.

    MODIFY_REG(GPIOA->CRH, GPIO_CRH_MODE11_Msk, 0); this works

    GPIOA->CRH &= ~(0x0F << 12); // CAN_TX PA12 GPIOA->CRH |= (8 << 12); this dosent work

  5. m.alarab#0000

    yes it is mentioned in the reference manual, the rx should be set to input.
    if you use the MODIFY_REG, i missed to shift the last argument (modify to 0<

  6. afuevu_#0000

    Yeahh

  7. afuevu_#0000

    So it seems if I set the input to INPUT PULL-UP, it doesn’t work, but when I set it to INPUT FLOATING, it works

  8. m.alarab#0000

    Hi @afuevu_
    i checked you code,
    i notice the pin config of PA11 is not correct, CAN_Rx should be set to input
    but i sont know if it resolve your problem
    image.png

CONTRIBUTE TO THIS THREAD

Browse other questions tagged 

Leaderboard

RANKED BY XP

All time
  • 1.
    Avatar
    @Nayel115
    1620 XP
  • 2.
    Avatar
    @UcGee
    650 XP
  • 3.
    Avatar
    @melta101
    600 XP
  • 4.
    Avatar
    @chitour
    600 XP
  • 5.
    Avatar
    @lifegochi
    250 XP
  • 6.
    Avatar
    @Youuce
    180 XP