banner



How To Access The Contents Of Registers In Arm Keil Software

This is the Series of tutorials on STM32 Microcontroller. The aim of this series is to provide easy and practical examples that anyone tin sympathize. Basically, you tin write GPIO codes in multiple ways (Using HAL, GPIO driver). Using that HAL you lot tin can finish your chore in ane line of code. But I would suggest you lot, larn to program using the bare-metal code (without any HAL or commuter) initially. This is the STM32 GPIO Tutorial without HAL.

You can also read, Getting started with STM32 RTOS, PIC16F877A GPIO tutorial, GPIO Linux device commuter, and STM32 GPIO RTOS tutorial.

Prerequisites

Before starting this STM32 GPIO Tutorial, Please get through the below tutorials.

  1. Create a New Projection for STM32 in Keil

STM32 GPIO Tutorial

Introduction

GPIO stands for "General Purpose Input/Output." We are using STM32F401VE for our examples. STM32F401VE  has v ports mentioned beneath.

  1. PORT A
  2. PORT B
  3. PORT C
  4. PORT D
  5. PORT Due east

Each port has 16 GPIO pins.

GPIO main features

  • Up to xvi I/Os under control
  • Output states: push-pull or open up-drain + pull-up/down
  • Output data from output information annals ( GPIOx_ODR ) or peripheral (alternate function output)
  • Speed selection for each I/O
  • Input states: floating, pull-up/downwards, analog
  • Input information to input data register ( GPIOx_IDR ) or peripheral (alternating function input)
  • Flake set and reset annals ( GPIOx_BSRR ) for bitwise write access to GPIOx_ODR
  • Locking machinery ( GPIOx_LCKR ) provided to freeze the I/O configuration
  • Analog part
  • Alternate function input/output pick registers (at most 16 AFs per I/O)
  • Fast toggle capable of irresolute every 2 clock cycles
  • Highly flexible pin multiplexing allows the employ of I/O pins every bit GPIOs or as one of several peripheral functions

STM32 GPIO Tutorial – Registers used in STM32 GPIO

At that place are a couple of registers used in GPIO. I have classified these register into 4 types based on their operation.

  1. Control Registers
  2. Information Registers
  3. Locking Registers
  4. Alternate Function Registers

Control Registers

Before looking into the control register, we will see the Clock Register ( RCC_AHB1ENR ) which will enable the AHB clock to the GPIO ports.

RCC_AHB1ENR

This is called as RCC AHB1 peripheral clock enable register. The register is given below.

GPIOx_AHB1ENR register

Bit [0] – GPIOAEN: IO port A clock enable

  • 0 – IO port A clock disabled
  • 1 – IO port A clock enabled

Scrap [1] – GPIOBEN: IO port B clock enable

  • 0 – IO port B clock disabled
  • one – IO port B clock enabled

Bit [2] – GPIOBEN: IO port C clock enable

  • 0 – IO port C clock disabled
  • 1 – IO port C clock enabled

Bit [3] – GPIOBEN: IO port D clock enable

  • 0 – IO port D clock disabled
  • 1 – IO port D clock enabled

Bit [4] – GPIOBEN: IO port E clock enable

  • 0 – IO port E clock disabled
  • i – IO port East clock enabled

We don't demand the remainder of the bits as nosotros are merely working on GPIO.

Example
//These are a couple of means of enabling AHB clock for Port A SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN); RCC->AHB1ENR |= (1UL << 0U);        

The below control registers are used to configure the GPIOs.

  • GPIO Port manner register ( GPIOx_MODER )
  • GPIO Port output type register ( GPIOx_OTYPER )
  • GPIO Port output speed register ( GPIOx_OSPEEDR )
  • GPIO Port Pullup/Pulldown register ( GPIOx_PUPDR )

GPIOx_MODER

This GPIO port mode annals is used to select the I/O management. Please notice the below image of the GPIOx_MODER register.

