cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429 ADC problem

tasabao
Associate II

I am currently using STM32CubeIDE and want to input an external sine wave. The signal has a voltage of 2.6V and a frequency of 10kHz, and I am using DMA + TIM + ADC. The following is the screenshot of my settings.

Currently, I can only capture the peak value of 2.6V, and this is only achievable when the ADC Sampling Time is set to 480 Cycles. With a lower number of cycles, I can only get lower values. Please help me resolve this issue, thank you!

DMA:

tasabao_2-1729413430489.png

 

ADC:

tasabao_1-1729413412132.png

 

TIM:

tasabao_0-1729413380782.png

Clock Configuration:

tasabao_3-1729413475914.png

Below is my code:

///////////////ADC////////////////

int test = 0;

uint32_t lastTick = 0;

uint16_t ADC_Value[4095] = {0};

float ADC_MaxValue = 0;

float ADC_MinValue = 0;

int count = 0;

double ADC_Value_Sum = 0;

int ADC_Value_AVG = 0;

float clock_AVG = 0;

uint16_t max_value = 0;

uint16_t min_value = 0;

char buffer[20];

 

HAL_TIM_Base_Start(&htim2);

/* USER CODE BEGIN WHILE */

while (1)

{

if (uart_received)

{

uart_received = 0;

 

if (uart_command == 'A')

{

check = 1;

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_Value, 4095);

}

else if (uart_command == 'Z')

{

check = 0;

m = 10000;

ADC_Value_Sum = 0;

memset(ADC_Value, 0, sizeof(ADC_Value));

HAL_ADC_Stop_DMA(&hadc1);

count = 0;

high_time_Sum = 0;

count_phase = 0;

zero_remove = 0;

max_value = 0;

min_value = 0;

}

else if (uart_command == 'S')

{

check = 2;

}

}

 

if (adc_conversion_complete)

{

adc_conversion_complete = 0;

 

sprintf(buffer, "Max: %.3f V, Min: %.3f V\r\n", ADC_MaxValue, ADC_MinValue);

HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);

}

 

 

if (check == 1)

{

if (HAL_GetTick() - lastTick >= 50000)

{

m += 10000;

ADC_Value_Sum = 0;

memset(ADC_Value, 0, sizeof(ADC_Value));

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_Value, 4095);

lastTick = HAL_GetTick();

}

ad9850_wr(0x00, m);

}

else if (check == 0)

{

ad9850_wr(0x00, 0);

}

else if (check == 2)

{

ad9850_wr(0x00, m);

}

}

 

 

/* USER CODE END WHILE */

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{

if(TIM2 == htim->Instance){

if(HAL_TIM_ACTIVE_CHANNEL_1 == htim->Channel){

switch(capture_cnt){

case 1:

capture_buf[0] = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);

__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);

capture_cnt++;

break;

case 2:

capture_buf[1] = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);

HAL_TIM_IC_Stop_IT(htim,TIM_CHANNEL_1);

capture_cnt++;

break;

default:

break;

}

}

}

}

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

test = 1;

if (hadc->Instance == ADC1)

{

max_value = ADC_Value[0];

min_value = ADC_Value[0];

for (int i = 0; i < 4095; i++)

{

 

if (ADC_Value[i] > max_value)

{

max_value = ADC_Value[i];

}

 

if (ADC_Value[i] < min_value)

{

min_value = ADC_Value[i];

}

}

ADC_MaxValue = ((float)max_value * 3.3f) / 4095.0f;

ADC_MinValue = ((float)min_value * 3.3f) / 4095.0f;

processFFT();

 

if (m >= 1000000)

{

m = 10000; // Reset frequency to 10 kHz

check = 0;

}

 

HAL_ADC_Stop_DMA(&hadc1);

lastTick = HAL_GetTick();

 

adc_conversion_complete = 1;

}

}

1 REPLY 1

> this is only achievable when the ADC Sampling Time is set to 480 Cycles.  With a lower number of cycles, I can only get lower values.

This usually means, that your input signal has too high impedance. My guess is, that you derive the sine wave using a high-resistance divider. You'll need to use a buffer (an amplifier with amplifiacation 1) before feeding that signal to ADC.

JW