【STM32H5开发板】5. 使用精密可调电位器与LED测试ADC采集转换
[复制链接]
这个试验之前很早就做过,因为操作不慎所拍照片和视频丢失。所以很多原始的资料素材丢失了。这次刚好有时间,再重新做一下这个试验。
1. STM32H5开发板 ADC资源
首先查看 STM32H5开发板 上ADC资源情况 ,
可以看出它有两组独立的ADC转换器,支持12bit 采样,并且采样速度可达到 5Msps
可以使用PC0~5 引脚
2.测试连线图
这里使用一个精密可调电阻器,电阻器固定端阻值是1K,通过多圈旋钮调节中间输出的位置,电阻器接3.3V,可调端则可以得到 0 ~3.3v 电压范围。
这是试验电路图如下,
3.测试代码实现
为了使得ADC 在外部点位器调节时可以看到,这里使用 LED1 的闪烁频率来标识其外部的电压大小,方法是当输入电压值大时,LED闪烁频率变高,ADC测量值低时,LED闪烁频率变低
实现代码如下:
#include "main.h"
#define VDDA_APPLI (3300UL)
/* Definitions of data related to this example */
/* Definition of ADCx analog watchdog window thresholds */
#define ADC_AWD_THRESHOLD_HIGH (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) / 2) /* Value of ADC analog watchdog threshold high */
#define ADC_AWD_THRESHOLD_LOW ( 0UL) /* Value of ADC analog watchdog threshold low */
/* Init variable out of expected ADC conversion data range */
#define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)
#define ADC_AWD_REARM_DELAY_MS (5000UL) /* ADC analog watchdog rearm delay (unit: ms) */
ADC_HandleTypeDef hadc1;
__IO uint16_t uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC group regular conversion data */
*/
__IO uint8_t ubAnalogWatchdog1Status = 0U;
uint32_t led_toggle_period_ms = LED_BLINK_SLOW; /* LED toggle period (unit: ms) */
uint32_t adc_awd_rearm_delay_iterations_count;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ICACHE_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
void ADC_AnalogWatchdog_Rearm(void);
void LED_On(void);
void LED_Off(void);
void LED_Toggle(void);
/* USER CODE END PFP */
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ICACHE_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
/* Initialize LED on board */
BSP_LED_Init(LED1);
/* Perform ADC calibration */
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
{
/* Calibration Error */
Error_Handler();
}
/* Start ADC group regular conversion */
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
Error_Handler();
}
while (1)
{
/* Process analog watchdog out of window event */
if(ubAnalogWatchdog1Status == 1)
{
/* Wait for ADC analog watchdog rearm */
adc_awd_rearm_delay_iterations_count--;
if(adc_awd_rearm_delay_iterations_count == 0)
{
led_toggle_period_ms = LED_BLINK_SLOW;
/* Reset status variable of ADC analog watchdog 1 */
ubAnalogWatchdog1Status = 0;
/* Rearm ADC analog watchdog to make it ready for another trig */
ADC_AnalogWatchdog_Rearm();
}
}
BSP_LED_Toggle(LED1);
HAL_Delay(led_toggle_period_ms);
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIGITAL;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 250;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK3;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
static void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode = {0};
ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.OversamplingMode = DISABLE;
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 Analog WatchDog 1
*/
AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
AnalogWDGConfig.ITMode = ENABLE;
AnalogWDGConfig.HighThreshold = ADC_AWD_THRESHOLD_HIGH;
AnalogWDGConfig.LowThreshold = ADC_AWD_THRESHOLD_LOW;
AnalogWDGConfig.FilteringConfig = ADC_AWD_FILTERING_NONE;
if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_ICACHE_Init(void)
{
if (HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : LED1_Pin */
GPIO_InitStruct.Pin = LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
}
void ADC_AnalogWatchdog_Rearm(void)
{
/* Clear flag ADC analog watchdog 1 */
__HAL_ADC_CLEAR_FLAG(&hadc1, ADC_FLAG_AWD1);
/* Enable ADC analog watchdog 1 interruption */
__HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_AWD1);
}
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD1);
uhADCxConvertedData = HAL_ADC_GetValue(hadc);
/* Update status variable of ADC analog watchdog 1 */
ubAnalogWatchdog1Status = 1;
if (uhADCxConvertedData > ADC_AWD_THRESHOLD_HIGH)
{
led_toggle_period_ms = LED_BLINK_VERY_FAST;
}
else /* (uhADCxConvertedData < ADC_AWD_THRESHOLD_LOW) */
{
led_toggle_period_ms = LED_BLINK_FAST;
}
adc_awd_rearm_delay_iterations_count = (ADC_AWD_REARM_DELAY_MS / led_toggle_period_ms);
}
void Error_Handler(void)
{
while (1)
{
BSP_LED_On(LED1);
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
while (1)
{
}
}
#endif
4.运行效果
经过调试,达到测试目标,最终测试试验如下图:
|