GPIOx_MODER registerHither 2-bits are combined for one particular GPIO pin.

Bits [31:0] – MODERy : Direction selection for port Ten and bit Y, (y = 0 … xv)

MODERy Direction Selection:

00: Input (reset state)
01: General purpose output mode
10: Alternate Function way
11: Analog mode

In this tutorial, we are using only the I/O operation. And so, we will apply either Input way or output mode.

Example
//makes Port A0 as output GPIOA->MODER = 0x00000001;  //makes Port A5 as output  GPIOA->MODER = 0x00000400;  //makes Port A every bit output GPIOA->MODER = 0x55555555;  //makes Port A every bit input GPIOA->MODER = 0x00000000;

GPIOx_OTYPER

This is the GPIO output blazon annals which is used to select the output type (Push-Pull or Open Bleed). Kickoff, nosotros need to know what is push button-pull and open drain.

Open-bleed output type

I think well-nigh of them are aware of this. If you have worked on I2C you must have heard this. But still, I will put my words. In open-drain mode, inside the microcontroller i switch (transistor/MOSFET) is continued to the GPIO pivot and the footing. So If you write high to the GPIO pin using software, it volition be continued to the ground through the switch. Which ways the original output is low. If you write low to the GPIO pin, it will be left floating since the switch will be turned off.  That's why nosotros are using a pullup resistor for the open-drain pins.

Button-Pull output type

Whereas in button-pull mode, two switches (transistor/MOSFET) will be there inside of the microcontroller. I switch is continued to Vcc/Vdd and another switch is connected to the ground. And then when you write Loftier to the GPIO pivot, the switch will be connected to the Vcc/Vdd. The resulting output will be high (1). And if you write low to the GPIO, then the switch volition be continued to the ground. The resulting output will be low (0).

Got some thought well-nigh both output modes? Okay, let's get to the annals now. Delight find the beneath image of the GPIOx_OTYPER annals.

GPIOx_OTYPER register

Here,

Bits [15:0] – OTy : Port output type, (y = 0 … 15)

  • 0 – Output Push button-Pull (reset state)
  • i – Output open-bleed

Bits [31:16] – Reserved (Must be kept at reset value).

GPIOx_OSPEEDR

This GPIO Output speed register is used to fix the speed of the GPIO pin. Please find the beneath image of the GPIOx_OSPEEDR register.

GPIOx_OSPPEDR registerHere 2-bits are combined for one particular GPIO pivot.

Bits [31:0] – OSPEEDRy : Speed selection for port 10 and bit Y, (y = 0 … 15)

OSPEEDRy Selection:

00: Depression Speed
01: Medium speed
10: High speed
eleven: Very high speed

GPIOx_PUPDR

This is the GPIO port pullup/pulldown register which is used to configure the GPIO pin into Pullup or pulldown style. Please detect the beneath image of the GPIOx_PUPDR annals.

GPIOx_PUPDR registerHere 2-bits are combined for one detail GPIO pin.

$.25 [31:0] – PUPDRy : pullup/pulldown option for port 10 and fleck Y, (y = 0 … 15)

PUPDRy Selection:

00: No pullup or pulldown
01: Pullup
10: Pulldown
11: Reserved

Case
//Enable Pullup on PA0  GPIOA->PUPDR = 0x00000001;  //Enable Pullup on PA  GPIOA->PUPDR = 0x55555555;

Information Registers

These data registers are used to make the store the data to be output/input. The beneath registers are used for output/input.

  1. Input data register ( GPIOx_IDR )
  2. Output data register ( GPIOx_ODR )
  3. Scrap Set/Reset register ( GPIOx_BSRR )

where, x = A, B, C, D, and E.

GPIOx_IDR

This is the Input Data Register. When yous configure the GPIO ports every bit input using GPIOx_MODER register, this annals is used to become the value from the GPIO pin. This register is a read-only register. And so you lot cannot write into it. Delight find the below image of the GPIOx_IDR register.

