STM32F103 Clock Setup using Registers
This tutorial will cover Clock setup, Timer Setup for Delay, and GPIO configuration for STM32F103C8 (BluePill) using the Register based programming. I will cover all the steps, and the link to download the code is at the end of this post.
Before starting the main setup, Let’s see the clock setup that we will be using in this tutorial.
As you can see above, the system will run at 72 MHz. Also take note of the APB1, and APB2 clocks, since they will be used in the timer setup
This part is very simple in BluePill compared to STM32F4 devices. The reason is that the function to set up the clock is predefined in the core files that we include in our project. Check the code below
This function SystemInit() is already present in system_stm32f10x.c file. All we need to do is call it in our main function and the clock setup will be complete
If you take a look at the top of the system_stm32f10x.c file, you can see that we have options to select different clocks
As you can see in the above code, we can select any of the predefined clocks. All you need to do is uncomment that line.
Here 72 MHz in uncommented and that’s why the system will run at 72 MHz
This is it for the clock setup. Now let’s take a look at the timer setup
In order to configure the timer, we need to follow some set of steps, and they are given below
Let’s see them one by one
1. Enable the Timer Clock
I am choosing timer 2 for this tutorial. And to enable the timer 2 clock, we need to see the RCC_APB1ENR Register
So all we need to do is write a 1 in the 0th position of the RCC_APB1ENR Register
Now let’s see how to set the presclalar and Auto Reload Register
Set Prescalar and ARR
Timers are connected to the Peripheral Clocks. In F103C8, there are 2 peripheral clocks i.e APB1 and APB2. In this tutorial I have decided to use the Timer 2, which is basically connected to the APB2.
We know by now that our system clock is at 72 MHz, and the rest of the clock setup will be as shown below
As shown above, the APB1 Clock is at 72 MHz. The Prescalar is used to bring this clock down to our working range. Here in this tutorial we will be focusing on creating delays in micro and milliseconds, so our working range is around 1 MHz.
As according to the above formula, If we use the prescalar of 71, the timer clock will come down to [72MHz/(71+1)] = 1 MHz
Now let’s see the ARR value.
After setting the timer for 1 MHz, if we start the timer, the counter starts counting from 0.
Each count by the counter takes 1 microsecond. The maximum count this counter can achieve is the value of the ARR.
After this the timer will overflow and our time delay will be messed up.
To avoid this we will keep the ARR value to the maximum possible. This is a 16 bit register, so the maximum value can be 0xffff.
ENABLE the TIMER and wait for CONFIRMATION
In order to enable the Timer, we will modify the Control Register 1 (TIM_CR1).
As shown above, the 0th bit of the TIMx_CR1 Register enable the timer, and to do so we need to write a 1 in the 0th position
To confirm if the timer has started, we will check the status Register (TIMx_SR)
UIF Bit is set whenever there is update event. So we will wait until this bit is set
This is it for the Timer setup. Let’s configure the GPIO now
I am using timer 2 to blink a LED, which is connected to PC13. In order to set PC13 as output, we need to follow some set of steps and they are as follows
Enable the GPIOC Clock
To enable the GPIOC clock, we need to modify the APB2 Enable Register (RCC_APB2ENR)
As you can see in the picture above, the 4th bit of RCC_APB2ENR controls the GPIOC Clock. SO we need to write a 1 to the 4th position in order to enable the PORT C clock
CONFIGURE the PIN
Now we will configure the pin as output pin. To do this, we need to modify the Port Configuration Register.
This Register is actually divided into 2 categories. Since we are using Pin PC13, we will be using Port configuration register high (GPIOx_CRH). For Pin 0 to 7, we will use GPIOx_CRL
Port Configuration Register controls both, mode and configuration for the Pin. 4 Bits are used to setup a single pin, for example, in order to set up PIN 10, we have to use bits 11:10:9:8
Since we are using the Pin PC13 for blinking the LED, we need to set it as the output mode. I am using the 10 MHz speed for the pin (there is no particular reason for it).
For the configuration part, i am choosing output Push Pull mode, as it’s best to use in simple GPIO operations.
This setup will lead us to configure the bits (23:22:21:20) as 0:0:0:1
- Here we will first call the SystemInit to configure the clocks
- next GPIO_Config to configure the PC13 as output
- Then TIM2_Config will configure the timer for the delay purpose
Now inside the while loop, we will turn the LED ON and OFF. To handle this, we need to look into the Port Bit Set Reset Register (GPIOx_BSRR)
GPIOx_BSRR is a 32 bit Register. The lower 16 Bits (0 to 15) are used to SET the Corresponding Bit. And the upper 16 bits (15 to 31) are used to RESET the corresponding bit
Since we are using PC13, in order to SET this pin, we will write a 1 to the 13th position, and in order to RESET it, we will write a 1 to the 29th position
There is s delay of 1 second between these two statements, and this will keep LED blinking every 1 second