19 de jun de 2012

Conversor Digital Analógico R2R

 

Conversores Digitais

Durante muito tempo fiquei intrigado com a eletrônica no que diz respeito a conversão de grandezas entre o mundo real e o mundo digital. No mundo real, as grandezas podem ser analisadas de forma contínua, já no mundo digital, onde temos a representação de grandezas em formado binário (temos apenas bits que podem valer 0 ou 1) estas grandezas devem ser discretizadas, ou seja, tanto o tempo (amostragem) quanto a amplitude (quantização) devem ser analisados.

O processo de amostragem do sinal consiste em obter instantâneamente o valor do sinal a ser processado em intervalos regulares, sendo que a frequência destes intervalos definem a taxa de amostragem do conversor.

Para que a resposta de um conversor digital possa ser substâncialmente eficiente em relação a entrada (conversor AD) ou a saída (conversor DA), se faz necessário que se respeite o teorema de Nyquist, que diz que a frequência de amostragem deve ser de pelo menos duas vezes maior que a maior frequência a ser amostrada. Um exemplo prático da aplicação desta teoria pode ser observada em aparelhos reprodutores de CD em que normalmente se informa a taxa de seu conversor interno que é de 44100Hz, ou seja mais de 2 vezes a maior frequência audível ao ser humano que está na faixa dos 20000Hz.

Harry Nyquist (1889–1976)

Harry Nyquist (1889–1976)


Conversor DA R2R

Neste projeto vamos efetuar a implementação de um conversor Digital Analógico utilizando um método muito eficiente de conversão que utiliza apenas dois valores de resistores, facilitando a construção e calibração do mesmo. Este conversor pode ser montado em um protoboard resistor por resistor ou comprado em um único package já contendo todos os resistores devidamente ajustados, este componente é conhecido como rede R2R. (R2R network)

Bourns-4610X-R2R-103LF

A placa PK2Lab, possui conectores de expansão que possibilitam a conexão de placas externas, como por exemplo a placa fornecida pela Mikroelektronica que consiste um em conversor DA R2R completo que pode fornecer uma corrente máxima de 20mA em sua saída.

Placa

Nesta placa podemos observar a utilização de resistores de dois valores distintos, sendo 47K e 100K representando respectivamente R e 2R conforme o esquema abaixo:

Esquema

Pode-se observar ainda a utilização de um amplificador do tipo Rail-to-Rail da Microchip operando como buffer de saída, está etapa pode ser obtida à partir de um simples amplificador operacional.

buffer

A vantagem de se utilizar amplificadores do tipo Rail-to-Rail, é o fato de a saída do sinal poder trabalhar praticamente no limite dos níveis de alimentação do operacional, isto é muito bem vindo quando trabalhamos com tensões de 3V por exemplo.

Até aqui temos o nosso hardware do conversor DA implementado, e para demonstrar o funcionamento do mesmo na prática, vamos gerar uma forma de onde senoidal podendo servir de base para um gerador de funções digital.

Para tanto, vamos utilizar uma tabela no microcontrolador que conterá os valores a serem aplicados na rede R2R do conversor DA para obtenção da senoide.

Esta tabela pode ser gerada contendo todos os pontos que formam a senoide completa de 0 a 2 pi de forma direta ponto a ponto, como mostrado no programa picseno1, ou utilizando a função de cosseno para gerar metade da senoide, sendo a outra metade é obtida através do espelhamento da primeira que será apresentada implementado no programa picsen2.

 

coseno

Função Cosseno

seno

Função Seno obtida da junção da função cosseno direta e espelhada

 

A função cosseno que será usada para criar a tabela pode ser implementada no MikroC PRO utilizando uma função interna do compilador.

cosE3 (ângulo em graus)

Esta função retorna o valor do cosseno do ângulo passado como parâmetro multiplicado por 1000 e arredondado para um valor inteiro aproximado. Exemplo: cosE3(45) resulta em 707 que corresponde a 0.707 valor do cosseno de 45°.

Para definir a frequência de saída do gerador, podemos utilizar a fórmula abaixo que leva em consideração a quantidade de pontos de amostra e a frequência desejada para definirmos o tempo de delay para a amostragem do sinal.

Valor_Delay = 1/(frequência * 360)