GPIOx_IDR RegisterHere,

Bits [15:0] – IDRy : Port Input Information, (y = 0 … 15)

This will be containing the corresponding value of the corresponding I/O port. And It can exist accessed in 32-bit give-and-take way only. Which means you cannot read a single bit. You have to read the whole register.

Bits [31:16] – Reserved (Must exist kept at reset value).

Example

Let's assume that I have configured PORT B as input, using the GPIOB_MODER register and other control registers. Now we can read the GPIO pins like below.

//Reading PB0 chip if( ( GPIOB->IDR & 0x01) == 0 )    {   //PORT B'south 0th fleck is 0 } else {   //PORT B's 0th bit is 1 }  //Reading total PB uint32_t value = GPIOB->IDR;  //Reading PB15 bool value = (( GPIOB->IDR >> xv ) & 0x1);

GPIOx_ODR

This is the Output Data Register. When you lot take configured GPIO Port as output using GPIOx_MODER register, this register is used to ready the value to the GPIO pin. We can read and write to the annals. Please detect the below image of the GPIOx_ODR annals.

GPIOx_ODR register

Bits [xv:0] – ODRy : Port Output Data, (y = 0 … fifteen)

We tin can write to the respective value of the corresponding I/O port.

$.25 [31:16] – Reserved (Must exist kept at reset value).

Note: When yous read the output data register, information technology will give you the terminal written value.

Case

Allow'due south assume that I have configured PORT B every bit output, using the GPIOB_MODER register and other control registers. Now we tin can write the GPIO pins like below.

//Write ane to the full Port B GPIOB->ODR = 0x0000FFFF;  //Write 0 to the full Port B GPIOB->ODR = 0x00000000;

Yous take to exist conscientious when you are writing the GPIO port using this GPIOx_ODR . Because you may disturb the other Pins (bits) of the register which you don't want to. So what if I want to write a unmarried fleck without agonizing others? There is a way to do that. Just keep reading.

GPIOx_BSRR

This is GPIO Bit Prepare/Reset Register. When you want to set or reset the particular bit or pivot, you lot can use this register. This is a write-only annals. This register volition do the diminutive set/reset. So we don't worry about the interrupts that causing problems during gear up/reset. And in this register, the lower sixteen-bits are used to set whatsoever of the 16 pins and the higher 16-bits to clear/reset any of the 16 pins of a item IO port. Delight discover the below image of the GPIOx_BSRR annals.

GPIOx_BSRR register

Bits [15:0] – BSy : Port Set Bit, (y = 0 … fifteen)

These $.25 are write-only and accessed in word, one-half-word, or byte mode. If you read this register you will get 0x00000000. If you write i to whatever flake [0 to 15], it will set the corresponding scrap in GPIOx_ODR register [0 to 15]. If you lot write 0 to whatsoever bit [0 to 15], no activity will exist performed to the corresponding chip in GPIOx_ODR annals [0 to 15].

Bits [31:sixteen] – BRy : Port Reset Fleck, (y = 0 … fifteen)

These $.25 are write-but and accessed in word, half-word, or byte mode. If you read this register you will get 0x00000000. If you lot write 1 to any fleck [16 to 31], information technology will set the respective bit in GPIOx_ODR annals [0 to 15]. If you write 0 to whatsoever bit [0 to 15], no action volition be performed to the corresponding chip in GPIOx_ODR register [0 to xv].

If you ready both BSx and BRx , BSx has the priority. So BRx will exist ignored. Where, ten = 0…15.

Example

Let'south assume that I accept configured PORT B as output, using the GPIOB_MODER register and other command registers. Now we can write the GPIO pins like below.

//set all the bits of Port B GPIOB->BSRR = 0x0000FFFF;  //Clear all the bits of Port B GPIOB->BSRR = 0xFFFF0000;  //Set the 5th bit of Port B GPIOB->BSRR = (1U << v);   //Clear the 5th bit of Port B GPIOB->BSRR = (1U << 21);

