一、ADC概述
把模拟量转换成数字量的过程称之为AD转换,完成这种转换的电路称之为模数转换器,简称ADC,模拟信号转换成数字信号一般分为2个大步骤,分别是采样 – 转换。 |
模拟信号:模拟信号是指信息参数在给定范围内表现为连续的信号。或在一段连续的时间间隔内,其代表信息的特征量可以在任意瞬间呈现为任意数值的信号。 |
数字信号:数字信号指自变量是离散的、因变量也是离散的信号,这种信号的自变量用整数表示,因变量用有限数字中的一个数字来表示。 |
![]() |
模数转换器:将模拟信号(连续)转换为数字信号(离散); 工作频率:最大14MHz; 转换精度:12位逐次逼近式转换方式; 转换原理:模拟量 = 转换结果[份数] *(参考电压[3.3] / 分辨率[4096]) 采样方式:单次(只工作一个工作周期)、连续(循环工作周期)、扫描(一个周期内转换多个通道)、间断(不连 续扫描); 工作模式:同一时刻只能有一个通道工作;触发注入模式下,注入通道打断规则通道;自动注入模式下,转换完规则通道后自动转换注入通道; 外部触发模式:定时器触发、外部中断触发、软件触发; ADC模块开关控制:断电模式或低功耗模式下,ADC使能为ADC唤醒(需要延时1us),再一次使能ADC则进入工作模式;清除ADC使能,则ADC进入低功耗。 |
二、CubeMX驱动生成
使用CubeMX生成ADC驱动: 修改时钟树ADC分频(最大不超过14MHz): 配置ADC驱动: |
三、使用ADC设备驱动程序
![]() |
确保HAL库hal_conf.h功能模块使能(CubeMX会自动解除注释): #define HAL_ADC_MODULE_ENABLED 添加adc.c硬件驱动到board.c: void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(adcHandle->Instance == ADC1) { /* USER CODE BEGIN ADC1_MspInit 0 */ /* USER CODE END ADC1_MspInit 0 */ /* ADC1 clock enable */ __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /**ADC1 GPIO Configuration PC0 ------> ADC1_IN10 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USER CODE BEGIN ADC1_MspInit 1 */ /* USER CODE END ADC1_MspInit 1 */ } } 修改board.h: #define BSP_USING_ADC1 /*#define BSP_USING_ADC2*/ /*#define BSP_USING_ADC3*/ |
四、示例代码
#include <rtthread.h>
#include <rtdevice.h>
static rt_adc_device_t devXxx;
static uint8_t xxxChannel;
bool xxxInit(char *devName, uint8_t channel)
{
// 查找设备
devXxx = (rt_adc_device_t)rt_device_find(devName);
if (devXxx == RT_NULL) {
rt_kprintf("rt_device_find[%s] failed!\n", devName);
return false;
}
xxxChannel = channel;
return true;
}
float getXxxValue()
{
// 读取采样值
rt_err_t ret = rt_adc_enable(devXxx, xxxChannel);
if (ret != RT_EOK) {
rt_kprintf("adc enable failed!\n");
return 0;
}
uint32_t value = rt_adc_read(devXxx, xxxChannel);
ret = rt_adc_disable(devXxx, xxxChannel);
if (ret != RT_EOK) {
rt_kprintf("adc disable failed!\n");
return 0;
}
return value;
}