Este tópico é uma alteração do exemplo demonstrado anteriormente com funções em assembly.
Acessando Registradores Mapeados em Memória
Os registradores estão mapeados em memória e portanto são acessados a partir de endereços únicos. Isto é, cada registrador possui uma posição fixa na memória. Para entender a estrutura básica de um registrador e as operações para configurá-los, acesse o conteúdo sobre programação de periféricos mapeados em memória.
Utilizando a linguagem C, basta indicar o endereço e realizar o acesso via ponteiro:
*endereço = valor;
Tal procedimento é mostrado a seguir.
#include <stdint.h>
#define SIM_SCGC5 (*(volatile uint32_t *)0x40048038)
#define PORTB_PCR18 (*(volatile uint32_t *)(0x4004A000 + 4*18))
#define GPIOB_PDOR (*(volatile uint32_t *)0x400FF040)
#define GPIOB_PSOR (*(volatile uint32_t *)0x400FF044)
#define GPIOB_PCOR (*(volatile uint32_t *)0x400FF048)
#define GPIOB_PTOR (*(volatile uint32_t *)0x400FF04C)
#define GPIOB_PDIR (*(volatile uint32_t *)0x400FF050)
#define GPIOB_PDDR (*(volatile uint32_t *)0x400FF054)
#define RED_MASK (1 << 18)
void redon(void){
//ativar o bit 18 do registrador PCOR.
//GPIOB_PCOR = (RED_MASK);
//ou desativar somente o bit 18 do registrador PDOR
GPIOB_PDOR = GPIOB_PDOR & ~(RED_MASK);
}
void redoff(void){
//ativar o bit 18 do registrador PSOR.
//GPIOB_PSOR = (RED_MASK);
//ou ativar somente o bit 18 do registrador PDOR
GPIOB_PDOR = GPIOB_PDOR | (RED_MASK);
}
void init_gpio(void){
//ativar somente o bit 10 do registrador SCGC5.
SIM_SCGC5 = SIM_SCGC5 | (1 << 10);
//ativar o bit 8 do registrador PORTB_PCR18
PORTB_PCR18 = (1 << 8);
//ativar o bit 18 do registrador PDDR
GPIOB_PDDR = (RED_MASK);
}
int main()
{
//configurações iniciais
init_gpio();
while(1){
//programa em loop infinito
redon();
redoff();
}
return 0;
}
Encapsulando Registradores
Os registradores podem ser agrupados em uma estrutura de dados para facilitar o acesso. Por exemplo, os registradores GPIOB_PDOR até GPIOB_PDDR estão posicionados sequencialmente na memória. Esse grupo de registradores é denominado GPIOB.
Cabe ressaltar que utilizando essa técnica outros módulos de GPIO podem ser acessados, pois apresentam a mesma sequência. Isto é, a estrutura do módulo é a mesma, a única diferença é o endereço dos registradores.
#include <stdint.h>
#define SIM_SCGC5 (*(volatile uint32_t *)0x40048038)
#define PORTB_PCR18 (*(volatile uint32_t *)(0x4004A000 + 4*18))
struct GPIO{
uint32_t PDOR;
uint32_t PSOR;
uint32_t PCOR;
uint32_t PTOR;
uint32_t PDIR;
uint32_t PDDR;
};
#define GPIOB ((volatile struct GPIO *)0x400FF040)
#define RED_MASK (1 << 18)
void redon(void){
//ativar o bit 18 do registrador PCOR.
//GPIOB->PCOR = (RED_MASK);
//ou desativar somente o bit 18 do registrador PDOR
GPIOB->PDOR = GPIOB->PDOR & ~(RED_MASK);
}
void redoff(void){
//ativar o bit 18 do registrador PSOR.
//GPIOB->PSOR = (RED_MASK);
//ou ativar somente o bit 18 do registrador PDOR
GPIOB->PDOR = GPIOB->PDOR | (RED_MASK);
}
void init_gpio(void){
//ativar somente o bit 10 do registrador SCGC5.
SIM_SCGC5 = SIM_SCGC5 | (1 << 10);
//ativar o bit 8 do registrador PORTB_PCR18
PORTB_PCR18 = (1 << 8);
//ativar o bit 18 do registrador PDDR
GPIOB->PDDR = (RED_MASK);
}
int main()
{
//configurações iniciais
init_gpio();
while(1){
//programa em loop infinito
redon();
redoff();
}
return 0;
}