2022-06-07 08:59 AM
In the MX program I set up the rank. to scan 4 values.
TemperatureSensor, VRefint, IN0, IN1.
I Initially saw this in DMA mode, But see it also happens in Discontinuous Mode.
But when read the order is off by 1 position.
It looks like it is reading IN1, TemperatureSensor, VRefint, IN0,
Here is the relevant code.
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_I2C1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_ADC1_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
//ADC_init();
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
{
print_debug_str("Did not calibrate right!");
}
//ADC_DMA_Setup();
HAL_Delay(100); // Make sure print is done.
{
char buf[100];
uint16_t i;
uint16_t refv;
uint16_t temp;
uint16_t adc_data[4];
for (i=0;i<50;i++)
{
adc_data[0] = 0xFFFF;
adc_data[0] = 0xFFFF;
adc_data[0] = 0xFFFF;
adc_data[0] = 0xFFFF;
ADC1->IER = 0; // make sure this is clear
// This should be Temperature
ADC1->ISR |= 2; // Clear EOC Flag
HAL_ADC_Start(&hadc1);
while ((ADC1->ISR & 2) == 0);
adc_data[0] = ADC1->DR;
ADC1->ISR |= 2;
// This should be vref
HAL_ADC_Start(&hadc1);
while ((ADC1->ISR & 2) == 0) ;
adc_data[1] = ADC1->DR;
ADC1->ISR |= 2;
// This should be a voltage -- Not connected expect 0
HAL_ADC_Start(&hadc1);
while ((ADC1->ISR & 2) == 0) ;
adc_data[2] = ADC1->DR;
ADC1->ISR |= 2;
// This should be a current -- Not connected expect 0
HAL_ADC_Start(&hadc1);
while ((ADC1->ISR & 2) == 0) ;
adc_data[3] = ADC1->DR;
ADC1->ISR |= 2;
refv = __HAL_ADC_CALC_VREFANALOG_VOLTAGE(adc_data[2],ADC_RESOLUTION_12B);
temp = __HAL_ADC_CALC_TEMPERATURE(refv,adc_data[1],ADC_RESOLUTION_12B);
sprintf(buf,"%4u ADC Discontinuous readings: %04X %04X %04X %04X TempC: %u, Vref mV: %u\r\n",i, adc_data[0],adc_data[1],adc_data[2],adc_data[3], temp, refv);
print_debug_str(buf);
HAL_Delay(100); // make sure print has time to finish.
} // for
}
while(1); // Stop here while debugging ADC
Looking at the printout it is:
0 ADC Discontinuous readings: 0020 039D 05D7 0001 TempC: 27, Vref mV: 3331
1 ADC Discontinuous readings: 0001 039F 05D6 0002 TempC: 27, Vref mV: 3333
2 ADC Discontinuous readings: 0000 03A3 05E4 0000 TempC: 26, Vref mV: 3302
3 ADC Discontinuous readings: 0001 03A5 05E4 0000 TempC: 26, Vref mV: 3302
4 ADC Discontinuous readings: 0002 03A5 05E3 0001 TempC: 27, Vref mV: 3304
5 ADC Discontinuous readings: 0001 03A5 05E2 0001 TempC: 27, Vref mV: 3306
6 ADC Discontinuous readings: 0001 03A5 05E4 0001 TempC: 26, Vref mV: 3302
7 ADC Discontinuous readings: 0001 03A4 05E2 0001 TempC: 27, Vref mV: 3306
8 ADC Discontinuous readings: 0002 03A6 05E3 0000 TempC: 27, Vref mV: 3304
9 ADC Discontinuous readings: 0002 03A5 05E2 0000 TempC: 27, Vref mV: 3306
10 ADC Discontinuous readings: 0001 03A7 05E4 0001 TempC: 27, Vref mV: 3302
11 ADC Discontinuous readings: 0002 03A5 05E4 0001 TempC: 26, Vref mV: 3302
12 ADC Discontinuous readings: 0002 039F 05D8 0001 TempC: 27, Vref mV: 3328
13 ADC Discontinuous readings: 0002 03A3 05DF 0001 TempC: 27, Vref mV: 3313
14 ADC Discontinuous readings: 0001 03A6 05E3 0001 TempC: 27, Vref mV: 3304
15 ADC Discontinuous readings: 0002 03A6 05E3 0000 TempC: 27, Vref mV: 3304
16 ADC Discontinuous readings: 0001 03A5 05E4 0001 TempC: 26, Vref mV: 3302
17 ADC Discontinuous readings: 0001 03A6 05E3 0000 TempC: 27, Vref mV: 3304
18 ADC Discontinuous readings: 0002 03A5 05E4 0000 TempC: 26, Vref mV: 3302
19 ADC Discontinuous readings: 0002 03A5 05E3 0000 TempC: 27, Vref mV: 3304
20 ADC Discontinuous readings: 0001 03A5 05E3 0001 TempC: 27, Vref mV: 3304
21 ADC Discontinuous readings: 0002 03A6 05E4 0002 TempC: 27, Vref mV: 3302
22 ADC Discontinuous readings: 0002 03A6 05E4 0001 TempC: 27, Vref mV: 3302
23 ADC Discontinuous readings: 0002 03A3 05DF 0000 TempC: 27, Vref mV: 3313
24 ADC Discontinuous readings: 0001 03A5 05E4 0001 TempC: 26, Vref mV: 3302
25 ADC Discontinuous readings: 0002 03A6 05E2 0000 TempC: 27, Vref mV: 3306
26 ADC Discontinuous readings: 0003 03A6 05E3 0001 TempC: 27, Vref mV: 3304
27 ADC Discontinuous readings: 0001 03A5 05E4 0001 TempC: 26, Vref mV: 3302
28 ADC Discontinuous readings: 0002 03A7 05E3 0001 TempC: 27, Vref mV: 3304
29 ADC Discontinuous readings: 0002 03A6 05E2 0001 TempC: 27, Vref mV: 3306
30 ADC Discontinuous readings: 0002 03A7 05E3 0001 TempC: 27, Vref mV: 3304
31 ADC Discontinuous readings: 0002 03A6 05DF 0000 TempC: 28, Vref mV: 3313
32 ADC Discontinuous readings: 0002 03A5 05E2 0002 TempC: 27, Vref mV: 3306
33 ADC Discontinuous readings: 0001 03A5 05E3 0001 TempC: 27, Vref mV: 3304
34 ADC Discontinuous readings: 0002 03A5 05E3 0001 TempC: 27, Vref mV: 3304
35 ADC Discontinuous readings: 0002 03A0 05DA 0000 TempC: 27, Vref mV: 3324
36 ADC Discontinuous readings: 0001 03A6 05E4 0001 TempC: 27, Vref mV: 3302
37 ADC Discontinuous readings: 0001 03A6 05E2 0001 TempC: 27, Vref mV: 3306
38 ADC Discontinuous readings: 0001 03A5 05E5 0002 TempC: 26, Vref mV: 3300
39 ADC Discontinuous readings: 0001 03A7 05E4 0001 TempC: 27, Vref mV: 3302
40 ADC Discontinuous readings: 0002 03A6 05E2 0001 TempC: 27, Vref mV: 3306
41 ADC Discontinuous readings: 0001 03A6 05E4 0000 TempC: 27, Vref mV: 3302
42 ADC Discontinuous readings: 0002 03A7 05E3 0000 TempC: 27, Vref mV: 3304
43 ADC Discontinuous readings: 0001 03A7 05E3 0001 TempC: 27, Vref mV: 3304
44 ADC Discontinuous readings: 0001 03A6 05E3 0000 TempC: 27, Vref mV: 3304
45 ADC Discontinuous readings: 0002 03A6 05E4 0001 TempC: 27, Vref mV: 3302
46 ADC Discontinuous readings: 0002 03A5 05E4 0000 TempC: 26, Vref mV: 3302
47 ADC Discontinuous readings: 0001 03A6 05E5 0000 TempC: 27, Vref mV: 3300
48 ADC Discontinuous readings: 0001 03A1 05DB 0000 TempC: 27, Vref mV: 3322
49 ADC Discontinuous readings: 0001 03A6 05E3 0001 TempC: 27, Vref mV: 3304
For a sanity check I converted the second one (adc_data[1]) to a temperature, and the third one )adc_data[2] to a voltage in mV, and they confirm they are in the wrong place.
The generated code looks right.
/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DiscontinuousConvMode = ENABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_3;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
Why is the order wrong?
How do I fix it?
Thanks, in advance.
2022-06-07 01:04 PM
I did not change anything in the MX program. I did change the the oversample to 8 in the ADC_CFGR2 register and set OVSE to enable it.
Now the order is correct!
In this line are the values as read from the ADC_DR (x8) Temp, Vref, AN0, AN1
ADC Discontinuous 8 readings: 1D37 2F28 0007 0020 FFFF FFFF FFFF FFFF
Here I shifted right 3 positions each of the values. And converted the first to Temperature in C, Temperature in F * 10, and second The Reference Voltage in mV. They all look good and are in the right position.
ADC Discontinuous readings: 03A6 05E5 0000 0004 TempC: 27, TempF*10: 806, Vref mV: 3300
I tried to run the routine 10 times but only got values the first time. I am going to hunt that down next.
2022-06-10 05:11 PM
I also ran into this bug recently. My solution is adding a delay (1ms) after stopping the DMA. It is confusing.
2022-06-13 12:34 AM
Same/similar thing happened to me, i wasnt giving the DMA enough time to fill the ADC readings buffer, i fixed it by speeding up the ADC triggers