Introduction to STM32 Blue Pill can be found in this blogpost
Creating header file to access registers in STM32F103C8T6
Programming in KEIL IDE:
main.c:
// Blinking Internal LED connected to Pin 13
#include "rcc_header.h"
#define IOPCEN ((uint32_t)1 << 4U) // Port C clock enable - bit 4
#define PC13_mode ((uint32_t)6 << 20U) // Output open-drain @2MHz
#define PC13_set ((uint32_t)1 << 13U) // Set Port C - pin 13
#define PC13_reset ((uint32_t)1 << 29U) // Reset Port C - pin 13
void delay(uint32_t);
void delay(uint32_t d) // approximate delay
{
for(; d; d--);
}
int main(void)
{
/* Enable PortC Clock
* Select PortC_Pin 13 as output @2MHZ
* Configure Pin 13 with open-drain */
RCC_map -> RCC_APB2ENR |= IOPCEN;
PortC_map -> GPIO_CRH |= PC13_mode;
PortC_map -> GPIO_BSRR = PC13_set; // Initialize PC13 LED - OFF
while(1)
{
PortC_map -> GPIO_BSRR = PC13_reset; // PC13 LED - ON
delay(10000000);
PortC_map -> GPIO_BSRR = PC13_set;
delay(10000000);
}
}
rcc_header.h:
#include <stdint.h>
#define RCC_baseaddr ((uint32_t) 0x40021000)
typedef struct
{
uint32_t RCC_CR;
uint32_t RCC_CFGR;
uint32_t RCC_CIR;
uint32_t RCC_APB2RSTR;
uint32_t RCC_APB1RSTR;
uint32_t RCC_AHBENR;
uint32_t RCC_APB2ENR;
uint32_t RCC_APB1ENR;
uint32_t RCC_BDCR;
uint32_t RCC_CSR;
} RCC_type;
#define RCC_map ((RCC_type*) RCC_baseaddr)
#define GPIO_PortC_base ((uint32_t) 0x40011000)
typedef struct // Common structure for all the ports
{
uint32_t GPIO_CRL;
uint32_t GPIO_CRH;
uint32_t GPIO_IDR ;
uint32_t GPIO_ODR;
uint32_t GPIO_BSRR;
uint32_t GPIO_BRR;
uint32_t GPIO_LCKR;
} GPIO_type;
#define PortC_map ((GPIO_type*) GPIO_PortC_base)
For creating delay using timer, refer next post
Explanation: Reference manual
1. Below are the available system clocks:
High speed: used as clock source to ADC, CRC, USB, AHB, APB1, APB2, DMA, etc.,
A. HSI (internal oscillator - 8 MHz)
B. HSE (external oscillator, can use 4 - 16 MHz)
Low speed: used for RTC and watchdog timer
C. LSI (internal - 40 kHz)
D. LSE (external - 32.768 kHz)
Using the RCC registers, clock source can be selected:
By default at reset, HSI is selected as clock source by hardware. The RCC registers can be used to select other sources like HSE by modifying the PLLs. We can also divide or multiply the clock frequency to get desired value for the peripherals.
(In Keil -> startup code, system clock is set to HSE with value of 72 MHz)
2. The LED is connected to PC13 pin of Port-C, so we need to enable clock for Port-C
which is under APB2 peripheral bus. Which is 4th bit of register RCC_APB2ENR
which is under APB2 peripheral bus. Which is 4th bit of register RCC_APB2ENR
boundary address of 0x4002 1000 (Refer RCC register map table and boundary address table
in reference manual)
3. To configure pin 13 as input / output or open-drain / push-pull, use register GPIOx_CRH
- one of the registers in GPIO register map.
Hint: This GPIO registers names are the same for all the GPIO ports, so we can reuse the
same structure for all the ports
We are configuring PC13 as output and open-drain because the internal LED already has a
resistor connected to it, below is the schematic
4. Now, use register GPIOx_BSRR or GPIOx_ODR to set and reset pin13 connected to onboard LED.
STM32 programming in KEIL:
1. Open KEIL
click on Project -> New uMission project -> provide project name
2. In the pop up window, select the board
STMicroelectronics -> STM32F1 series -> STM32F103 -> STM32F103C8 -> click ok
3. In the next pop up, select CORE under CMSIS and startup under Device -> click ok
(This will include all the necessary header files [stm32f10x.h], startup code, etc., to our project.
But in the above program, we are creating and using own user defined header file for registers,
which contains the required base addresses and structures just for this program)
4. In left window -> under Target 1 -> right click on Source group 1 -> Add New Item to Group
-> select C file (.c) and provide name
(repeat the same steps to create header file - .h)
5. After writing your program, click on option for target button or find that option in
Flash -> Configure Flash tools
In the pop up, click on Debug -> select STLink Debugger (or select the programmer
you are using) -> click ok
6. Then click on build button to build the program and load button to flash it
Hint: If you get chip mismatch issue, then after build, use STM32CubeProgrammer for flash
the hex file. In option for target -> output -> check the Create HEX file
7. To Debug: use debug options
- If debug option cant be used in Keil (because of fake chip), in STM32CubeProgrammer there
are options to read register values.
Comments
Post a Comment