Hello,
I’m facing an issue with an STM32F103C8T6 microcontroller in my project, where I aim to read 4 NTC sensors. I'm seeking your help regarding a problem I haven't encountered before. Below, you can see the circuit schematic. This schematic was reverse-engineered from an existing NTC reading device available in the market. While the original system used an ATmega168P, my system is based on an STM32 microcontroller.
Anyway, I built the circuit on a manufactured PCB. When no NTC is connected to the circuit, I expect the adc_average
values to be around 4096, but instead, I’m observing values around 2300. Similarly, connecting an NTC sensor to one pin affects the ADC readings of the other pins, causing their values to change as well.
I’ve spent the entire weekend troubleshooting this perplexing issue. Below, I’m sharing the code for reference. Here, I’m running the STM32 ADC in poll mode and attempting to filter out noise by averaging the readings. While I’m able to achieve precise measurements with a single ADC channel, I’m struggling significantly when reading multiple channels, encountering various unexpected problems.
Code:
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 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
// sConfig.Channel = ADC_CHANNEL_4;
// sConfig.Rank = ADC_REGULAR_RANK_1;
// sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }
// /** Configure Regular Channel
// */
// sConfig.Channel = ADC_CHANNEL_5;
// sConfig.Rank = ADC_REGULAR_RANK_2;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }
// /** Configure Regular Channel
// */
// sConfig.Channel = ADC_CHANNEL_6;
// sConfig.Rank = ADC_REGULAR_RANK_3;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }
// /** Configure Regular Channel
// */
// sConfig.Channel = ADC_CHANNEL_7;
// 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 */
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_Delay(1000);
/* 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_ADC1_Init();
MX_RTC_Init();
MX_SPI2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
FlashIndex = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1); // SRAM memory kaydedilen NOR Flash index degeri
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_UARTEx_ReceiveToIdle_IT(&huart2, RxData, 256);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Run_LED();
UpdateTemperature();
}
/* USER CODE END 3 */
}
void UpdateTemperature(void) {
for(int i = 0; i < 4; i++) // 4 ADC kanalini sirayla okumak için döngü
{
// Kanali seç
switch(i) {
case 0:
ADC_CHANNEL4(); // 0. kanal
break;
case 1:
ADC_CHANNEL5(); // 1. kanal
break;
case 2:
ADC_CHANNEL6(); // 2. kanal
break;
case 3:
ADC_CHANNEL7(); // 3. kanal
break;
}
adc_sum[i] = 0; // Kanal basina toplami sifirla
for(int j = 0; j < num_samples; j++) // Her kanal için 20 ölçüm al
{
HAL_ADC_Start(&hadc1); // ADC'yi baslat
HAL_ADC_PollForConversion(&hadc1, 1); // Poll ADC'yi, timeout = 1ms
AD_RES = HAL_ADC_GetValue(&hadc1); // ADC sonucunu al
adc_sum[i] += AD_RES; // Her ölçümü toplamaya ekle
HAL_ADC_Stop(&hadc1); // ADC'yi durdur
//HAL_Delay(10); // Küçük bir gecikme ekle
}
adc_average[i] = adc_sum[i] / num_samples; // 20 ölçümün ortalamasini al
}
void ADC_CHANNEL4(void){
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void ADC_CHANNEL5(void){
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void ADC_CHANNEL6(void){
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void ADC_CHANNEL7(void){
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
Thank you.