Escreva um código para fazer interface com o ADC de um microcontrolador genérico. O ADC deste microcontrolador possui 4 registradores para interface. O registrador ADC_CONFIG, posicionado sob o endereço 0x40001666, o registrador ADC_DATA_1, sob o endereço
, o registrador ADC_DATA__2, sob o endereço 0x40001697 e o registrador ADC_START_WAIT, sob o endereço 0x40001660. Os registradores são de oito (8) bits. As tabelas abaixo ilustram o significado de cada bit dos registradores.
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
NOME
Endereço
CH
EN
ADC_CONFIG
habilita
ADC e coloca em funcionamento
seleciona o canal para aquisição. Bit em nivel alto (a) para canal 1 e nivel baixo (0) para canal 2.
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
NOME
Endereço
DATA Lo
ADC_DATA_1
0×40001687
DATA Lo
byte menos significativo da conversão
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
NOME
Endereço
DATA Hi
ADC_DATA_2
DATA Hi
bits mais significatrivos do resultado da conversão
bit7
bit6
bit5
bit4
bit3
bit2
bit1
bit0
NOME
Endereço
WAIT
GO
ADC_START_WAIT
GO = inicia a conversão
WAIT = bit fica preso em valor alto (1) enquanto a conversão está em curso.
Ele vai para zero (0) quando a conversão termina.
Tabela 1 - Datasheet Registradores ADC
Você deve escrever um código para efetuar a leitura de um potenciômetro, conectado ao canal 1 do ADC. A frequencia de amostragem deve ser 100 Hz e deve ser feita via pooling, com o auxilio da função
Template para código:
void main(void)
{
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | NOME | Endereço | ||
CH | EN | ADC_CONFIG |
|
||||||||
|
|||||||||||
|
|||||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | NOME | Endereço | ||
DATA Lo | ADC_DATA_1 | 0×40001687 | |||||||||
DATA Lo
|
|||||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | NOME | Endereço | ||
DATA Hi | ADC_DATA_2 |
|
|||||||||
DATA Hi
|
|||||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | NOME | Endereço | ||
WAIT | GO | ADC_START_WAIT |
|
||||||||
GO = inicia a conversão | |||||||||||
|
Você deve escrever um código para efetuar a leitura de um potenciômetro, conectado ao canal 1 do ADC. A frequencia de amostragem deve ser 100 Hz e deve ser feita via pooling, com o auxilio da função
Template para código:
void main(void)
{
Passo 1
Beleza, vamos lá! O exercício pede para gente escrever um código que faça a leitura de um potenciômetro usando o ADC (Conversor Analógico para Digital) de um microcontrolador genérico. A gente vai precisar mexer com registradores específicos do ADC, entender como configurar esses registradores para selecionar o canal certo, iniciar a conversão, esperar ela terminar e, finalmente, ler os valores convertidos. Além disso, precisamos fazer isso com uma frequência de 100 Hz, ou seja, uma leitura a cada 10 milissegundos, usando polling (verificação contínua).
Passo 2
Primeiro, vamos configurar o ADC. Para isso, usamos o registrador
ADC_CONFIG
que está no endereço 0x40001666
. Esse registrador tem dois bits importantes:- EN (bit0): Habilita o ADC.
- CH (bit1): Seleciona o canal de leitura. Como queremos ler do canal 1, precisamos colocar esse bit em 1.
Então, nossa primeira tarefa é escrever esses valores no registrador
ADC_CONFIG
para habilitar o ADC e selecionar o canal 1.Passo 3
Agora que o ADC está configurado, precisamos iniciar a conversão. Para isso, usamos o registrador
ADC_START_WAIT
no endereço 0x40001660
. Esse registrador também tem dois bits importantes:- GO (bit0): Inicia a conversão quando colocado em 1.
- WAIT (bit2): Fica em 1 enquanto a conversão está em andamento e volta para 0 quando termina.
Então, após iniciar a conversão colocando o bit GO em 1, vamos entrar num loop que vai verificar o estado do bit WAIT. Quando ele voltar para 0, sabemos que a conversão terminou.
Passo 4
Com a conversão concluída, os dados convertidos ficam armazenados nos registradores
ADC_DATA_1
e ADC_DATA_2
. O ADC_DATA_1
contém os bits menos significativos (LSB) e o ADC_DATA_2
os bits mais significativos (MSB) da conversão. Para obter o valor final, precisamos ler ambos os registradores e combinar esses bits. Isso vai nos dar o valor digital correspondente à posição do potenciômetro.Passo 5
Por último, precisamos garantir que estamos fazendo as leituras a uma frequência de 100 Hz, ou seja, uma a cada 10 milissegundos. Para isso, vamos implementar um atraso (
delay
) de 10 ms após cada leitura. Em um microcontrolador real, isso pode ser feito usando timers, mas aqui vamos simplificar usando uma função de espera.Resposta
#include <stdint.h>
// Definição dos endereços dos registradores
#define ADC_CONFIG (*(volatile uint8_t*)0x40001666)
#define ADC_DATA_1 (*(volatile uint8_t*)0x40001687)
#define ADC_DATA_2 (*(volatile uint8_t*)0x40001697)
#define ADC_START_WAIT (*(volatile uint8_t*)0x40001660)
// Máscaras para os bits do ADC_CONFIG
#define ADC_CONFIG_EN (1 << 0) // Bit 0 - EN
#define ADC_CONFIG_CH (1 << 1) // Bit 1 - CH
// Máscaras para os bits do ADC_START_WAIT
#define ADC_START_GO (1 << 0) // Bit 0 - GO
#define ADC_START_WAIT_BIT (1 << 2) // Bit 2 - WAIT
// Função de delay simplificada (substituir por implementação real)
void delay_ms(int ms) {
// Implementação de delay depende do microcontrolador
// Aqui estamos apenas representando a ideia
for(int i = 0; i < ms * 1000; i++);
}
void main(void)
{
// Passo 2: Configurar o ADC
// Habilita o ADC e seleciona o canal 1
ADC_CONFIG = ADC_CONFIG_EN | ADC_CONFIG_CH;
while(1)
{
// Passo 3: Iniciar a conversão
ADC_START_WAIT |= ADC_START_GO;
// Esperar a conversão terminar
while(ADC_START_WAIT & ADC_START_WAIT_BIT)
{
// Loop de espera (polling)
}
// Passo 4: Ler os dados
uint8_t data_lo = ADC_DATA_1; // Dados menos significativos
uint8_t data_hi = ADC_DATA_2; // Dados mais significativos
// Combinar os dados para obter o valor final
uint16_t adc_value = (data_hi << 8) | data_lo;
// Aqui você pode usar o valor adc_value conforme necessário
// Por exemplo, enviar para uma porta serial, ajustar um display, etc.
// Passo 5: Aguardar 10 ms para manter a frequência de 100 Hz
delay_ms(10);
}
}
Explicação do Código
-
Definições de Registradores: Usamos
#define
para mapear os endereços dos registradores para facilitar o acesso no código. -
Máscaras de Bits: Definimos máscaras para os bits que vamos manipular em cada registrador, facilitando a configuração e verificação dos mesmos.
-
Função de Delay: Criamos uma função
delay_ms
simplificada para representar a espera de 10 ms. Em um microcontrolador real, você deveria usar timers ou métodos mais precisos. -
Configuração do ADC: No início do
main
, configuramos o ADC para habilitar e selecionar o canal 1 escrevendo nos bits correspondentes doADC_CONFIG
. -
Loop Principal:
- Iniciar Conversão: Colocamos o bit GO em 1 para iniciar a conversão.
- Esperar Conversão: Usamos um
while
para ficar verificando o bit WAIT até que ele volte para 0, indicando que a conversão terminou. - Ler Dados: Após a conversão, lemos os registradores
ADC_DATA_1
eADC_DATA_2
, combinando-os para formar o valor final do ADC. - Delay: Implementamos um atraso de 10 ms para manter a frequência de amostragem de 100 Hz.
Esse código básico permite que você leia constantemente o valor de um potenciômetro conectado ao canal 1 do ADC, com as leituras acontecendo a cada 10 milissegundos.