Bibliotecas para ADC da FRDM-KL25Z

Biblioteca de GPIO

Olá caro leitor, este é segundo artigo da série Bibliotecas de Software para FRDM-KL25Z, onde apresentamos as bibliotecas para ADC da FRDM-KL25Z (Freedom Board KL25Z).

 

Como já foi dito no artigo anterior, essa biblioteca é parte de um conjunto de bibliotecas para outra biblioteca que estou desenvolvendo, para utilizar a FRDM-KL25Z em conjunto com o KiT de Automação Open Hardware.

 

No primeiro artigo foram apresentadas as funções de acesso aos pinos GPIO (General Purpose Input/Output). E neste segundo vamos apresentar as funções de leitura dos canais do Conversor Analógico Digital (ADC). 

 

As bibliotecas apresentadas são compatíveis com o Kinetis Design Studio IDE e CodeWarrior IDE. Também são facilmente portáveis para as demais placas Freedom Board. Essa biblioteca foi desenvolvida com base na série de artigos sobre o Desenvolvimento de sistemas embarcados com a KL05Z, escrita pelo Rodrigo Almeida.

 

 

Conversor Analógico Digital

 

O microcontrolador presente na Freedom Board FRDM-KL25Z possui conversor analógico digital de 16 bits por Aproximação Sucessiva (SAR ADC) e 14 canais. O ADC suporta tanto gatilhos de software quanto de hardware.

 

 

Inicializando o ADC

 

A seguir serão apresentadas as configurações mínimas para realizar a leitura do conversor analógico digital.

 

Configurando o CLOCK

 

O primeiro passo a ser dado é configurar o clock para o periféricos ADC. Para realizar operação deve configurar o registrador SIM_SCGC6 (System Clock Gating Control Register 6). Essa operação deve ser feita utilizando a macro SIM_SCGC5_ADC0_MASK.

 

Bibliotecas para ADC da FRDM-KL25Z: Registrador SIM_SCGC6
Registrador SIM_SCGC6

 

A seguir o código fonte demonstrando essa operação: 

/* Habilita Clock para ADC */
SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; 

 

Configurando o ADC

 

Para configurar o modo de operação do ADC deve-se usar o registrador ADC0_CFG1. Nesse registrador vamos configurar os seguintes itens: resolução da conversão, a fonte de clock e divisor do Clock.

 

Registrador ADC0_CFG1
Registrador ADC0_CFG1

 

Para configurar a resolução da conversão do ADC, são destinados dois bits do registrador ADC0_CFG1. São os bits 2 e 3 (item MODE do registrador). A seguir a tabela com as opções resoluções do conversor analógico digital.

 

Essa configuração dever ser feita utilizando a macro ADC_CFG1_MODE( n ). A variável n é o valor descrito na tabela.

 

Seleção do modo de conversão do ADC.
Seleção do modo de conversão do ADC.

 

Configurando a fonte de clock

 

Para configurar a fonte de Clock, são reservados os dois primeiros bits do registrador ADC0_CFG1 (1 – 0 ADICLOK). Essa configuração dever ser feita utilizando a macro ADC_CFG1_ADICLK( n ). A variável n é o valor descrito na tabela.

 

Seleção do clock de entrada.
Seleção do clock de entrada.

 

Divisor do Clock

 

O último item a ser configurado é o divisor interno do Clock do ADC. Este também é configurado em dois bits do registrador ADC0_CFG1, é o item ADIV. Essa configuração dever ser feita utilizando a macro ADC_CFG1_ADIV( n ). A variável n é o valor descrito na tabela.

 

Seleção do divisor do clock.
Seleção do divisor do clock.

  

/* Configurando o ADC */
ADC0_CFG1 |= (ADC_CFG1_MODE(3)  |  	// 16 bits mode
	     ADC_CFG1_ADICLK(0)|	// Input Bus Clock 
	     ADC_CFG1_ADIV(1)) ;	// Clock divide 

 

A seguir o código fonte header: 

/* */
#ifndef SOURCES_ADC_H_
#define SOURCES_ADC_H_

#include "MKL25Z4.h"

#define ADC_0	0	//  PTE20
#define ADC_1	4	//  PTE21
#define ADC_2	3	//  PTE22
#define ADC_3	7	//  PTE23
#define ADC_4	8	//  PTB0
#define ADC_5	9	//  PTB1
#define ADC_6	12	//  PTB2
#define ADC_7	13	//  PTB3
#define ADC_8	14	//  PTC0
#define ADC_9	15	//  PTC1
#define ADC_10 	11	//  PTC2
#define ADC_11 	5	//  PTD1   LED AZUL FRDM-KL25Z
//#define ADC_12 	6	//  PTD5
//#define ADC_13 	7	//  PTD6

