Stm32 Peripheral Drivers from Scartch : GPIO Programming Part 1

Posted by Eddie on August 10, 2016
Programming the GPIO is nothing out of this world. A series of steps must be taken to get those pins to do our bidding.

1. Initialize the clock for the Port you are going to use
2.Configure the Pin
3.Use the pin.

Pretty easy is'nt it? The board which I showed in an earlier post has an LED wired to Pin 13 on PORT C.  SO lets make this LED blink using the steps above.

1.Initializing the clock

To initialize the clock we must access the RCC Peripheral which controls the enabling and disabling of clocks for all the peripherals. The Stm32 has most of its peripherals turned off after a reset to consume less power, so it is your job to turn on what you need.

Above you can see the exact register (Page 145)  we need to turn on the clock gating for various GPIO Ports and highlighted is the one we need labeled InputOutputPortC (IOPC-ENable)

The code looks like this:

RCC->APB2ENR |= 1<<4;

That it as far as enabling the clock. Now lets look at step 2 which is configuring the pin or pins you want to use.

Lets take a look at the register required to do so.

Okay we are now in the GPIO peripheral part of the data sheet (Page 171) and here is the eact register we need to configure Pin 13 , since 13 is not between 0 and 7  we need to configure it in the HIGH register which handles pins 8 through 15. Also keep in mind to help you figure out what to type Look at the top where GPIOx_CRH is highlighted. GPIOx is the nameof the peripheral , the x gets replaced with the port you are configuring , in our case Port C , after that is the specific register within that peripheral in this case CRH so that is exactly what our code will look like.

GPIOC->CRH |=  blah bla blah

Okay now that we know where we are getting these names from lets figure out how we are going to configure this pin.
Under the MODE section i have highlighted how I want to configure the mode, which is output at 50Mhz, and in the CNF section i have highlighted that i want it as a General Purpose Push Pull.
I have also highlighted the corresponding bits in the register the configure Pin13.

the code looks like this:

GPIOC->CRH  |= (1<<20) |(1<<21) ;  // shift a 1 into bit 20 and 21

GPIOC-> CRH &= ~(  (1<<22) | (1<<23)  );  //AND NOT a 1 into 22 and 23, 
//this means put a 1 in   //those bits, and then change those ones to zeros

And that is all there is to configuring a pin as input or output. Now to set it HIGH or LOW we turn to the BSRR register seen below (Page 172)

We will first SET/HIGH the pin and then RESET/LOW the pin. To set the pin we must write a 1 into bit 13 labeled BS13 (bit set 13) next we will enter a silly delay by way of a for loop and then RESET the pin by writing a 1 to the BR13 bit which is Bit 29.  Remember that the RESET bit is Exactly 16 bits away from the SET bit so we dont have to remember the exact number of the RESET bit , As long as we know the SET bit which is the same number as our pin we are good to go.

The code looks like this:

GPIOC->BSRR = 1<<13; // set the Pin HIGH
for(int i= 0; i<=5000000; i++) ; //dummy delay not how it should be done
GPIOC->BSRR = 1<<(13+16) ; //to get to the reset bit we just add 16 to our pin number
for(int i= 0; i<=5000000; i++) ; //dummy delay not how it should be done

Note that i set my uVision to C99 mode which allows me to initialize the variable "i" inside my for loop statement, other versions of C do not allow this.
Andthere you have it. How to program the GPIO of most STM32 chips. Now lets take all of this and write a driver for it which will be a more readable and sensible way of doing this.

This is the video version of the what i explained above