Closed wdfk-prog closed 1 year ago
Hi @wdfk-prog,
In order to read Temperature or Vrefint using ADC, you need to enable each channel in the ADC_CCR register.
ADC_CCR_TSEN to enable the VSENSE channel for the temperature sensor. ADC_CCR_VREFEN to enable the Vrefint channel
When you call HAL_ADC_ConfigChannel with ADC_CHANNEL_TEMPSENSOR or ADC_CHANNEL_VREFINT the HAL driver automatically enable the corresponding channel. The temperature sensor and vrefint are not enabled by the HAL driver when Channel 18/19 are configured.
In your test, did you make sure ADC_CCR_TSEN and ADC_CCR_VREFEN were enabled ?
With regards,
Hi @ARIOSTM
I looked at the register values in KEIL5 and found some issues
After the HAL_ADCEx_Calibration_Start function is enabled, all capabilities are set to one
if (HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK) { Error_Handler(); }
- Below is a screenshot of register values for ADC3 in KEIL5
But I only configured the temperature and internal reference voltage channels
The register value does not change when debug stops at the following location
None of the flags are in place, but I still have the reference voltage and temperature values I read
The configuration code I use is as follows
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;
/ ADC3 init function / void MX_ADC3_Init(void) {
/ USER CODE BEGIN ADC3_Init 0 /
/ USER CODE END ADC3_Init 0 /
ADC_ChannelConfTypeDef sConfig = {0};
/ USER CODE BEGIN ADC3_Init 1 /
/ USER CODE END ADC3_Init 1 /
/* Common config / hadc3.Instance = ADC3; hadc3.Init.Resolution = ADC_RESOLUTION_16B; hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc3.Init.LowPowerAutoWait = DISABLE; hadc3.Init.ContinuousConvMode = ENABLE; hadc3.Init.NbrOfConversion = 2; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc3.Init.OversamplingMode = ENABLE; hadc3.Init.Oversampling.Ratio = 1024; hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_10; hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER; hadc3.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE; if (HAL_ADC_Init(&hadc3) != HAL_OK) { Error_Handler(); }
/* Configure Regular Channel / sConfig.Channel = ADC_CHANNEL_VREFINT; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; sConfig.OffsetSignedSaturation = DISABLE; if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { Error_Handler(); }
/* Configure Regular Channel / sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; sConfig.Rank = ADC_REGULAR_RANK_2; if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN ADC3_Init 2 /
/ USER CODE END ADC3_Init 2 /
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) {
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; if(adcHandle->Instance==ADC3) { / USER CODE BEGIN ADC3_MspInit 0 /
/ USER CODE END ADC3_MspInit 0 /
/* Initializes the peripherals clock / PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); }
/* ADC3 clock enable */
__HAL_RCC_ADC3_CLK_ENABLE();
/* ADC3 DMA Init */
/* ADC3 Init */
hdma_adc3.Instance = DMA1_Stream3;
hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc3.Init.Mode = DMA_CIRCULAR;
hdma_adc3.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc3) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3);
/ USER CODE BEGIN ADC3_MspInit 1 /
/ USER CODE END ADC3_MspInit 1 / } }
static int adc_init(void) { / DMA controller clock enable / __HAL_RCC_DMA1_CLK_ENABLE(); / DMA1_Stream3_IRQn interrupt configuration / HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 15, 0); HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn); MX_ADC3_Init();
if (HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler();
}
adc3_data = (rt_uint16_t *)rt_malloc_align(ADC3_BUFFER_LEN,16);
if (HAL_ADC_Start_DMA(&hadc3, (uint32_t *)adc3_data, ADC3_BUFFER_LEN) != HAL_OK)
{
Error_Handler();
}
return RT_EOK;
}
typedef enum { VREFINT_CHANNEL = 0x00, TEMP_CHANNEL, }ADC1_CHANNEL;
rt_uint16_t* adc3_data = RT_NULL;
static int adc_vol_sample(void) { rt_uint16_t vref_mv,temp_mv; rt_uint32_t vref_value,temp_value; rt_uint32_t sum = 0;
for(int i = VREFINT_CHANNEL; i < ADC3_BUFFER_LEN; i += ADC3_CHANNEL_NUM)
{
sum += adc3_data[i];
}
vref_value = sum / ADC3_BUFFER_SIZE;
sum = 0;
for(int i = TEMP_CHANNEL; i < ADC3_BUFFER_LEN; i += ADC3_CHANNEL_NUM)
{
sum += adc3_data[i];
}
temp_value = sum / ADC3_BUFFER_SIZE;
rt_kprintf("Vref is %u.\n", vref_value);
rt_kprintf("Temp is %u.\n" , temp_value);
// Calculating Vref voltage
vref_mv = __HAL_ADC_CALC_VREFANALOG_VOLTAGE(vref_value, ADC_RESOLUTION_16B);
rt_kprintf("Vref voltage is %u mV.\n", vref_mv);
// Calculate Temperature
rt_kprintf("%d are Temperature in Degree C.\n",
__HAL_ADC_CALC_TEMPERATURE(vref_mv, temp_value, ADC_RESOLUTION_16B));
return RT_EOK;
}
## In addition, I manually modified the configuration code to use the 18/19 channel
![image](https://user-images.githubusercontent.com/66928464/208803275-e263eafd-a2c5-4eae-b164-f68bfccf7641.png)
![image](https://user-images.githubusercontent.com/66928464/208803298-2d3c6dd1-9c8f-4638-89ef-b84c36e07222.png)
- Calibration enabled, all flags at position one
![image](https://user-images.githubusercontent.com/66928464/208803329-22e756f4-0a02-4bbd-b5dc-86875b19a648.png)
- The results of uncalibration are as follows
![image](https://user-images.githubusercontent.com/66928464/208803515-b8ee66ab-6c24-4e2d-bdca-25a2045d5d2d.png)
![image](https://user-images.githubusercontent.com/66928464/208803526-4feed21f-12c3-4760-9aff-f29c23fafb77.png)
## Finally, a graph is attached comparing the operating temperature and reference voltage to the register values using the 18/19 channel. You can see that the register values are the same
- temperature and reference voltage
![image](https://user-images.githubusercontent.com/66928464/208804605-94694cf9-93ee-4faf-8d08-36ffea3d8b48.png)
- 18/19 channel
![image](https://user-images.githubusercontent.com/66928464/208805855-36018290-607c-4576-82e7-490217e0c3d2.png)
Hello @wdfk-prog ,
Would you please share the project you have used to reproduce the problem. Could you give us more information about the context of execution
BeST Regards,
Rania.
Hello @wdfk-prog
Please allow me to close this thread as no activity. You may reopen it at any time if you have any details to share with us in order to help you to solve the issue. Thank you for your comprehension.
With regards
Caution
Describe the set-up
Additional context
issue