#define _8BIT 0
#define _10BIT 1
#define _12BIT 2
#define _16BIT 3

void adc_init(uint8_t res);
uint16_t adc_read(uint16_t ch);

//int adc_cal(void);

#endif /* SOURCES_ADC_H_ */

 

Código fonte da função de inicialização adc_init()

/* 
*/
void adc_init(uint8_t res)
{
	// Enable clocks
	SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // ADC 0 clock

	// Configure ADC
	ADC0_CFG1 = 0; // Reset register

	ADC0_CFG1 |= (ADC_CFG1_MODE(res) | // resolução da conversão
	            ADC_CFG1_ADICLK(0) | // Input Bus Clock 
	            ADC_CFG1_ADIV(1));	 // Clock divide by 2 

	ADC0_SC3 = 0; // Reset SC3

	ADC0_SC1A |= ADC_SC1_ADCH(31); // Disable module
}

 

 

Lendo o ADC

 

Uma vez criada a função para inicializar o conversor analógico digital, agora devemos criar a função  para realizar a leitura dos canais ADC.

 

A seguir o código fonte da função para realizar a leitura do canal ADC: 

/* */
uint16_t adc_read(uint16_t ch)
{
	ADC0_SC1A = ch & ADC_SC1_ADCH_MASK; //Write to SC1A to start conversion
	while(ADC0_SC2 & ADC_SC2_ADACT_MASK); // Conversion in progress
	while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)); // Run until the conversion is complete
	return ADC0_RA;
}

 

A função adc_read recebe como parâmetro o número do canal a ser lido e retorna o resultado da conversão.

 

Na primeira linha temos o registrador ADC0_SC1A, que é responsável iniciar a conversão. Esse registador recebe o resultado da operação “and” entre o número do canal a ser lido e a macro “ADC_SC1_ADCH_MASK”. Essa operação tem como objetivo escrever nos bits ADCH do registrador.

 

Registrador ADC0_SCIA
Registrador ADC0_SCIA

 

Na segunda linha verifica-se se a conversão está em andamento. Nesta etapa vamos checar o registrador ADC0_SC2, especificamente o bit ADACT. Para realizar esta tarefa deve-se utilizar a macro ADC_SC2_ADACT_MASK.

 

Registrador ADC0_SC2
Registrador ADC0_SC2

 

Na terceira linha fica aguardando o termino da conversão. Essa etapa verifica o bit COCO do registrador ADC0_SC1A. Para essa etapa deve utilizar a macro ADC_SC1_COCO_MASK.

 

E por fim, na ultima linha é retornado o conteúdo do registrador ADC0_RA, que contém o resultado da conversão.

 

 

Exemplo de Aplicação 

 

O projeto que demostra o usa da biblioteca ADC é bem simples. O seu algoritmo é:

  • Realiza a leitura do canal ADC_5 (PTB1);
  • Se o valor do resultado da conversão for maior do 50000, acende o led vermelho e apaga o led verde;
  • Caso o valor seja menor, apaga o led vermelho e acende o led verde.

 

A seguir o código fonte do projeto: 

/*
Projeto: Aplicação com Biblioteca ADC 
*/
#include "MKL25Z4.h"
#include "adc.h"
#include "gpio.h"

uint16_t adc = 0;

int main(void)
{

    adc_init( _16BIT ); // Inicializa ADC
    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_set(PORT_B,19,1); // Desliga LED vermelho
    gpio_set(PORT_B,18,1); // Desliga LED verde

    for (;;)
    {
    	adc = adc_read( ADC_5 );	// Le ADC ~ PTB1

    	if(adc > 50000)
    	{
    		gpio_set(PORT_B,19,0); // Liga LED vermelho
    		gpio_set(PORT_B,18,1); // Desliga LED verde
    	}
    	else
    	{
    		gpio_set(PORT_B,18,0); // Liga LED verde
    		gpio_set(PORT_B,19,1); // Desliga LED vermelho
    	}
    }
}

 

 

Conclusão 

 

Neste artigo foi apresentada a biblioteca do conversor analógico digital para a Freedom Board KL25Z e projeto para demonstrar a utilização da biblioteca.

 

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

 

E por fim fica o meu convite para você leitor a contribuir com o desenvolvimento dessa biblioteca. Seja simplesmente testando ou colocando a mão na massa, melhorando as funções existentes ou até criando novas. A biblioteca se encontra no meu GitHub.

 

 

Referências 

 

FRDM-KL25Z
Reference Manual
Diretório do GitHub
https://en.wikipedia.org/wiki/Successive_approximation_ADC
https://community.nxp.com/docs/DOC-102951

Outros artigos da série

<< Biblioteca de GPIO para a placa FRDM-KL25ZBiblioteca SPI para a placa 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.

Deixe um comentário

avatar
 
  Notificações  
Notificar