cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303C8C6 DMA 2ADC 5Channels

MichelDatema
Associate

hi i am having some difficoulty's where i cant find a solve for:

 

problem 1 ADC1_channel12 feeds me a value back around 4030 while its voltage on the pin is 0.0V

problem 2 ADC2_channel3 is always reading 0

 

i configured all ADC channels to place data in the memory using DMA.

different channels different prioritys and all but no resoult

cheked hardware but same resoult

i am using SWD for debuggin and am running the microconroller for a few seconds. than add a breakpoin and than check the registers assigned to the ADC ADC1Values&ADC1Values

# note i am not using the conversion complete callback becouse i dont really care about the moment when the data is read out

 

honestley i am not very good at this and just started so i let the IOC configurationhandle all of the settings

 

please review my code and settings i hope i forgot something simple but i am in to it for 3 days now and need a solve.

 

here is my configration:

 

MX_GPIO_Init();

MX_DMA_Init();

MX_ADC1_Init();

MX_ADC2_Init();

MX_TIM2_Init();

MX_TIM6_Init();

HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADC1Values, NumADC1channels*AmtOfSamples);

HAL_ADC_Start_DMA(&hadc2, (uint32_t*) ADC2Values, NumADC2channels*AmtOfSamples);

 

static void MX_ADC1_Init(void)

{

 

/* USER CODE BEGIN ADC1_Init 0 */

 

/* USER CODE END ADC1_Init 0 */

 

ADC_MultiModeTypeDef multimode = {0};

ADC_ChannelConfTypeDef sConfig = {0};

 

/* USER CODE BEGIN ADC1_Init 1 */

 

/* USER CODE END ADC1_Init 1 */

 

/** Common config

*/

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

hadc1.Init.Resolution = ADC_RESOLUTION_12B;

hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

hadc1.Init.ContinuousConvMode = ENABLE;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 4;

hadc1.Init.DMAContinuousRequests = ENABLE;

hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

hadc1.Init.LowPowerAutoWait = DISABLE;

hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}

 

/** Configure the ADC multi-mode

*/

multimode.Mode = ADC_MODE_INDEPENDENT;

if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_1;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SingleDiff = ADC_SINGLE_ENDED;

sConfig.SamplingTime = ADC_SAMPLETIME_181CYCLES_5;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_2;

sConfig.Rank = ADC_REGULAR_RANK_2;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_3;

sConfig.Rank = ADC_REGULAR_RANK_3;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_12;

sConfig.Rank = ADC_REGULAR_RANK_4;

sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN ADC1_Init 2 */

 

/* USER CODE END ADC1_Init 2 */

 

}

 

/**

* @brief ADC2 Initialization Function

* @param None

* @retval None

*/

static void MX_ADC2_Init(void)

{

 

/* USER CODE BEGIN ADC2_Init 0 */

 

/* USER CODE END ADC2_Init 0 */

 

ADC_ChannelConfTypeDef sConfig = {0};

 

/* USER CODE BEGIN ADC2_Init 1 */

 

/* USER CODE END ADC2_Init 1 */

 

/** Common config

*/

hadc2.Instance = ADC2;

hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

hadc2.Init.Resolution = ADC_RESOLUTION_12B;

hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;

hadc2.Init.ContinuousConvMode = ENABLE;

hadc2.Init.DiscontinuousConvMode = DISABLE;

hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc2.Init.NbrOfConversion = 1;

hadc2.Init.DMAContinuousRequests = ENABLE;

hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;

hadc2.Init.LowPowerAutoWait = DISABLE;

hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

if (HAL_ADC_Init(&hadc2) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_3;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SingleDiff = ADC_SINGLE_ENDED;

sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;

if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN ADC2_Init 2 */

 

/* USER CODE END ADC2_Init 2 */

 

}

 

 

every 100 ms i call this function:

static void SaveAnalogValues(void) {

 

for (uint16_t a = 0; a < NumADC1channels; a++) {

uint32_t SUM1 = 0;

for (uint16_t b = 0; b < AmtOfSamples; b++) {

SUM1 = SUM1+ADC1Values[b][a];

}

switch (a) {

case 0: varADCpotTimUp = SUM1 / AmtOfSamples; break;

case 1: varADCpotTinDown = SUM1 / AmtOfSamples; break;

case 2: varADCpotDutycycle = SUM1 / AmtOfSamples; break;

case 3: varADCmotorCurrent = SUM1 / AmtOfSamples; break;

}

}

for (uint16_t a = 0; a < NumADC2channels; a++) {

uint32_t SUM2 = 0;

for (uint16_t b = 0; b < AmtOfSamples; b++) {

SUM2 = SUM2+ADC2Values[b][a];

}

switch (a) {

case 0: varADCvoltage = SUM2 / AmtOfSamples; break;

}

}

//varADCvoltage = HAL_ADC_GetValue(&hadc2); // de DMA werkt niet dus moet maar even met POLL methode

 

// refactor adc value to usable time for potmeters for limitswitches

LimitSwitchUpDelayTIME = map(varADCpotTimUp, 0, 4095, 0, LimitswitchPotmeterBandwith);

LimitSwitchDownDelayTIME = map(varADCpotTinDown, 0, 4095, 0, LimitswitchPotmeterBandwith);

MotorStartupSpeed = map(varADCpotDutycycle, 0 , 4095 , 0, 100);

 

InputvoltageVOLTS = map((float)varADCvoltage, 0, 4095, 0, 39.98); // Real Volts

MotorcurrentAMPS = map((float)varADCmotorCurrent, 0, 4095, 0, 6.6); // real AMPS

}

 

where i read all the data from the banks back to the variables that i use in my program.

1 REPLY 1
TDK
Guru

If the other 3 channels are converting correctly, the likely explanation is that the pin isn't hooked up to what you think it is. Everything downstream of the mux is going to the be the same for all channels. Could also be that the pin is not configured in analog mode, but if this is CubeMX generated that seems unlikely.

Initialize the pin as GPIO output and toggle it to verify it's connected to what you think it is.

If you feel a post has answered your question, please click "Accept as Solution".