7 years, 5 months ago.

how to use STM32F103RB CAN ?

I would like to use STM32f103 the CAN interface, however, the official code does not work. How can solve.

Question relating to:

Affordable and flexible platform to ease prototyping using a STM32F103RBT6 microcontroller.

4 Answers

7 years, 4 months ago.

Try this library:
https://developer.mbed.org/users/hudakz/code/CANnucleo/

I konw this library , but i found this lib not do work. it notify “ transmission error“. i nevery change any code and heaware.

posted by dong chunfeng 29 Nov 2016

I am seeing the same problem on my board. To Adu Stm : I am using the D14,D15 pins for CAN on the 103. The code does not work with the latest mbed release. Zoltan (the author) states that it only compiles with the 127 and previous revisions of mbed which I tried. Still does not work.

posted by Bill Bellis 30 Nov 2016

Hello,
When testing the CANnucle_Hello demo with various combination of boards I noticed that the CAN bus frequency of STM32F103C8T6 board was incompatible with the other mbed boards. (The demo worked fine with two STM32F103C8T6 boards. However it failed when an STM32F103C8T6 was trying to communicate with other type of mbed board.) This was caused by incorrect STM32F103C8T6 system clock frequency. The bug has been fixed and the latest revision of the CANnucle_Hello demo should work correctly. However, please remember to switch the revision of mbed library in your project back to 127 or earlier.
I'm sorry for the inconvenience. With best regards,
Zoltan

posted by Zoltan Hudak 01 Dec 2016
7 years, 4 months ago.

Hello Adu,
Could you please publish a demo (for example the code used for testing). I have tried the following program (see also the mbed CAN-Handbook example) but it hangs when using a NUCLEO-F103RB board. However, it works just fine with an LPC1768 board:

#include "mbed.h"

Ticker ticker;
DigitalOut led(LED1);
//CAN can(p9, p10);         // LPC1768    CAN Rx pin, CAN Tx pin
CAN  can(PA_11, PA_12);   // NUCLEO     CAN Rx pin, CAN Tx pin 
char counter = 0;
 
void send() {
    printf("send()\n");
    if(can.write(CANMessage(257, &counter, 1))) {
        counter++;
        printf("Message sent: %d\n", counter);
    } 
    led = !led;
}
 
int main() {
    printf("main()\n");
    led = 1;
    can.frequency(1000000);
    ticker.attach(&send, 1);
    CANMessage msg;
    while(1) {
        if(can.read(msg)) {
            printf("Message received: %d\n", msg.data[0]);
            led = !led;
        } 
        wait(0.2);
    }
}

NOTE: 'Hangs' means the LED stays dark and not even a single serial message is sent to the PC connected.

Thank you in advance. With best regards,

Zoltan

I tried the fix from Bill Bellis, but still hangs just like for Zoltan.

posted by Mark Peter Vargha 11 Jan 2017

Did you ever get this demo to work?

posted by John Sabean 28 Feb 2017

I have tested the demo again on a NUCLEO-F103RB using the current revision (137) of mbed 2 library. Unfortunately with no success. If you need to run CAN bus on a NUCLEO-F103RB board then you can give the CANnucle_Hello demo a try. But please remember to switch the revision of mbed library in your project back to 127 or earlier replace the mbed library with the mbed-dev library in your project.

posted by Zoltan Hudak 06 Mar 2017

Bug fixed in rev 138. https://github.com/ARMmbed/mbed-os/issues/3826

posted by Mark Peter Vargha 17 Mar 2017
7 years, 4 months ago.

Hi ST Team I found a bug in the init of the STM32F103RB. Is it possible to get this fix into the next mbed release?

In PeripheralPins.c the following lines of code incorrectly assign the SPI alternate function instead of the CAN alternate function. I was able to get D15,D14 working once I change the "1" to "10" and then added a case statement for initialization 10 inside of

Original code:

const PinMap PinMap_CAN_RD[] = {
    {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)},
    {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 1)},
    {NC,    NC,    0}
};

