ST意法半导体
直播中

张秀兰

8年用户 1341经验值
私信 关注
[问答]

stm32439VITx板的ADC问题求解

大家好。
我有一个自定义的 STM32439VITx 板,运行频率为 60MHz,HSI 时钟:
  • void SystemClock_Config(void)
  • {
  • RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  • RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  • /** Configure the main internal regulator output voltage
  • */
  • __HAL_RCC_PWR_CLK_ENABLE();
  • __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
  • /** Initializes the RCC Oscillators according to the specified parameters
  • * in the RCC_OscInitTypeDef structure.
  • */
  • RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  • RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  • RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  • RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  • RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  • RCC_OscInitStruct.PLL.PLLM = 8;
  • RCC_OscInitStruct.PLL.PLLN = 64;
  • RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  • RCC_OscInitStruct.PLL.PLLQ = 4;
  • if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  • {
  •   Error_Handler();
  • }
  • /** Initializes the CPU, AHB and APB buses clocks
  • */
  • RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  • |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  • RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  • RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  • RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  • RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  • if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  • {
  •   Error_Handler();
  • }
  • }

信号由放大器驱动到 1K/1M 电阻分压器,馈入 ADC1 通道 10,我需要每十秒左右读取一次:
  • 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_DIV6;
  •   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  •   hadc1.Init.ScanConvMode = DISABLE;
  •   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 = 1;
  •   hadc1.Init.DMAContinuousRequests = DISABLE;
  •   hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  •   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  •   */
  •   sConfig.Channel = ADC_CHANNEL_10;
  •   sConfig.Rank = 1;
  •   sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  •   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   /* USER CODE BEGIN ADC1_Init 2 */
  •   /* USER CODE END ADC1_Init 2 */
  • }
我已经尝试了几乎所有我能想到的方法来让它工作,并且我已经将代码简化为一个简单的测试用例:
  • static void test_adc() {
  •         HAL_Init();
  •         SystemClock_Config();
  •         MX_GPIO_Init();
  •         MX_ADC1_Init();
  •         HAL_ADC_Start(&hadc1);
  •         while(true) {
  •                 HAL_Delay(1000);
  •                 if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) {
  •                         static const float Vref = 3.3f;
  •                         static const float R14 = 1000.0f;
  •                         static const float R15 = 1000000.0f;
  •                         const float adc = HAL_ADC_GetValue(&hadc1);
  •                         const float vadc = adc * Vref / 4096.0f;
  •                         const float vin = vadc * (R14 + R15) / R15;
  •                         __NOP();
  •                 }
  •         }
  •         HAL_ADC_Stop(&hadc1);
  • }
输入引脚上的电压表显示 1200mV,ADC 的读数在 890 到 910 之间,调整后的读数约为 720mV。
就像我说的,我已经尝试了各种方法来获得合理的阅读,也许我缺少一些简单的东西。我的代码有什么明显的错误吗?






回帖(1)

王军

2022-12-15 10:50:35
这不是软件问题,而主要是硬件问题。使用您的测量设置,测量不能产生任何有意义的值,至少不能产生预期的值。对于这个 ADC,您也必须考虑输入参数。
让我们总结一下:


  • 你用放大器给分压器供电
  • 分压器的分压系数为 1/1000 = 0.001,GND 电阻为 1Mohms
  • 根据数据表,ADC 的最大(!)外部输入阻抗为 50kohms(表 74,第 159 页)
  • 实际输入阻抗可以用等式 1 估算(表 74 下方,第 160 页)

这个星座的分压器会发生什么变化?
正确,电压崩溃。
解决方法:使用放大器将待测电压直接加到输入端,只要低于最大值即可,即去掉R15,短接R14。
通常,ADC 前面的运算放大器正是用于此目的,也用于抗混叠。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分