Locking Registers

This register is used to lock the configuration of the port bits. The below register is used to practise that.

  • GPIO Lock register ( GPIOx_LCKR )

GPIOx_LCKR

Using this register, you can freeze the GPIO configurations. In one case you practise the proper lock key write sequence, it volition lock the GPIOx_MODER , GPIOx_OTYPER , GPIOx_OSPEEDR , GPIOx_PUPDR , GPIOx_AFRL , and GPIOx_AFRH registers. Earlier we see how to do that, let's come across that register. Please find the below paradigm of the GPIOx_LCKR register.

GPIOx_LCKR registerThis can be accessed 32-bit word simply and you tin perform both read and write.

Bits [15:0] – LCKy : Port Gear up Bit, (y = 0 … fifteen)

  • 0 – Port configuration is not locked
  • i – Port configuration is locked

These bits can be written when the LCKK (16th bit) is 0.

$.25 [16] – LCKK : Lock Key

  • 0 – Port configuration lock key is not active
  • one – Port configuration lock key is not active

This bit can be read at any time. Simply if we want to modify the bit, nosotros have to follow the Lock key write sequence. Once you take locked the GPIO, and so it will exist locked until an MCU reset or a peripheral reset occurs.

$.25 [31:17] – Reserved (Must be kept at reset value).

Lock cardinal write sequence

As per the datasheet, below is the lock cardinal write sequence.

WR LCKR [ sixteen ] = '1' + LCKR [ fifteen : 0 ]

WR LCKR [ xvi ] = '0' + LCKR [ 15 : 0 ]

WR LCKR [ sixteen ] = '1' + LCKR [ 15 : 0 ]

RD LCKR

RD LCKR [ 16 ] = 'one' ( this read operation is optional just it confirms that the lock is active )

Note:During the Lock central write sequence, the value of LCK[xv:0] should not alter. And in some other STM32, this GPIOx_LCKR is not available for all the GPIO ports. So you should check with the datasheet before doing this. But in the STM32F401VE, GPIOx_LCKR register is available for all the GPIO ports.

Whatever error in the lock key write sequence aborts the lock. Once you accept done the lock key write sequence properly on any chip of the port, any read access on the LCKK bit will return '1' until the side by side CPU reset.

If y'all get confused, delight go through the below example.

/* ** The below total lawmaking snippet, locks the GPIO configuration of Port B.5 (PB5) */ #ascertain GPIO_PIN_POS (5U)    //I want to lock PB5. So setting 5th bit #ascertain LCKK_BIT_POS (16U)   //Position of LCKK fleck  volatile uint32_t lock_gpio = 0;  /* Lock central write sequence */ /* WR LCKR[sixteen] = 'i' + LCKR[5] = '1' */ lock_gpio = (( 1UL << LCKK_BIT_POS) | ( 1UL << GPIO_PIN_POS )); GPIOB->LCKR = lock_gpio;  /* WR LCKR[xvi] = '0' + LCKR[5] should not change*/ GPIOB->LCKR = ( 1UL << GPIO_PIN_POS );  /* WR LCKR[sixteen] = '1' + LCKR[5] should not change*/ GPIOB->LCKR = lock_gpio;  /* RD LCKR */ lock_gpio = GPIOB->LCKR; if((GPIOB->LCKR & ( 1UL << LCKK_BIT_POS)) != 0) {   //PB5 configuration has been locked } else {   //PB5 configuration has not been locked }        

Alternate Function Registers

Each GPIO pin has around sixteen alternative functions similar SPI, I2C, UART, etc. So we can tell the STM32 to apply our required functions.

The below-mentioned 2 registers are used to select the one function out of sixteen alternative function inputs/outputs available for each I/O.

  • Alternate Function Low annals ( GPIOx_AFRL )
  • Alternate Office High register ( GPIOx_AFRH )

