| ... | ... | @@ -4,7 +4,7 @@ GPIOs are grouped in ports and so each GPIO has an identifier. |
|
|
|
The identifiers have the following format: `PXY`, where `X` is the GPIO port name and `Y` is the pin number.
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
GPIO ports registers are mapped to well defined memory addresses. This means that by accessing those addresses, we can access the GPIO registers.
|
|
|
|
GPIO ports' registers are mapped to well defined memory addresses. This means that by accessing those addresses, we can access the GPIO registers.
|
|
|
|
Then, we can define a structure that represents the memory layout of the GPIO registers:
|
|
|
|
```cpp
|
|
|
|
typedef struct
|
| ... | ... | @@ -23,14 +23,14 @@ typedef struct |
|
|
|
```
|
|
|
|
Remmeber that strcut member's are allocated to consecutive addresses in memory.
|
|
|
|
|
|
|
|
In order to access a specific register (address) we need a pointer to the GPIO port.
|
|
|
|
In order to access a specific register (address) we need a pointer to a `GPIO_TypeDef` structure.
|
|
|
|
Assuming we want to control the `GPIOA` port and that it can be found at `0x48000000`:
|
|
|
|
```cpp
|
|
|
|
#define GPIOA ((GPIO_TypeDef *) 0x48000000)
|
|
|
|
```
|
|
|
|
By simply changing the pointer address we can access different GPIO ports.
|
|
|
|
By simply changing the pointer address we can access to different GPIO ports.
|
|
|
|
|
|
|
|
Via *bitwise operations* we can access the GPIO registers:
|
|
|
|
Via *bitwise operations* we can modify single bits of the GPIO registers:
|
|
|
|
```cpp
|
|
|
|
// set 5th bit of ODR to 1
|
|
|
|
GPIOA->ODR |= (1 << 4);
|
| ... | ... | |