9 years, 9 months ago.

baud rate for STM32F103RB

if you add to line 13:

pc.baud(115200);

The code does not work. Baudrate 9600 does work. What is the exact implementation of serial hardware on Nucleo STM32 F103RB and others ?

Has anyone a working example of UART with interrupts ?

Thank you.

posted by andy mosi 11 Aug 2014

2 Answers

9 years, 9 months ago.

You can find the implementation in the mbed-src lib (http://mbed.org/users/mbed_official/code/mbed-src/file/ccdf646660f2/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/serial_api.c). However I just tested it on my F030 (closest one I got to the F103), and there it worked fine. You can try updating the mbed lib (right mouse button, update), to see if that helps.

I assume you are also changing the baudrate in your terminal program? Otherwise it definately won't work. And for UARTs with interrupt you should be able to use the same code as for other targets, that is the goal of mbed. See for example: http://mbed.org/handbook/Serial

first, thank you for the serial_api.c

on the original Nucleo STM32 F103RB, the baud rate 9600 is confirmed to work, 115200 does not. Using Mac OS X, minicom -b 9600 or -b 115200 . The code freezes in the middle of pc.printf(" some long string" );

Now to the question with IRQ on UART : Does any one have a working example on Nucleo board with the UART IRQ working?

I tried porting LPC1768 code, but it fails somewhere after printf ** 6.3 ,

snippet for read line UART

// Read a line from the large rx buffer from rx interrupt routine
void read_line() {
    int i;
    i = 0;
// Start Critical Section - don't interrupt while changing global buffer variables
    NVIC_DisableIRQ(UART_IRQ); // stm32: USART2_IRQn lpc nxp: UART1_IRQn
// Loop reading rx buffer characters until end of line character
    while ((i==0) || (rx_line[i-1] != '\r')) {
// Wait if buffer empty
        if (rx_in == rx_out) {
// End Critical Section - need to allow rx interrupt to get new characters for buffer
            NVIC_EnableIRQ(UART_IRQ);
            pc.printf(" ************** 6.3 \r\n");  
            while (rx_in == rx_out) {
                
            }
            pc.printf(" ************** 6.4 \r\n");  
// Start Critical Section - don't interrupt while changing global buffer variables
            NVIC_DisableIRQ(UART_IRQ);
            pc.printf(" ************** 6.5 \r\n");  
        }
        rx_line[i] = rx_buffer[rx_out];
        i++;
        rx_out = (rx_out + 1) % buffer_size;
    }

while this routine never gets called:

snippet for Rx interrupt UART

// Interupt Routine to read in data from serial port
void Rx_interrupt() {
    pc.printf(" ************** 9 \r\n");  
//    led1=1;
// Loop just in case more than one character is in UART's receive FIFO buffer
// Stop if buffer full
    while ((pc.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
        pc.printf(" ************** 10 \r\n");  
        rx_buffer[rx_in] = pc.getc();
// Uncomment to Echo to USB serial to watch data flow
        pc.putc(rx_buffer[rx_in]);
        rx_in = (rx_in + 1) % buffer_size;
    }
//    led1=0;
    return;
}

after registering the interrupts with this:

snippet for registering UART interrupt routines

// Setup a serial interrupt function to receive data
    pc.attach(&Rx_interrupt, Serial::RxIrq);
    // Setup a serial interrupt function to transmit data
    pc.attach(&Tx_interrupt, Serial::TxIrq);

Sorry if not meaningful, the entire code involves unnecessary clutter. Thank you!

posted by andy mosi 11 Aug 2014

I can't verify the F103 since I don't have it, maybe someone else can.

Regarding interrupts, did you try the simple test program from the Serial handbook page? And if you want a buffered serial implementation, then this one uses standard mbed functions to create it, you can see if it works: http://mbed.org/users/sam_grove/code/BufferedSerial/ (I haven't tried it on a Nucleo target myself yet).

posted by Erik - 11 Aug 2014
9 years, 8 months ago.

I had the same issue: While I printf on 115200 - nothing happens on the console.

Problem Investigation: The NUCLEO-F103RB has several revisions and one of them comes with internal RC oscillator only (revision MB1136 C-01)! (The revisions and signals are described in DM00105823.pdf) This means that this board does not have precise clock to generate of 115200 and this confuses the STLINK.

Solutions for accurate main frequency: 1. Solder 8.00 MHz Quartz + C33 and C34 (15pF) 2. Use the Nucleo signal "MCO" - this is a 8MHz generated from STLINK. (DM00105823.pdf; 5.7.1 OSC clock supply)

My approach: I've solder a quartz and it works :)