cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect ADC values when using HAL setup for DISCO-L475VG-IOT01A

mbe
Visitor

The ADC values remain unchanged even when input signals does change. The C++ code provided below should hopefully clarify the situation, as I am a stuck. Thank you in advance for any help!

 

#include "mbed.h"
#include "stm32l4xx_hal.h"

//Once the buffer below is filled, transfer it over to the PC
#define ADC_BUF_SIZE 1024   // Number of samples in buffer
#define SAMPLE_RATE 50000   // Sampling rate in Hz (e.g., 50 kHz)

AnalogIn adc_pin(A0);  // Use A0 as the analog input pin

// ADC and DMA handles
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
uint16_t adc_buffer[ADC_BUF_SIZE];  // ADC DMA buffer
volatile bool buffer_ready = false; // Flag to indicate data is ready

void ADC_Init() {
    __HAL_RCC_ADC_CLK_ENABLE();       // Enable ADC Clock
    __HAL_RCC_DMA1_CLK_ENABLE();      // Enable DMA Clock
   
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
   
    if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        printf("ADC Init Failed!\n");
    }

    // Configure ADC Channel
    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ADC_CHANNEL_5; // Corresponds to A0
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5;  // Adjust if needed

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
        printf("ADC Channel Config Failed!\n");
    }
}

void DMA_Init() {
    // Configure DMA
    hdma_adc1.Instance = DMA1_Channel1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;

    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) {
        printf("DMA Init Failed!\n");
    }

    __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);

    // Enable Interrupt on DMA Transfer Complete
    HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}

void Start_ADC_DMA() {
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUF_SIZE);
    printf("ADC Sampling Started...\n");
}

extern "C" void DMA1_Channel1_IRQHandler() {
    HAL_DMA_IRQHandler(&hdma_adc1);
}

// Callback function when buffer is full
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
    if (hadc->Instance == ADC1) {
        buffer_ready = true;  // Signal that buffer is full
    }
}

void Process_ADC_Data() {
    if (buffer_ready) {
        buffer_ready = false;
        for (int i = 0; i < ADC_BUF_SIZE; i++) {
            printf("Sample %d: %d\n", i, adc_buffer[i]);
        }
    }
}

int main() {
    printf("Starting ADC DMA Sampling...\n");
   
    ADC_Init(); //
    DMA_Init(); //Direct memory access - giving permission to ADC to write into the memory
    Start_ADC_DMA(); //Start DMA writing
   
    while (1) {
        Process_ADC_Data();
        ThisThread::sleep_for(10ms);  // Avoid CPU overload
    }
}​

 


Code formatting applied - please see How to insert source code for future reference.



0 REPLIES 0