自学内容网 自学内容网

STM32-ADC一步到位学习手册

1.按部就班陈述概念

ADC 是 Analog-to-Digital Converter 的缩写,指的是模拟/数字转换器。它将连续变量的模拟信号转换为离散的数字信号。在 STM32 中,ADC 具有高达 12 位的转换精度,有多达 18 个测量通道,其中 16 个为外部通道,2 个为内部通道。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行,并将扫描结果存储在 16 位的数据寄存器中

2.突如其来的结构讲解

  • 输入电压范围:ADC 所能测量的电压范围,一般为 0 ~ VREF+,其中 VREF+ 可以是 VDDA 或外部参考电压
  • 输入通道:ADC 的信号通过输入通道进入单片机内部,每个通道可以是外部的 GPIO 或内部的 VREFINT、VSS、温度传感器等
  • 转换通道:ADC 的输入通道在转换时又分为规则通道和注入通道,规则通道最多有 16 路,注入通道最多有 4 路,它们可以有不同的转换顺序和触发方式
  • 触发源:ADC 的转换可以由软件或外部触发,外部触发可以是定时器或外部引脚,它们可以有不同的极性和源选择
  • 转换周期:ADC 的转换需要一定的采样时间和转换时间,采样时间可以由 SMP[2:0] 位设置,转换时间由 ADC 时钟决定,总转换时间为 Tconv = 采样时间 + 12.5 个周期
  • 数据寄存器:ADC 的转换结果存储在 16 位的数据寄存器中,可以是左对齐或右对齐,可以是单个或双个,可以是规则或注入
  • 数据传输:ADC 的转换结果可以通过中断或 DMA 的方式传输到内存或其他外设,可以设置不同的传输模式和优先级

3.程序实例

数据转换结束后,可以产生中断,中断分为三种:规则通道转换结束中断,注入转换通道转换结
束中断,模拟看门狗中断,除了产生中断外,还可以产生 DMA 请求。因此代码部分,我仅采用单通道和 AD多通道。

AD单通道

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA的时钟

/*设置ADC时钟*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟6分频,ADCCLK = 
    72MHz / 6 = 12MHz

/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//将PA0引脚初始化为模拟输入

/*规则组通道配置*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//规 
   则组序列1的位置,配置为通道0

/*ADC初始化*/
ADC_InitTypeDef ADC_InitStructure;//定义结构体变量
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//模式,选择独立模式,即单独使用ADC1
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐,选择右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发,使用软件触发,不需要外部触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续转换,失能,每转换一次规则组序列后停止
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描模式,失能,只转换规则组的序列1这一个位置
ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
ADC_Init(ADC1, &ADC_InitStructure);//将结构体变量交给ADC_Init,配置ADC1

/*ADC使能*/
ADC_Cmd(ADC1, ENABLE);//使能ADC1,ADC开始运行

/*ADC校准*/
ADC_ResetCalibration(ADC1);//固定流程,内部有电路会自动执行校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
}

AD带中断

GPIO_InitTypeDef GPIO_InitStructure;

// 打开 ADC IO端口时钟
ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );

// 配置 ADC IO 引脚模式
// 必须为模拟输入
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

// 初始化 ADC IO
GPIO_Init(ADC_PORT, &GPIO_InitStructure);
}

/**
  * @brief  配置ADC工作模式
  * @param  无
  * @retval 无
  */
static void ADCx_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;

// 打开ADC时钟
ADC_APBxClock_FUN ( ADC_CLK, ENABLE );

// ADC 模式配置
// 只使用一个ADC,属于独立模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

// 禁止扫描模式,多通道才要,单通道不需要
ADC_InitStructure.ADC_ScanConvMode = DISABLE ; 

// 连续转换模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

// 不用外部触发转换,软件开启即可
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

// 转换结果右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

// 转换通道1个
ADC_InitStructure.ADC_NbrOfChannel = 1;

// 初始化ADC
ADC_Init(ADCx, &ADC_InitStructure);

// 配置ADC时钟为PCLK2的8分频,即9MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div8); 

// 配置 ADC 通道转换顺序和采样时间
ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, 
                         ADC_SampleTime_55Cycles5);

// ADC 转换结束产生中断,在中断服务程序中读取转换值
ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);

// 开启ADC ,并开始转换
ADC_Cmd(ADCx, ENABLE);

// 初始化ADC 校准寄存器  
ADC_ResetCalibration(ADCx);
// 等待校准寄存器初始化完成
while(ADC_GetResetCalibrationStatus(ADCx));

// ADC开始校准
ADC_StartCalibration(ADCx);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADCx));

// 由于没有采用外部触发,所以使用软件触发ADC转换 
ADC_SoftwareStartConvCmd(ADCx, ENABLE);
}

static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
// 优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

4.结语

ADC 是 stm32 单片机的一个重要的外设,它可以让我们获取外部的模拟信号,并进行一些有用的操作,例如:

  • 测量电压、电流、电阻、电容等电路参数
  • 测量温度、湿度、气压、光照等环境参数
  • 采集声音、图像、视频等多媒体信号
  • 实现模拟信号的滤波、放大、调制、解调等信号处理


原文地址:https://blog.csdn.net/qq_63091423/article/details/136329744

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!