GPIOx_AFRL

This 32-chip register is grouped by 4bits. Then This GPIOx_AFRL register is used to select the alternate functions of Pivot 0 to Pin vii. Please find the below image of the GPIOx_AFRL register.

GPIOx_AFRL register Bits [31:0] – AFRLy : Alternate role selection for port Ten and chip Y, (y = 0 … 7)

AFRLy Selection:

0000: AF0 (Alternate Function 0)
0001: AF1 (Alternating Function i)
0010: AF2 (Alternate Office 2)
0011: AF3 (Alternate Function 3)
0100: AF4 (Alternating Function four)
0101: AF5 (Alternate Function five)
0110: AF6 (Alternate Function half dozen)
0111: AF7 (Alternate Role 7)
m: AF8 (Alternating Function eight)
1001: AF9 (Alternate Role ix)
1010: AF10 (Alternate Role 10)
1011: AF11 (Alternate Part 11)
1100: AF12 (Alternating Function 12)
1101: AF13 (Alternate Role 13)
1110: AF14 (Alternate Function xiv)
1111: AF15 (Alternating Office 15)

GPIOx_AFRH

This 32-scrap annals is grouped by 4bits. So This GPIOx_AFRH annals is used to select the alternating functions of Pivot 8 to Pin 15. Please find the below image of the GPIOx_AFRH register.

GPIOx_AFRH register

$.25 [31:0] – AFRHy : Alternating function selection for port Ten and chip Y, (y = 0 … 7)

AFRHy Selection:

0000: AF0 (Alternate Function 0)
0001: AF1 (Alternating Role 1)
0010: AF2 (Alternate Role 2)
0011: AF3 (Alternating Function 3)
0100: AF4 (Alternate Part 4)
0101: AF5 (Alternating Function 5)
0110: AF6 (Alternate Function vi)
0111: AF7 (Alternate Function vii)
thou: AF8 (Alternate Function 8)
1001: AF9 (Alternating Function ix)
1010: AF10 (Alternating Part 10)
1011: AF11 (Alternating Function 11)
1100: AF12 (Alternating Office 12)
1101: AF13 (Alternate Function thirteen)
1110: AF14 (Alternate Office 14)
1111: AF15 (Alternating Part 15)

As of now, nosotros are using these pins as a GPIO and we are not selecting other functions than Input/Output. Then in our time to come post, we will hash out these GPIOx_AFRL and GPIOx_AFRH .

I retrieve nosotros have covered almost all the registers. Now we will just put them all together and make our hands muddy by playing with the LEDs. Let's dive into the programming office.

STM32 GPIO Tutorial – LED Interfacing with STM32

In the below instance, I have enabled all the Ports (A, B, C, D, and E) as an output. and toggling them with some delay. You can likewise notice the complete project on GitHub.

Code

/***************************************************************************//** *   \file       main.c * *   \details    Setting all the Ports (A, B, C, D, and E) as output  *               and toggling them with some random delay - STM32 GPIO Tutorial               * *   \author     EmbeTronicX * *   \This code is verified with proteus simulation * *******************************************************************************/  #include "stm32f4xx.h"   #define DELAY_COUNT    ( 30000 )   //delay count  /***************************************************************************//**    \details  Providing Delay by running empty for loop    \return   void    \retval   none  *******************************************************************************/ static void delay( void ) {     uint32_t i = 0;     for( i=0; i<=DELAY_COUNT; i++ ); }  /***************************************************************************//**    \details  The main function.  It should not return.    \return   void    \retval   none  *******************************************************************************/ int main(void){    //Enable the AHB clock all GPIO ports   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);    //set all Port A to Port E as output   GPIOA->MODER = 0x55555555;   GPIOB->MODER = 0x55555555;   GPIOC->MODER = 0x55555555;   GPIOD->MODER = 0x55555555;   GPIOE->MODER = 0x55555555;    //Endless loop   while(1){      //Plough ON the LED of all the ports     GPIOA->BSRR = 0x0000FFFF;     GPIOB->BSRR = 0x0000FFFF;     GPIOC->BSRR = 0x0000FFFF;     GPIOD->BSRR = 0x0000FFFF;     GPIOE->BSRR = 0x0000FFFF;      delay();      //Turn OFF the LED of all the ports     GPIOA->BSRR = 0xFFFF0000;     GPIOB->BSRR = 0xFFFF0000;     GPIOC->BSRR = 0xFFFF0000;     GPIOD->BSRR = 0xFFFF0000;     GPIOE->BSRR = 0xFFFF0000;      delay();   } }        

