【正点原子STM32连载】 第三十五章 单通道ADC采集实验 摘自【正点原子】APM32F407最小系统板使用指南

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html##

第三十五章 单通道ADC采集实验

本章介绍使用APM32F407模数转换器(ADC)进行带通道的电压采集。通过本章的学习,读者将学习到单通道ADC的使用。
本章分为如下几个小节:
35.1 硬件设计
35.2 程序设计
35.3 下载验证

35.1 硬件设计
35.1.1 例程功能

  1. ADC1采集通道1(PA1)上的电压,并在LCD上显示ADC转换后电压的数字量和换算后的模拟量
  2. LED0闪烁,指示程序正在运行
    35.1.2 硬件资源
  3. LED
    LED0 - PF9
  4. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
  5. ADC1
    通道1 - PA1
    35.1.3 原理图
    本章实验使用的ADC1为APM32F407的片上资源,因此没有对应的连接原理图。
    35.2 程序设计
    35.2.1 Geehy标准库的ADC驱动
    本章实验将使用ADC1的通道1(PA1引脚)采集外部输入电压的模拟量,并将其转换为数字量,其具体的步骤如下:
    ①:配置ADC通用控制寄存器
    ②:配置ADC
    ③:使能ADC
    ④:配置ADC规则通道
    ⑤:启动转换规则通道
    ⑥:等待规则通道转换结束
    ⑦:读取规则通道的转换结果
    在Geehy标准库中对应的驱动函数如下:
    ①:配置ADC通用控制寄存器
    该函数用于配置ADC通用控制寄存器,其函数原型如下所示:
    void ADC_CommonConfig(ADC_CommonConfig_T* adcCommonConfig);
    该函数的形参描述,如下表所示:
    形参 描述
    adcCommonConfig 指向ADC通用控制寄存器配置结构体的指针
    需自行定义,并根据ADC通用控制寄存器的配置参数填充结构体中的成员变量
    表35.2.1.1 函数ADC_CommonConfig()形参描述
    该函数的返回值描述,如下表所示:
    返回值 描述
    无 无
    表35.2.1.2 函数ADC_CommonConfig()返回值描述
    该函数使用了ADC_CommonConfig_T类型的结构体变量传入ADC通用控制寄存器的配置参数,该结构体的定义如下所示:
typedef enum
{
    /* 所有ADC都独立 */
    ADC_MODE_INDEPENDENT					= (uint8_t)0x00,	/* 独立模式 */
    
    /* ADC1和ADC2一起工作,ADC3独立 */
    /* 规则同时+注入同时组合模式 */
    ADC_MODE_DUAL_REGSIMULT_INJECSIMULT		= (uint8_t)0x01,
    /* 规则同时+交替触发组合模式 */
    ADC_MODE_DUAL_REGSIMULT_ALTERTRIG		= (uint8_t)0x02,
    ADC_MODE_DUAL_INJECSIMULT				= (uint8_t)0x05,	/* 仅注入同时模式 */
    ADC_MODE_DUAL_REGSIMULT					= (uint8_t)0x06,	/* 仅规则同时模式 */
    ADC_MODE_DUAL_INTERL					= (uint8_t)0x07,	/* 仅交替模式 */
    ADC_MODE_DUAL_ALTERTRIG					= (uint8_t)0x09,	/* 仅交替触发模式 */
    
    /* ADC1、ADC2和ADC3一起工作 */
    /* 规则同时+注入同时组合模式 */
    ADC_MODE_TRIPLE_REGSIMULT_INJECSIMULT	= (uint8_t)0x11,
    /* 规则同时+交替触发组合模式 */
    ADC_MODE_TRIPLE_REGSIMULT_ALTERTRIG		= (uint8_t)0x12,
    ADC_MODE_TRIPLE_INJECSIMULT				= (uint8_t)0x15,	/* 仅注入同时模式 */
    ADC_MODE_TRIPLE_REGSIMULT				= (uint8_t)0x16,	/* 仅规则同时模式 */
    ADC_MODE_TRIPLE_INTERL					= (uint8_t)0x17,	/* 仅交替模式 */
    ADC_MODE_TRIPLE_ALTERTRIG				= (uint8_t)0x19		/* 仅交替触发模式 */
} ADC_MODE_T;

typedef enum
{
    ADC_PRESCALER_DIV2,			/*PCLK2 2分频 */
    ADC_PRESCALER_DIV4,			/*PCLK2 4分频 */
    ADC_PRESCALER_DIV6,			/*PCLK2 6分频 */
    ADC_PRESCALER_DIV8			/*PCLK2 8分频 */
} ADC_PRESCALER_T;

typedef enum
{
    ADC_ACCESS_MODE_DISABLED,	/* 禁止DMA模式 */
    ADC_ACCESS_MODE_1,			/* 使能DMA模式1 */
    ADC_ACCESS_MODE_2,			/* 使能DMA模式2 */
    ADC_ACCESS_MODE_3			/* 使能DMA模式3 */
} ADC_ACCESS_MODE_T;

typedef enum
{
    ADC_TWO_SAMPLING_5CYCLES,	/* 5个Tadcclk */
    ADC_TWO_SAMPLING_6CYCLES,	/* 6个Tadcclk */
    ADC_TWO_SAMPLING_7CYCLES,	/* 7个Tadcclk */
    ADC_TWO_SAMPLING_8CYCLES,	/* 8个Tadcclk */
    ADC_TWO_SAMPLING_9CYCLES,	/* 9个Tadcclk */
    ADC_TWO_SAMPLING_10CYCLES,	/* 10个Tadcclk */
    ADC_TWO_SAMPLING_11CYCLES,	/* 11个Tadcclk */
    ADC_TWO_SAMPLING_12CYCLES,	/* 12个Tadcclk */
    ADC_TWO_SAMPLING_13CYCLES,	/* 13个Tadcclk */
    ADC_TWO_SAMPLING_14CYCLES,	/* 14个Tadcclk */
    ADC_TWO_SAMPLING_15CYCLES,	/* 15个Tadcclk */
    ADC_TWO_SAMPLING_16CYCLES,	/* 16个Tadcclk */
    ADC_TWO_SAMPLING_17CYCLES,	/* 17个Tadcclk */
    ADC_TWO_SAMPLING_18CYCLES,	/* 18个Tadcclk */
    ADC_TWO_SAMPLING_19CYCLES,	/* 19个Tadcclk */
    ADC_TWO_SAMPLING_20CYCLES	/* 20个Tadcclk */
} ADC_TWO_SAMPLING_T;

typedef struct
{
    ADC_MODE_T			mode;			/* ADC模式 */
    ADC_PRESCALER_T		prescaler;		/* ADC预分频器 */
    ADC_ACCESS_MODE_T	accessMode;		/* DMA模式 */
    ADC_TWO_SAMPLING_T	twoSampling;	/* 2个采样阶段之间的延迟 */
} ADC_CommonConfig_T;
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    ADC_CommonConfig_T adc_comm_init_struct;
    
    /* 配置ADC通用控制寄存器 */
    adc_comm_init_struct.mode			= ADC_MODE_INDEPENDENT;
    adc_comm_init_struct.prescaler		= ADC_PRESCALER_DIV4;
    adc_comm_init_struct.accessMode		= ADC_ACCESS_MODE_DISABLED;
    adc_comm_init_struct.twoSampling	= ADC_TWO_SAMPLING_5CYCLES;
    ADC_CommonConfig(&adc_comm_init_struct);
}

②:配置ADC
该函数用于配置ADC的各项参数,其函数原型如下所示:
void ADC_Config(ADC_T* adc, ADC_Config_T* adcConfig);
该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
例如:ADC1、ADC2等(在apm32f4xx.h文件中有定义)
adcConfig 指向ADC配置结构体的指针
需自行定义,并根据ADC的配置参数填充结构体中的成员变量
表35.2.1.3 函数ADC_Config()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表35.2.1.4 函数ADC_Config()返回值描述
该函数使用ADC_Config_T类型的结构体变量传入ADC外设的配置参数,该结构体的定义如下所示:

typedef enum
{
    ADC_RESOLUTION_12BIT,				/* 12位 */
    ADC_RESOLUTION_10BIT,				/* 10位 */
    ADC_RESOLUTION_8BIT,				/* 8位 */
    ADC_RESOLUTION_6BIT					/* 6位 */
} ADC_RESOLUTION_T;

typedef enum
{
    ADC_EXT_TRIG_EDGE_NONE,				/* 禁止触发检测 */
    ADC_EXT_TRIG_EDGE_RISING,			/* 上升沿上的触发检测 */
    ADC_EXT_TRIG_EDGE_FALLING,			/* 下降沿上的触发检测 */
    ADC_EXT_TRIG_EDGE_RISING_FALLING,	/* 上升沿和下降沿上的触发检测 */
} ADC_EXT_TRIG_EDGE_T;

typedef enum
{
    ADC_EXT_TRIG_CONV_TMR1_CC1,			/* 定时器1的CC1事件 */
    ADC_EXT_TRIG_CONV_TMR1_CC2,			/* 定时器1的CC2事件 */
    ADC_EXT_TRIG_CONV_TMR1_CC3,			/* 定时器1的CC3事件 */
    ADC_EXT_TRIG_CONV_TMR2_CC2,			/* 定时器2的CC2事件 */
    ADC_EXT_TRIG_CONV_TMR2_CC3,			/* 定时器2的CC3事件 */
    ADC_EXT_TRIG_CONV_TMR2_CC4,			/* 定时器2的CC4事件 */
    ADC_EXT_TRIG_CONV_TMR2_TRGO,		/* 定时器2的TRGO事件 */
    ADC_EXT_TRIG_CONV_TMR3_CC1,			/* 定时器3的CC1事件 */
    ADC_EXT_TRIG_CONV_TMR3_TRGO,		/* 定时器3的TRGO事件 */
    ADC_EXT_TRIG_CONV_TMR4_CC4,			/* 定时器4的CC4事件 */
    ADC_EXT_TRIG_CONV_TMR5_CC1,			/* 定时器5的CC1事件 */
    ADC_EXT_TRIG_CONV_TMR5_CC2,			/* 定时器5的CC2事件 */
    ADC_EXT_TRIG_CONV_TMR5_CC3,			/* 定时器5的CC3事件 */
    ADC_EXT_TRIG_CONV_TMR8_CC1,			/* 定时器8的CC1事件 */
    ADC_EXT_TRIG_CONV_TMR8_TRGO,		/* 定时器8的TRGO事件 */
    ADC_EXT_TRIG_CONV_EINT_11			/* EINT线11 */
} ADC_EXT_TRIG_CONV_T;

typedef enum
{
    ADC_DATA_ALIGN_RIGHT,				/* 右对齐 */
    ADC_DATA_ALIGN_LEFT					/* 左对齐 */
} ADC_DATA_ALIGN_T;

typedef struct
{
    ADC_RESOLUTION_T		resolution;			/* 分辨率 */
    uint8_t				scanConvMode;		/* 扫描模式 */
    uint8_t				continuousConvMode;	/* 连续转换模式 */
    ADC_EXT_TRIG_EDGE_T	extTrigEdge;		/* 规则通道的外部触发 */
    ADC_EXT_TRIG_CONV_T	extTrigConv;		/* 启动规则组转换的外部事件 */
    ADC_DATA_ALIGN_T		dataAlign;			/* 数据对齐方式 */
    uint8_t				nbrOfChannel;		/* 规则通道序列长度 */
} ADC_Config_T;
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    ADC_Config_T adc_init_struct;
    
    /* 配置ADC1 */
    adc_init_struct.resolution			= ADC_RESOLUTION_12BIT;
    adc_init_struct.scanConvMode		= DISABLE;
    adc_init_struct.continuousConvMode	= DISABLE;
    adc_init_struct.extTrigEdge			= ADC_EXT_TRIG_EDGE_NONE;
    adc_init_struct.dataAlign			= ADC_DATA_ALIGN_RIGHT;
    adc_init_struct.nbrOfChannel		= 1;
    ADC_Config(ADC1, &adc_init_struct);
}

③:使能ADC
该函数用于使能ADC,其函数原型如下所示:
void ADC_Enable(ADC_T* adc);
该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
例如:ADC1、ADC2等(在apm32f4xx.h文件中有定义)
表35.2.1.5 函数ADC_Enable()形参描述
该函数的返回值描述如下表所示
返回值 描述
无 无
表35.2.1.6 函数ADC_Enable()返回值描述
该函数的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    /* 使能ADC1 */
    ADC_Enable(ADC1);
}

④:配置ADC规则通道
该函数用于配置ADC规则通道,其函数原型如下所示:

void ADC_ConfigRegularChannel(	ADC_T* adc,
    								uint8_t channel,
    								uint8_t rank,
    								uint8_t sampleTime);

该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
例如:ADC1、ADC2等(在apm32f4xx.h文件中有定义)
channel ADC通道
例如:ADC_CHANNEL_0、ADC_CHANNEL_1等(在apm32f4xx_adc.h文件中有定义)
rank 转换顺序
sampleTime ADC通道的采样周期
例如:ADC_SAMPLETIME_3CYCLES
ADC_SAMPLETIME_15CYCLES等(在apm32f4xx_adc.h文件中有定义)
表35.2.1.7 函数ADC_ConfigRegularChannel()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表35.2.1.8 函数ADC_ConfigRegularChannel()返回值描述
该函数的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    /* 使能ADC1通道1的规则通道 */
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_1, 1, ADC_SAMPLETIME_480CYCLES);
}

⑤:启动转换规则通道
该函数用于启动转换规则通道,其函数原型如下所示:
void ADC_SoftwareStartConv(ADC_T* adc);
该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
例如:ADC1、ADC2等(在apm32f4xx.h文件中有定义)
表35.2.1.9 函数ADC_SoftwareStartConv()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表35.2.1.10 函数ADC_SoftwareStartConv()返回值描述
该函数的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    /* 使能ADC1转换规则通道 */
    ADC_SoftwareStartConv(ADC1);
}

⑥:读取ADC状态标志
该函数用于读取ADC的状态标志,其函数原型如下所示:
uint8_t ADC_ReadStatusFlag(ADC_T* adc, ADC_FLAG_T flag);
该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
例如:ADC1、ADC2等(在apm32f4xx.h文件中有定义)
flag 指定的ADC状态标志
例如:ADC_FLAG_AWD、ADC_FLAG_EOC等(在apm32f4xx_adc.h文件中有定义)
表35.2.1.11 函数ADC_ReadStatusFlag()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
SET 事件标志发生
RESET 事件标志为发生
表35.2.1.12 函数ADC_ReadStatusFlag()返回值描述
该函数的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    uint8_t flag;
    
    /* 读取ADC1的转换结束标志 */
    flag = ADC_ReadStatusFlag(ADC1, ADC_FLAG_EOC)
    if (flag == SET)
    {
    		/* Do something. */
    }
    else
    {
    		/* Do something. */
    }
}

⑦:读取规则通道转换结果
该函数用于读取规则通道的转换结果,其函数原型如下所示:
uint16_t ADC_ReadConversionValue(ADC_T* adc);
该函数的形参描述,如下表所示:
形参 描述
adc 指向ADC外设结构体的指针
表35.2.1.13 函数ADC_ReadConversionValue()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
uint16_t类型数据 转换结果
表35.2.1.14 函数ADC_ReadConversionValue()返回值描述
该函数的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_adc.h"

void example_fun(void)
{
    uint16_t data;
    
    /* 读取规则通道转换结果 */
    data = ADC_ReadConversionValue(ADC1);
    
    /* Do something. */
}

35.2.2 ADC驱动
本章实验的ADC驱动主要负责向应用层提供ADC的初始化和获取ADC转换结果的函数。本章实验中,ADC的驱动代码包括adc.c和adc.h两个文件。
ADC驱动中,对ADC、GPIO的相关宏定义,如下所示:

#define ADC_ADCX				ADC1
#define ADC_ADCX_CHY			ADC_CHANNEL_1
#define ADC_ADCX_CHY_CLK_ENABLE()							\
    do {														\
    		RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);	\
    } while (0)

#define ADC_ADCX_CHY_GPIO_PORT	GPIOA
#define ADC_ADCX_CHY_GPIO_PIN	GPIO_PIN_1
#define ADC_ADCX_CHY_GPIO_CLK_ENABLE()						\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);	\
    } while (0)
ADC驱动中,ADC的初始化函数,如下所示:
/**
 * @brief	初始化ADC
 * @note	本函数配置ADC为12位分辨率,时钟频率ADCCLK为21MHz,
 * 			ADC转换时间TCONV=采样周期+12个周期
 * 			例如使用最大采样周期480个周期,则ADC的转换时间为492个ADC时钟周期,
 * 			即约为23.43微秒
 * @param	无
 * @retval	无
 */
void adc_init(void)
{
    GPIO_Config_T gpio_init_struct;
    ADC_Config_T adc_init_struct;
    ADC_CommonConfig_T adc_comm_init_struct;
    
    /* 使能时钟 */
    ADC_ADCX_CHY_CLK_ENABLE();							/* 使能ADC时钟 */
    ADC_ADCX_CHY_GPIO_CLK_ENABLE();						/* 使能ADC输入引脚端口时钟 */
    
    /* 配置ADC输入引脚 */
    gpio_init_struct.pin	= ADC_ADCX_CHY_GPIO_PIN;		/* ADC输入引脚 */
    gpio_init_struct.mode	= GPIO_MODE_AN;					/* 模拟模式 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;				/* 禁止上拉/下拉 */
    GPIO_Config(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);/* 配置ADC输入引脚 */
    
    /* 配置ADC通用控制寄存器 */
    adc_comm_init_struct.mode			= ADC_MODE_INDEPENDENT;
    adc_comm_init_struct.prescaler		= ADC_PRESCALER_DIV4;
    adc_comm_init_struct.accessMode		= ADC_ACCESS_MODE_DISABLED;
    adc_comm_init_struct.twoSampling	= ADC_TWO_SAMPLING_5CYCLES;
    ADC_CommonConfig(&adc_comm_init_struct);
    
    /* 配置ADC */
    adc_init_struct.resolution			= ADC_RESOLUTION_12BIT;
    adc_init_struct.scanConvMode		= DISABLE;
    adc_init_struct.continuousConvMode	= DISABLE;
    adc_init_struct.extTrigEdge			= ADC_EXT_TRIG_EDGE_NONE;
    adc_init_struct.dataAlign			= ADC_DATA_ALIGN_RIGHT;
    adc_init_struct.nbrOfChannel		= 1;
    ADC_Config(ADC_ADCX, &adc_init_struct);
    
    ADC_Enable(ADC_ADCX);									/* 使能ADC */
}

从上面的代码中可以看出,ADC的初始化函数中,不仅配置了ADC通用控制寄存器和ADC,该配置了ADC1通道1对应的GPIO引脚,同时也配置了该引脚为模拟模式。
ADC驱动中,获取ADC转换结果的函数,如下所示:

/**
 * @brief	获取ADC转换后的结果
 * @param	ch: ADC通道,范围:ADC_CHANNEL_0~ADC_CHANNEL_18
 * @retval	ADC转换后的结果
 */
uint16_t adc_get_result(uint8_t ch)
{
    /* 配置指定ADC规则通道 */
    ADC_ConfigRegularChannel(ADC_ADCX, ch, 1, ADC_SAMPLETIME_480CYCLES);
    /* 开始转换规则通道 */
    ADC_SoftwareStartConv(ADC_ADCX);
    /* 等待规则通道转换结束 */
    while (ADC_ReadStatusFlag(ADC_ADCX, ADC_FLAG_EOC) == RESET);
    /* 返回规则通道的转换结果 */
    return ADC_ReadConversionValue(ADC_ADCX);
}

/**
 * @brief	获取ADC转换且进行均值滤波后的结果
 * @param	ch   : ADC通道,范围:ADC_CHANNEL_0~ADC_CHANNEL_18
 * @param	times: 参与均值滤波的原始数据的个数
 * @retval	ADC转换且进行均值滤波后的结果
 */
uint16_t adc_get_result_average(uint8_t ch, uint8_t times)
{
    uint32_t temp_val = 0;
    uint8_t t;
    
    for (t=0; t<times; t++)
    {
    		temp_val += adc_get_result(ch);
    		delay_ms(5);
    }
    
    return temp_val / times;
}

以上两个函数都是用于获取ADC转换结果的函数,其中函数adc_get_result()会配置并开启ADC指定通道的规则通道转换,并等待其转换结束后,读取其转换的1次结果;而函数adc_get_result_averagr()则是多次调用啊含糊adc_get_result()获取多次ADC的转换结果,然后进行均值滤波。
35.2.3 实验应用代码
本章实验的应用代码,如下所示:

int main(void)
{
    uint16_t adcdata;
    uint16_t voltage;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    led_init();											/* 初始化LED */
    lcd_init();											/* 初始化LCD */
    adc_init();											/* 初始化ADC */
    
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "ADC TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "ADC1_CH1_VAL:", BLUE);
    lcd_show_string(30, 130, 200, 16, 16, "ADC1_CH1_VOL:0.000V", BLUE);
    
    while (1)
    {
    		/* 获取ADC通道5转换且进行均值滤波后的结果 */
    		adcdata = adc_get_result_average(ADC_ADCX_CHY, 10);
    		/* 显示原始值 */
    		lcd_show_xnum(134, 110, adcdata, 5, 16, 0, BLUE);
    		
    		/* 计算实际电压值(扩大1000倍) */
    		voltage = (adcdata * 3300) / 4095;
    		/* 显示电压值的整数部分 */
    		lcd_show_xnum(134, 130, voltage / 1000, 1, 16, 0, BLUE);
    		/* 显示电压值的小数部分(保留三位小数) */
    		lcd_show_xnum(150, 130, voltage % 1000, 3, 16, 0x80, BLUE);
    		
    		LED0_TOGGLE();
    		delay_ms(100);
    }
}

从上面的代码中可以看出,在进行完包括ADC的所有初始化工作后,便不断地获取ADC1通道1进行5次转换后经过均值滤波后的结果,并将该原始值显示在LCD上,同时还通过该电压的原始值计算出了电压的模拟量,并在LCD上进行显示。
35.3 下载验证
在完成编译和烧录操作后,可以看到LCD上实时刷新显示着ADC1通道1(PA1引脚)采集到电压的数字量和模拟量,此时可以通过杜邦线给PA1引脚接入不同的电压值(注意共地,且输入电压不能超过3.3V,否则可能损坏开发板),可以看到LCD上显示的电压数字量和模拟量也随之改变。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值