Como utilizamos 360 pontos para criar a nossa forma de onda, obtivemos um resultado muito bom, mesmo sem a utilização de filtro passa baixa na saída.

Fotos do projeto:

foto (2)

foto (1)

 

 


Programa picsen1.c

/******************************************************************************

                      JL Audio Manutenção Eletrônica

Data: Junho 2012
Autor: Jean Carlos
Projeto: Gerador Senoidal
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:

          Gerador de sinal senoidal utilizando tabela de referencia


*******************************************************************************/
// Inicializações do programa

// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

//******************************************************************************
// Variáveis Globais

char amostra;
char tabela_Seno[] =
{127, 130, 133, 136, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173,
176, 179, 182, 185, 187, 190, 193, 195, 198, 201, 203, 206, 208, 211, 213, 215,
217, 220, 222, 224, 226, 228, 230, 232, 233, 235, 237, 238, 240, 241, 242, 244,
245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 253, 254, 254, 254, 254, 255,
255, 254, 254, 254, 254, 253, 253, 252, 252, 251, 250, 250, 249, 248, 247, 246,
244, 243, 242, 240, 239, 237, 236, 234, 232, 231, 229, 227, 225, 223, 221, 219,
216, 214, 212, 209, 207, 204, 202, 199, 197, 194, 191, 189, 186, 183, 180, 177,
175, 172, 169, 166, 163, 160, 157, 154, 150, 147, 144, 141, 138, 135, 132, 129,
125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94, 91,88, 85, 82, 79, 77, 74,
71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 42, 40, 38, 35, 33, 31, 29, 27, 25,
23, 22, 20, 18, 17, 15, 14, 12, 11, 10, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 17,
19, 21, 22, 24, 26, 28, 30, 32, 34, 37, 39, 41, 43, 46, 48, 51, 53, 56, 59, 61,
64, 67, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96,99,102, 105, 108, 111, 114, 118,
121, 124, 127 };

//******************************************************************************
//Rotina Principal


void main()
{
TRISA     = 0b00000000;
PORTA   = 0b00000000;
TRISB     = 0b00000000;
PORTB   = 0b00000000;
TRISC     = 0b00000000;
PORTC   = 0b00000000;
TRISD     = 0b00000000;
PORTD   = 0b00000000;
TRISE     = 0b00000000;
PORTE   = 0b00000000;
ADCON1 = 0X0F;                                           // Entradas digitais.

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Gerador Senoidal");

while(1)
{
  for(amostra = 0; amostra <= 256; amostra++)
     {
     PORTD = Tabela_Seno[amostra];
     delay_us(65);                                       // Delay = 1/(Freq*256)
     }                                                   // Para 60Hz --> 1/(60*256) = 65us
}
}


Programa picsen2.c

/******************************************************************************

                      JL Audio Manutenção Eletrônica

Data: Junho 2012
Autor: Jean Carlos
Projeto: Gerador Senoidal 60Hz
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:

          Este circuito gera uma senoide de 60Hz com 180 Amostras


*******************************************************************************/
// Inicializações do programa

// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

//******************************************************************************
// Variáveis Globais

char sample;
char array[181];

//******************************************************************************
//Rotina Principal


void main() {
TRISA     = 0b00000000;
PORTA   = 0b00000000;
TRISB     = 0b00000000;
PORTB   = 0b00000000;
TRISC     = 0b00000000;
PORTC   = 0b00000000;
TRISD     = 0b00000000;
PORTD   = 0b00000000;
TRISE     = 0b00000000;
PORTE   = 0b00000000;
ADCON1 = 0X0F;                                                           // Entradas digitais.

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Gerador Senoidal");
Delay_ms(1000);
 
  for (sample = 0; sample <= 180; sample++)                   // 181 amostras de 0 a pi
  {                                                                                
    array[sample] = (255l * (1000 + cosE3(sample)))/2000;

  }

  while(1)
  {
    for (sample = 0; sample <= 180; sample++)                 // Amostras de 0 a pi
    {

      PORTD = array[sample];                                          // Delay = 1/(Freq*360)
      Delay_us(46);                                                          // Para 60Hz 46.29us

    }
        
    for (sample = 179; sample > 0; sample—)                    // Amostras de pi a 2pi
    {
      PORTD = array[sample];
      Delay_us(46);
    }
  }
}