const PinMap PinMap_CAN_TD[] = {
    {PA_12,  CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)},
    {PB_9 ,  CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 1)},
    {NC,    NC,    0}

Corrected code

const PinMap PinMap_CAN_RD[] = {
    {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)},
    {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 10)},  //SET ALTERNATE2 CAN FUNCTION type 10
    {NC,    NC,    0}
};

const PinMap PinMap_CAN_TD[] = {
    {PA_12,  CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)},
    {PB_9 ,  CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 10)},
    {NC,    NC,    0}
};

In addition I made changes to pinmap.c to accommodate a 10th case within the following function:

/**
 * Configure pin (input, output, alternate function or analog) + output speed + AF
 */
void pin_function(PinName pin, int data)
{
    MBED_ASSERT(pin != (PinName)NC);
    // Get the pin informations
    uint32_t mode  = STM_PIN_MODE(data);
    uint32_t pupd  = STM_PIN_PUPD(data);
    uint32_t afnum = STM_PIN_AFNUM(data);

    uint32_t port_index = STM_PORT(pin);
    uint32_t pin_index  = STM_PIN(pin);

    // Enable GPIO clock
    uint32_t gpio_add = Set_GPIO_Clock(port_index);
    GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;

    // Enable AFIO clock
    __HAL_RCC_AFIO_CLK_ENABLE();

    // Configure Alternate Function
    // Warning: Must be done before the GPIO is initialized
    if (afnum > 0) {
        switch (afnum) {
            case 1: // Remap SPI1
                __HAL_AFIO_REMAP_SPI1_ENABLE();
                break;
            case 2: // Remap I2C1
                __HAL_AFIO_REMAP_I2C1_ENABLE();
                break;
            case 3: // Remap USART1
                __HAL_AFIO_REMAP_USART1_ENABLE();
                break;
            case 4: // Remap USART2
                __HAL_AFIO_REMAP_USART2_ENABLE();
                break;
            case 5: // Partial Remap USART3
                __HAL_AFIO_REMAP_USART3_PARTIAL();
                break;
            case 6: // Partial Remap TIM1
                __HAL_AFIO_REMAP_TIM1_PARTIAL();
                break;
            case 7: // Partial Remap TIM3
                __HAL_AFIO_REMAP_TIM3_PARTIAL();
                break;
            case 8: // Full Remap TIM2
                __HAL_AFIO_REMAP_TIM2_ENABLE();
                break;
            case 9: // Full Remap TIM3
                __HAL_AFIO_REMAP_TIM3_ENABLE();
                break;
            case 10://Remap CAN1 on to PB_8 PB_9
                __HAL_AFIO_REMAP_CAN1_2();
                break;
            default:
                break;
        }
    }

    // Configure GPIO
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin   = (uint32_t)(1 << pin_index);
    GPIO_InitStructure.Mode  = gpio_mode[mode];
    GPIO_InitStructure.Pull  = pupd;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(gpio, &GPIO_InitStructure);

    // Disconnect JTAG-DP + SW-DP signals.
    // Warning: Need to reconnect under reset
    if ((pin == PA_13) || (pin == PA_14)) {
        __HAL_AFIO_REMAP_SWJ_DISABLE(); // JTAG-DP Disabled and SW-DP Disabled
    }
    if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) {
        __HAL_AFIO_REMAP_SWJ_NOJTAG(); // JTAG-DP Disabled and SW-DP enabled
    }
}

Thank you Bill

This change can solve the problem?

posted by dong chunfeng 19 Dec 2016
7 years, 4 months ago.

Thanks Bill to have investigated and find the root cause of this issue.

I have created an Issue on GitHub: https://github.com/ARMmbed/mbed-os/issues/3474

I'll try to make the correction tomorrow.

Pull Request submitted: https://github.com/ARMmbed/mbed-os/pull/3489

Need to wait now that it's published in the mbed library.

posted by bco stm 21 Dec 2016