Biblioteca de GPIO para a placa FRDM-KL25Z

Biblioteca de GPIO

Olá caro leitor, iniciarei uma nova série de artigos abordando algumas bibliotecas que desenvolvi para a FRDM-KL25Z. Essas bibliotecas servirão como base para as aplicações que estou desenvolvendo, utilizando a FRDM-KL25Z em conjunto com o KiT de Automação Open Hardware.

 

Neste primeiro artigo serão apresentadas as funções de acesso ao General Purpose Input/Output (GPIO).

 

A biblioteca apresentada é compatível com o Kinetis Design Studio IDE e CodeWarrior IDE, e também é facilmente portável para as demais Freedom Boards. Essa biblioteca foi desenvolvida tomando como base a série de artigos Desenvolvimento de sistemas embarcados com a KL05Z, escrita pelo Rodrigo Almeida.

 

 

Freedom Board KL25Z

 

Antes de detalhar a biblioteca, vamos apresentar a plataforma que será utilizada.

 

A FRDM-KL25Z é uma placa de baixo custo que contém como microcontrolador alvo o Kinetis KL25Z128VLK4, um ARM Cortex-M0+ que pode operar a até 48 MHz.

 

Principais características deste microcontrolador:

  • Memória Flash de 128 KB;
  • Memória RAM de 16 KB;
  • Conversor Analógico Digital ADC de 16 bits;
  • Conversor Digital Analógico DAC de 12 bits.

 

Essa placa é equipada com os seguintes periféricos:

  • Slider touch capacitivo;
  • Um acelerômetro MMA8451Q;
  • Um LED RGB;
  • Footprint compatível com Arduino;
  • Interface de debug OpenSDA da P&E Multilink, compatível com diversas IDE's (utiliza porta USB de alimentação).

 

Para informações mais detalhadas sobre a placa, eu recomendo o artigo Conheça a FRDM KL25Z da NXP publicado pelo Fábio Souza.

 

Bom! Feita uma breve apresentação da FRDM-KL25Z, vamos agora apresentar a biblioteca desenvolvida.

 

 

Biblioteca de GPIO

 

A biblioteca de GPIO possui dois arquivos gpio.c (Code) e gpio.h (Header). O arquivo gpio.c possui o código fonte e o arquivo gpio.h contém as definições e os protótipos das funções. Para essa biblioteca foram criadas quatro funções, gpio_direction, gpio_set, gpio_toggle e gpio_read.

 

A seguir temos o arquivo gpio.h. Este arquivo contém todas as definições e os protótipos das funções.

 

/*
 gpio.h
*/

#include "derivative.h" 
#include <MKL25Z4.h> /* I/O map for MKL25Z128VLK4 */

#ifndef PORT_PCR_PE(x)
#define PORT_PCR_PE(x) (((uint32_t)(((uint32_t)(x))<<PORT_PCR_PE_SHIFT))&PORT_PCR_PE_MASK)
#endif

#ifndef bool
typedef unsigned char bool;
#endif

#define PORT_A 	0
#define PORT_B 	1
#define PORT_C 	2
#define PORT_D 	3
#define PORT_E 	4
#define OUTPUT 	1
#define INPUT 	0
#define HIGH 	1
#define LOW 	0

#define PULL_RESISTOR 1			// habilita pull resistor
#define NO_PULL_RESISTOR 0

void gpio_direction(uint8_t port, 	 	// numero do port
                    uint8_t pin, 	 	// numero de pino (bit)	
                    uint8_t mode, 	 	// entrada ou saída 
                    bool pull_resistor);// pull resistor 
					
void gpio_set(uint8_t port, 			// numero do port
              uint8_t pin, 			// numero do pino
              uint8_t value);			// valor (0 ou 1)		

void gpio_toggle(uint8_t port, 			// numero do port
                 uint8_t pin) 			// numero do pino (bit)	

uint16_t gpio_read(uint8_t port, 		// numero do port
                   uint8_t pin);		// numero do pino (bit)					 

 

 

gpio_direction

 

A função “gpio_direction” é destinada para inicialização dos GPIOs. Essa, por sua vez, recebe diversos parâmetros, que são eles:

  • número do “PORT”;
  • número do pino (Bit);
  • configuração do pino: entrada ou saída (INPUT ou OUTPUT) e Pull Resistor (habilitado ou desabilitado).

 

A seguir o código dessa função:

void gpio_direction(uint8_t port, uint8_t pin, uint8_t mode,bool pull_resistor)
{
	switch(port)
	{	    
		case PORT_A:
			SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
			PORT_PCR_REG(PORTA_BASE_PTR,pin) = PORT_PCR_MUX(1);
			if(pull_resistor == PULL_RESISTOR)
			{
				PORT_PCR_REG(PORTA_BASE_PTR,pin) |= PORT_PCR_PE(1);
			}
			if(mode == OUTPUT)
			{
				GPIOA_PDDR |= (1 << pin);
			}
			else if(mode == INPUT)
			{
				GPIOA_PDDR &=~ (1 << pin);
			}			
		break;
		//...
}

 

 

gpio_set

 

A função “gpio_set” foi desenvolvida para o acionamento dos GPIOs, inicializados no modo de saída (OUTPUT). Os parâmetros que essa função recebe são:

  • o número do “PORT”;
  • o número do pino (bit) e;
  • valor que deseja enviar para a saída (0 ou  1).

 

A seguir o código dessa função:

void gpio_set(uint8_t port, uint8_t pin, uint8_t value)
{
	switch(port)
	{
		case PORT_A:
			if(value == HIGH)
			{
				GPIOA_PSOR |= (1 << pin);
			}
			else if(value == LOW)
			{
				GPIOA_PDOR &=~ (1 << pin);
			}
		break;
		//...
}

 

 

gpio_toggle

 

A função “gpio_toggle” tem como objetivo inverter valor do GPIO. Essa função recebe dois parâmetros:

  • o número do "PORT" e;
  • o número do pino (bit).

 

A seguir o código da função:

void gpio_toggle(uint8_t port, uint8_t pin)
{
	switch(port)
	{
		case PORT_A:
			GPIOA_PTOR = (1 << pin);
		break;
		//...
}

 

 

gpio_read

 

Para ler o valor dos GPIOs foi criada a função “gpio_read”, uma vez que o pino foi inicializado como entrada (INPUT). Essa função recebe dois parâmetros, são eles:

  • o número do "PORT" e;
  • o número pino.

 

O retorno é valor que está presente no IO. A seguir o código da função:

uint16_t gpio_read(uint8_t port, uint8_t pin)
{
	switch(port)
	{
		case PORT_A:
			return (GPIOA_PDIR & (1 << pin));
		break;
		// ...
}

 

 

Utilizando a Biblioteca de GPIO

 

Para demostrar o uso da biblioteca de GPIO foi criado o projeto pisca LED RGB

 

A seguir, temos uma figura com o circuito elétrico do LED RGB, onde podemos identificar quais são os IOs que devemos acionar. O LED vermelho está no PTB18, o verde no PTB19 e azul PTD1.

 

Circuito elétrico LED RGB
Figura 1 - Circuito elétrico LED RGB

 

A seguir o código fonte do projeto Pisca LED RGB:

/* 
 * Projeto: Pisca LED RGB  
 */
#include "derivative.h" /* include peripheral declarations */
#include "gpio.h"       /* Inclui a biblioteca gpio*/  


int main(void)
{ 
	uint16_t i = 0;
	uint8_t led = 0;
	
	gpio_direction(PORT_B,18,OUTPUT,NO_PULL_RESISTOR); // Inicializa IO PTB18 - LED Vermelho
	gpio_direction(PORT_B,19,OUTPUT,NO_PULL_RESISTOR); // Inicializa IO PTB19 - LED Verde
	gpio_direction(PORT_D,1, OUTPUT,NO_PULL_RESISTOR); // Inicializa IO PTB18 - LED Azul

	gpio_set(PORT_B,18,HIGH); // Apaga LED Vermelho
	gpio_set(PORT_B,19,HIGH); // Apaga LED Verde
	gpio_set(PORT_D,1, HIGH); // Apaga LED Azul

	for(;;)
	{
		switch(led)
		{	
			case 0:
				gpio_toggle(PORT_B,18);	// Inverte valor do IO 
				led = 1;
			break;
			case 1:
				gpio_toggle(PORT_B,19); // Inverte valor do IO 
				led = 2;
			break;
			case 2:
				gpio_toggle(PORT_D,1);  // Inverte valor do IO 
				led = 0;
			break;
		}
		for(i=0;i<50000;i++);
	}
}

 

 

Conclusão

 

Neste artigo foi apresentada a biblioteca de acesso General Purpose Input/Output GPIO para a Freedom Board KL25Z e o projeto demonstrando sua aplicação.

 

Nos próximos artigos vamos apresentar outras bibliotecas (ADC, Timer, UART e entre outras) para utilizar com esse hardware.

 

 

Referências

 

FRDM-KL25Z

Reference Manual 

Diretório do GitHub 

Outros artigos da série

Bibliotecas para ADC da FRDM-KL25Z >>
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Evandro Teixeira
Desenvolvedor de Sistemas Embarcados. Sou formado Técnico em Instrumentação e Automação Industrial/Mecatrônica pelo Colégio Salesiano Dom Bosco de Americana-SP, cursei o Engenharia Elétrica com Ênfase em Eletrônica pela UNISAL Centro Universitário Salesiano de São Paulo e atualmente estou cursando Superior de Tecnologia em Análise e Desenvolvimento de Sistemas pela UNIP Universidade Paulista.

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Evandro TeixeiraJorge Guzman Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Jorge Guzman
Visitante
Jorge Guzman

Olá Evandro, Parabens pelo artigo, eu comecei a montar uma lib GPIO igual a sua tempos atrás, praticamente seguindo a mesma interface das suas funções ( void gpio_set(uint8_t port, uint8_t pin, uint8_t value) ), após uma conversa com o prof. Rodrigo almeida que também escreve no canal ele me sugeriu algumas melhorias na lib, eu gostaria de passar elas com você também. Primeiramente todos os pinos são referenciados como algum numero, exemplo: #define PB0 3 #define PB1 4 #define PB2 19 #define PB3 38 #define PB4 7 #define PB5 2 #define PB6 14 #define PB7 15 Eu uso essas referencias… Leia mais »