Output

Please notice the output of the example below.

STM32 GPIO Tutorial

STM32 GPIO Tutorial – Switch/Push button interfacing with STM32

I take connected the button to the PA0 (Port A.0) and LEDs to the PD0 to PD3. Y'all can likewise notice the project on GitHub.

Code

/***************************************************************************//** *   \file       primary.c * *   \details    Setting PORT D0 to D3 as output and PORT A0 as input. *               When we press the Port A0, we will plough on the PD0-PD3. - STM32 GPIO Tutorial * *   \author     EmbeTronicX * *   \This code is verified with proteus simulation * *******************************************************************************/  #include "stm32f4xx.h"    /***************************************************************************//**    \details  The main function.  It should not return.    \render   void    \retval   none  *******************************************************************************/ int main(void){    //Enable the AHB clock all GPIO PORT A and PORT D   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);   SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);    //set Port A as input   GPIOA->MODER = 0x00000000;   //Enable Pullup on PA0   GPIOA->PUPDR = 0x00000001;      //set PORTD0 to PORTD3 as output   GPIOD->MODER = 0x00000055;      //Plough OFF the LEDs of PORTD    GPIOD->BSRR = 0xFFFF0000;    //Endless loop   while(1){          //Button is connected to PA0. Then we need to cheque bit 0 of IDR register.     if( ( GPIOA->IDR & 0x01) == 0 )        {       //Turn ON the LEDs       GPIOD->BSRR = 0x0000000F;     }     else     {       //Turn OFF the LEDs        GPIOD->BSRR = 0x000F0000;     }   } }        

Output

Please find the output of the example below.

STM32 GPIO Tutorial

Note: The code is tested with the Proteus simulation. Not with the real hardware. If y'all take figured out whatsoever problems and issues with code while testing with the hardware, Please inform united states and provide the states as the workaround. So that, We will update here also. This will assistance others to learn.

If you want to use RTOS in STM32, you lot tin can refer to the STM32 GPIO with the RTOS tutorial.

You lot tin also read the below tutorials.

Linux Device Driver Tutorials C Programming Tutorials
FreeRTOS Tutorials NuttX RTOS Tutorials
RTX RTOS Tutorials Interrupts Nuts
I2C Protocol – Part one (Basics) I2C Protocol – Part 2 (Avant-garde Topics)
STM32 Tutorials LPC2148 (ARM7) Tutorials
PIC16F877A Tutorials 8051 Tutorials
Unit of measurement Testing in C Tutorials ESP32-IDF Tutorials
Raspberry Pi Tutorials Embedded Interview Topics
Reset Sequence in ARM Cortex-M4 BLE Basics
VIC and NVIC in ARM SPI – Serial Peripheral Interface Protocol
Bootloader Tutorials Raspberry PI Pico Tutorials
Zephyr RTOS Tutorials - STM32 Zephyr RTOS Tutorials - ESP32

How To Access The Contents Of Registers In Arm Keil Software,

Source: https://embetronicx.com/tutorials/microcontrollers/stm32/stm32-gpio-tutorial/

Posted by: joneswaseltory1969.blogspot.com

0 Response to "How To Access The Contents Of Registers In Arm Keil Software"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel