STM32F1与STM32CubeIDE快速入门-ADC轮询方式实现PWM调光器

ADC轮询方式实现PWM调光器

在模拟输入通道上使用 ADC 执行模数转换的最简单的代码方法。 然而,这并不是所有情况下的有效方式,因为它被认为是使用 ADC 的一种阻塞方式。 通过这种方式,我们开始 A/D 转换并等待 ADC 完成转换,以便 CPU 可以继续处理主代码。

在这里插入图片描述

本次实例将实现通过ADC轮询方式采样,并转换成PWM方式输出,从而达到LED调光效果。

1、ADC模式方式配置

创建工程及系统时钟配置请参考前面文章,在这里不再做介绍。

1)、ADC配置

在这里插入图片描述

2)、配置定时器

在这里插入图片描述
3)硬件接线:将一个10K旋转电位计连接到开发板,电位计的输出端连接ADC1通道。

2、代码生成与功能实现

STM32Cube IDE生成的主要代码如下:

1)ADC初始化

main.c文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/\*\*
\* @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 \*/
/\*\* Common config
\*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
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_7;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL\_ADC\_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error\_Handler();
}
/\* USER CODE BEGIN ADC1\_Init 2 \*/

/\* USER CODE END ADC1\_Init 2 \*/

}

stm32f1xx_hal_msp.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/\*\*
\* @brief ADC MSP Initialization
\* This function configures the hardware resources used in this example
\* @param hadc: ADC handle pointer
\* @retval None
\*/
void HAL\_ADC\_MspInit(ADC_HandleTypeDef\* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadc->Instance==ADC1)
{
/\* USER CODE BEGIN ADC1\_MspInit 0 \*/

/\* USER CODE END ADC1\_MspInit 0 \*/
/\* Peripheral clock enable \*/
\_\_HAL\_RCC\_ADC1\_CLK\_ENABLE();

\_\_HAL\_RCC\_GPIOA\_CLK\_ENABLE();
/\*\*ADC1 GPIO Configuration
PA7 ------> ADC1\_IN7
\*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL\_GPIO\_Init(GPIOA, &GPIO_InitStruct);

/\* USER CODE BEGIN ADC1\_MspInit 1 \*/

/\* USER CODE END ADC1\_MspInit 1 \*/
}

}

2)定时器TIM2初始化

main.c文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/\*\*
\* @brief TIM2 Initialization Function
\* @param None
\* @retval None
\*/
static void MX\_TIM2\_Init(void)
{

/\* USER CODE BEGIN TIM2\_Init 0 \*/

/\* USER CODE END TIM2\_Init 0 \*/

TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};

/\* USER CODE BEGIN TIM2\_Init 1 \*/

/\* USER CODE END TIM2\_Init 1 \*/
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL\_TIM\_Base\_Init(&htim2) != HAL_OK)
{
Error\_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL\_TIM\_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error\_Handler();
}
if (HAL\_TIM\_PWM\_Init(&htim2) != HAL_OK)
{
Error\_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL\_TIMEx\_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error\_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL\_TIM\_PWM\_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error\_Handler();
}
/\* USER CODE BEGIN TIM2\_Init 2 \*/

/\* USER CODE END TIM2\_Init 2 \*/
HAL\_TIM\_MspPostInit(&htim2);

}

3)程序入口与功能实现

main.c文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/\*\*
\* @brief The application entry point.
\* @retval int
\*/
int main(void)
{
/\* USER CODE BEGIN 1 \*/
uint16_t AD_RES = 0;
/\* USER CODE END 1 \*/

/\* 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\_ADC1\_Init();
MX\_TIM2\_Init();
/\* USER CODE BEGIN 2 \*/
HAL\_TIM\_PWM\_Start(&htim2, TIM_CHANNEL_1);
// Calibrate The ADC On Power-Up For Better Accuracy
HAL\_ADCEx\_Calibration\_Start(&hadc1);
/\* USER CODE END 2 \*/

/\* Infinite loop \*/
/\* USER CODE BEGIN WHILE \*/
while (1) {
/\* USER CODE END WHILE \*/

/\* USER CODE BEGIN 3 \*/
// Start ADC Conversion
HAL\_ADC\_Start(&hadc1);
// Poll ADC1 Perihperal & TimeOut = 1mSec
HAL\_ADC\_PollForConversion(&hadc1, 1);
// Read The ADC Conversion Result & Map It To PWM DutyCycle
AD_RES = HAL\_ADC\_GetValue(&hadc1);
TIM2->CCR1 = (AD_RES << 4);
HAL\_Delay(1);
}
/\* USER CODE END 3 \*/
}

文章来源: https://iotsmart.blog.csdn.net/article/details/123465048