// 1. Declarar a variável como 'volatile' para que o compilador
// não a ignore, pois ela muda "sozinha" via hardware
volatile uint16_t sensorValueDMA;
void setup() {
Serial.begin(9600);
// Configuração padrão do pino como analógico
pinMode(PA0, INPUT_ANALOG);
// --- CONFIGURAÇÃO DE BAIXO NÍVEL (REGISTRADORES) ---
// Habilita o clock para o DMA1 [cite: 85]
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// Configura o Canal 1 do DMA (conectado ao ADC1 no STM32F103)
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; // Endereço de ORIGEM (ADC Data Register)
DMA1_Channel1->CMAR = (uint32_t)&sensorValueDMA; // Endereço de DESTINO (Variável na RAM)
DMA1_Channel1->CNDTR = 1; // Quantidade de dados a transferir
// Configura o canal: modo circular, 16 bits, habilitado
DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_EN;
// Habilita o DMA dentro do periférico ADC [cite: 489, 523]
ADC1->CR2 |= ADC_CR2_DMA;
// Inicia a conversão contínua (Software Trigger para teste inicial)
ADC1->CR2 |= ADC_CR2_ADON;
ADC1->CR2 |= ADC_CR2_CONT;
ADC1->CR2 |= ADC_CR2_SWSTART;
}
void loop() {
// Meça o tempo apenas para provar que a leitura é instantânea
long ti = micros();
// Agora você não usa analogRead(). O valor já está na variável!
int valorAtual = sensorValueDMA;
long tf = micros() - ti;
float tensao = (float(valorAtual) / 4095.0) * 3.3;
Serial.print("Tempo de CPU: ");
Serial.print(tf);
Serial.print("us | Valor ADC: ");
Serial.println(tensao);
delay(1000);
}