# STM32 and ST library, GPIO and possibly clock problems

#### wattrod

##### New Member
I'm new to ARM development and trying to do some fundamental beginner stuff with STM32. I have a VL Discovery board, and I'm just trying to send serial data. I set up the port, relying largely on sample code (though at this point I think I mostly understand what it's trying to do), and it definitely sends something, but it comes out as garbage on the other end. This happens for a variety of different baud rates, even 4800 baud. So I figure the baud rate is inaccurate for some reason (but I'm unsure how -- I call a function in the ST library and hand it a baud rate, it does the calculations).

So I try to measure the system clock. I try to set up the MCO on A8 so I can put a scope on it, and I end up getting a very faint signal, +/-40mV, that looks like a very messy clock, with waves that aren't very square. Most importantly, the period is not consistent. Many of the waves are sort of the same length, but frequently there are really short ones, and much longer ones. I couldn't even get a viewable image on my old analog scope; I had to use a DSO to capture a screenful so I could look at it.

So then I try to just toggle a GPIO pin to see how consistent that is, flipping it back and forth with the BSRR and BRR registers in a while(1) loop, mostly following example code to do so. And I'm getting no output at all.

So, I'm really confused at this point.

Code:
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
Simplest question first -- should the above be adequate for setting up the GPIO pin B1 for output? Is there anything else I need to do? I've looked at several examples online and in the ST library example code, and I can't see that they're doing anything else.

To toggle the bit, I'm just doing this:

Code:
	while (1)  {
bit = !bit;
if (bit) GPIOB->BSRR = 1; else GPIOB->BRR = 1;
}
I put a scope on the pin, and see nothing. I've tried several different pins on different ports, no difference.

FWIW, regarding the clock stuff, the chip is using an 8Mhz crystal with a PLL set for 24Mhz.

Edit -- I should probably add that I'm using KEIL for development, but I'm trying to stay away from KEIL-related code, eg. STM32_Init, etc. I'm using the ST library v3.5.0. I've deleted KEIL's ancient ST library to prevent it from using that, as most people seem to recommend.

Last edited:

#### wattrod

##### New Member
Sigh.

Ok, even if it's embarrassing, I should update this to point out the should-have-been-obvious mistake I made. I didn't bit-shift. This seemed a little peculiar in the back of my mind at the time I copied and pasted the code from the ST library examples, but I guess not enough to get me to pay more attention. They were keeping the values in an array, so I didn't clue in to what they were actually doing.

The assignment "GPIOB->BSRR = 1" should be either "GPIOB->BSRR = 1 << 1" or "GPIOB->BSRR = GPIO_Pin_1".

So, that works, and the output is very consistent, about 1.2μS per pulse. Still working out the MCO problem, and then on to figure out why the serial timing is [apparently] off.

#### dangnl

##### New Member
STM32 Primer2

hey guys, so Im also working with an STM32 chip here. I attached it to a serial COM port which is connected to a laptop so I can use to send/receive signal from the STM32 Primer2. So there are 20 pins on the chip which I used to connect to the serial port and I used 3 pins as Ground, Usart_TX, Usart_Rx (the latter 2 are used for sending signal into the laptop). There is a pin #11 which can either be used as either a standard GPIO prot or an analog ADC12_in14 function. Im trying to used this port to send out a signal "1" or "0". So here's my sample code for rerouting the port.

GPIOC->BSRR = 1<<11;

Is this correct?

#### پروژه های الکترو

##### Member
I'm new to ARM development and trying to do some fundamental beginner stuff with STM32. I have a VL Discovery board, and I'm just trying to send serial data. I set up the port, relying largely on sample code (though at this point I think I mostly understand what it's trying to do), and it definitely sends something, but it comes out as garbage on the other end. This happens for a variety of different baud rates, even 4800 baud. So I figure the baud rate is inaccurate for some reason (but I'm unsure how -- I call a function in the ST library and hand it a baud rate, it does the calculations).

So I try to measure the system clock. I try to set up the MCO on A8 so I can put a scope on it, and I end up getting a very faint signal, +/-40mV, that looks like a very messy clock, with waves that aren't very square. Most importantly, the period is not consistent. Many of the waves are sort of the same length, but frequently there are really short ones, and much longer ones. I couldn't even get a viewable image on my old analog scope; I had to use a DSO to capture a screenful so I could look at it.

So then I try to just toggle a GPIO pin to see how consistent that is, flipping it back and forth with the BSRR and BRR registers in a while(1) loop, mostly following example code to do so. And I'm getting no output at all.

So, I'm really confused at this point.[size=-10][/size]
Code:
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
Simplest question first -- should the above be adequate for setting up the GPIO pin B1 for output? Is there anything else I need to do? I've looked at several examples online and in the ST library example code, and I can't see that they're doing anything else.

To toggle the bit, I'm just doing this:

Code:
	while (1)  {
bit = !bit;
if (bit) GPIOB->BSRR = 1; else GPIOB->BRR = 1;
}
I put a scope on the pin, and see nothing. I've tried several different pins on different ports, no difference.

FWIW, regarding the clock stuff, the chip is using an 8Mhz crystal with a PLL set for 24Mhz.

Edit -- I should probably add that I'm using KEIL for development, but I'm trying to stay away from KEIL-related code, eg. STM32_Init, etc. I'm using the ST library v3.5.0. I've deleted KEIL's ancient ST library to prevent it from using that, as most people seem to recommend.
Hi there,

To change a PIN on a PORT, you can use GPIO's ODR register or BSRR/BRR for atomic bit set/reset.

As you figured it out, to atomic set PINx on PORTy you must write:
Code:
GPIOy->BSRR = ( 1 << x );
and to atomic reset PINx on PORTy you must write:
Code:
GPIOy->BRR = ( 1 << x );

but for toggling a bit you can simply use XOR operand on ODR register:
Code:
GPIOy->ODR ^=  ( 1 << x );
for example to toggle bit 8 of GPIOB you can write:
Code:
GPIOB->ODR ^=  ( 1 << 8 );

##### New Member
Hi guys, i'm hoping one of you can help me on the way.

I'm playing with STM32F030 nukleo board. Trying to toggle a pin as "bare metal" as possible ( = fast).

What i'm doing is this:
RCC -> AHBENR |= (1 << 17);
GPIOA -> MODER |= (1 << 10); // pin 5
GPIOA -> OSPEEDR |= ((3UL << 2*5) );

while(1)
{
GPIOA->BSRR = (1<<5); //a
GPIOA->BSRR = (1<<21); //b
}

The SystemCoreClock shows 48000000 but the toggling is only like 3 MHz, with shortest pulse 100nS
from a to b of course. This suggest only 10 MIPS.

My question is: isn't this too slow?

I have checked that i'm actually running on the PLL by changing the multiplier variable, and this does
actually change the toggle frequency.

Thanks in advance for any clues....

##### New Member
If is add i = 0, then it takes 200 nS, can this be correct?

while(1)
{
GPIOA->BSRR = (1<<5); //a
i = 0;
GPIOA->BSRR = (1<<21); //b
}

200nS from a to b