O Efeito Hall
O efeito Hall é o surgimento de uma diferença de pontecial elétrico em um condutor elétrico, transversa a uma corrente elétrica no condutor e a campo magnético perpendicular à corrente (tradução minha para a introdução em inglês de http://en.wikipedia.org/wiki/Hall_effect).
Simplificando, se pegamos um condutor elétrico alimentado por uma fonte e o submetemos a um campo magnético, surge no condutor uma diferença de potencial entre as bordas perpendiculares à corrente e ao campo magnético.
Sensor de Efeito Hall
O sensor de efeito Hall utiliza o efeito Hall descrito acima em um semicondutor para detectar um campo magnético. Em alguns sensores, como o que estou usando, obtem-se uma tensão proporcional ao campo magnético. Em outros obtem-se apenas uma indicação de presença ou ausência do campo magnético (o que bastaria para o meu projeto).
Alguns detalhes adicionais podem ser vistos (em inglês) na wikipedia (em http://en.wikipedia.org/wiki/Hall_effect_sensor); tem uma animação bonitinha.
O ADC SD16_A
Como descrito (para variar) na Wikipedia inglesa (http://en.wikipedia.org/wiki/Analog-to-digital_converter#ADC_structures) existem várias formas de implementar um Conversor Anaógico Digital (ADC). O objetivo é sempre fornecer um número proporcional a uma tensão.
O funcionamento de um ADC usando modulação Sigma Delta pode ser visto (em inglês) em http://en.wikipedia.org/wiki/Sigma-delta_modulation#Analog_to_Digital_Conversion. Se eu entendi direito, a tensão de entrada (sinal analógico) é usada para gerar pulsos de largura constante espaçados por um tempo proporcional à tensão de entrada (esta é a parte delta). Estes pulsos são contados em um tempo fixo (esta é a parte sigma), fornecendo assim um valor digital proporcional à tensão de entrada. Isto permite construir ADCs com precisão muito boa (o que não deixa de ser um desperdício para o meu projeto).
A programação do SD16_A do MSP430F2113 pode ser encontrada no MSP430x2xx Family User's Guide. Eu me basei no Application Note SLAA283A (que você pode baixar daqui).
A programação é feita escrevendo em quatro registradores do SD16_A:
- SD16CTL: aqui selecionamos o clock e areferência. No nosso caso vamos usar como clock o SMCLK que virá do DCO. Como o limite do SD16_A é 1.1MHz, segui o Application Note e usei o DCO a 1MHz sem divisão. A referência que vamos usar é a interna (1.2V). Seguindo a recomendação do fabricante, o VMID buffer é ligado e pouco depois desligado para estabilizar o capacitor da referência.
- SD16INCTL0: controle da entrada. Mantemos o default de esperar quatro amostragens antes de interromper, usamos um ganho de 1 e escolhemos a entrada A3.
- SD16CCTL0: outro registrador de controle. Selecionamos o modo Single onde se dispara uma conversão e uma interrupção é gerada quando a conversão foi completada (a interrupção também é habilitada neste registrador). Pedimos o resultado na forma Unipolar, onde o resultado é um valor de 0 a 0xFFFF. Por último, usamos uma taxa de oversampling de 256.
- SD16AE: Habilita os pinos de entrada analógica (no nosso caos, P1.6 e P1.7).
O Programa de Teste
O programa de teste usa os LEDs para mostrar (em binário) a tensão na saída do sensor. Para testar o sensor basta aproximar ou afastar um imã e observar o valor nos LEDs. Aproveitando a idéia da Application Note, o programa economia energia deixando o clock e a referência ligados somente enquanto efetua uma conversão.
- /*
- Spoke-o-dometer
- Teste1 - teste do sensor
- Daniel Quadros - abril, 2009
- */
- #include <msp430.h>
- // Valor para contar 100ms c/ clock de 12KHz
- #define TEMPO_100MS 1200 // 100ms * 12KHz
- typedef unsigned char byte;
- // Rotinas Locais
- static void Led (unsigned int valor);
- // Programa Principal
- void main (void)
- {
- int cont = 0;
- // Desliga Watchdog
- WDTCTL = WDTPW + WDTSSEL + WDTHOLD;
- // Altera a configuração de clock para ativar o VLOCLK
- BCSCTL3 |= LFXT1S1;
- // Programa entradas e saídas
- P1SEL = 0xC0; // P1.0 a P1.5 -> LEDs
- // P1.6 e P1.7 são A3+ e A3-
- P1DIR = 0x3F;
- P1OUT = 0; // Todos as saídas em zero
- P2SEL = 0; // Todos os pinos como I/O
- P2DIR = 0xFF; // Todos os pinos como saída
- P2OUT = 0; // Todos as saídas em zero
- // Programa o ADC
- // MSP430F2013 -> SD16
- SD16CTL = SD16VMIDON + SD16REFON + SD16SSEL_1; // 1.2V ref, SMCLK
- SD16INCTL0 = SD16INCH_3; // PGA = 1x, Diff inputs A3- & A3+
- SD16CCTL0 = SD16SNGL + SD16UNI + SD16IE; // Single conversion, Unipolar, 256 SR, Int enable
- SD16CTL &= ~SD16VMIDON; // VMID off: used to settle ref cap
- SD16AE = SD16AE6 + SD16AE7; // P1.6 & P1.7: A3+/- SD16_A inputs
- // Dá um tempinho para estabilizar a alimentação
- while (cont < 0xFF)
- cont++;
- // Alimentação já deve estar estável, vamos ligar o DCO
- BCSCTL1 = CALBC1_1MHZ;
- DCOCTL = CALDCO_1MHZ;
- // Programar a interrupção de tempo real p/ cada 100ms
- TACCR0 = TEMPO_100MS;
- TACTL = TASSEL_1 + MC_1 + TAIE; // ACLK, up mode, interrupt
- // O nosso programa principal vai ficar dormindo,
- // todo o tratamento será feito na interrupção
- _BIS_SR(LPM3_bits + GIE); // Dorme tratando interrupção
- // Nuca vai chegar aqui
- while (1)
- ;
- }
- // Tratamento da interrupção do Timer A
- #pragma vector=TIMERA1_VECTOR
- __interrupt void Timer_A_TO(void)
- {
- switch (TAIV)
- {
- case 10: // overflow
- SD16CTL |= SD16REFON; // Liga a referência do SD16
- SD16CCTL0 |= SD16SC; // Inicia uma conversão
- _BIC_SR_IRQ (SCG1+SCG0); // Manter osciladores ligados
- break;
- case 2: // CCR1, não utilizado
- break;
- }
- }
- // Tratamento da interrupção do SD16
- #pragma vector = SD16_VECTOR
- __interrupt void SD16ISR(void)
- {
- unsigned int result;
- SD16CTL &= ~SD16REFON; // Desliga referência do SD16_A
- result = SD16MEM0; // Save result (clears IFG)
- Led (result);
- _BIS_SR_IRQ (SCG1+SCG0); // voltar para LPM3
- }
- // Mostra resultado nos LEDs
- static void Led (unsigned int valor)
- {
- // vamos mostrar somente os 7 bits mais significativos
- valor >>= 8;
- P1OUT = (P1OUT & 0xC0) | (valor & 0x3E);
- P2OUT = (P2OUT & 0x3F) | (valor & 0xC0);
- }
No próximo post vamos prender o nosso circuito à roda da bicicleta e ver o funcionamento do sensor em uma situação mais real.
Nenhum comentário:
Postar um comentário