3 ADC简介
ADC全称Analog-to-Digital Converter,即模数转换器。
其主要作用是通过PIN测量电压,并将采集到的电压模拟信号转换成数字信号。
3.1 功能描述
3.1.2 ADC模式
校准模式(calibration):用于校准精度。
转换模式(conversion):用于正常工作状态下的模数转换。
根据ADC输入模式完成对应的模式校准,之后在转换模式下进行正常模数转换。
3.1.4 ADC转换模式
单次转换(single):ADC完成单次转换后,ADC将停止,数据将被拉入
FIFO;连续转换(continuous):ADC经过 loop-delay 时间后循环进行转换,直到手动关闭。
3.1.5 ADC通道
ADC共10个channel,即ch0-ch9。
其中ch0-ch8为通用通道。CH9连接用于计算VBAT。
ch0、ch1两个通道默认对输入电压进行1/2分压,且不可配置,对较低电压采样精准度较差。
具体通道的输入连接引脚如下:
| 通道 | 连接引脚 |
|---|---|
| ch0 | GPIO7 |
| ch1 | GPIO8 |
| ch2 | GPIO9 |
| ch3 | GPIO10 |
| ch4 | GPIO30 |
| ch5 | GPIO31 |
| ch6 | GPIO34 |
| ch7 | GPIO35 |
| ch8 | GPIO15 |
| ch9 | VBAT |
以下是关于ADC通道对于开发者的几点使用建议:
1. 在使能通道前请先配置ADC输入模式;
2. 如需切换ADC输入模式,建议调用ADC_DisableAllChannels关闭之前模式下所有已使能通道,重新使能新的通道;
3.2 使用方法
3.2.2 ADC参数配置
ADC参数配置接口的函数声明如下:
void ADC_ConvCfg(SADC_adcCtrlMode ctrlMode,
SADC_channelId ch,
uint8_t enNum,
uint8_t dmaEnNum,
uint32_t loopDelay);涉及参数有:ADC转换模式、采样通道、data触发中断数、data触发DMA搬运数、ADC输入模式和 loop-delay。
具体的参数取值范围请参考ADC头文件里对应的枚举定义或参数说明。
data触发中断数和data触发DMA搬运数决定了搬运ADC数据的方式。前者用触发中断的方式,后者用触发DMA搬运的方式。
注意: data触发中断数和data触发DMA搬运数应该一个为0,一个非0,。如果两值都非0则默认选择触发中断的方式,DMA配置不生效;
关于搬运方式的建议:
一般在小数据量情况下,如定时采集温度、电池电压,建议采用触发中断并CPU读数的方式。
一般大数据量连续采样,如模拟麦克风采样,建议采用DMA搬运方式(乒乓搬运),可以大大提高数据搬运处理效率。
注意: 多次调用ADC_ConvCfg则以最后一次调用为准(除通道使能,不会自动关闭之前已使能的通道),如只需使能(关闭)ADC通道可以通过ADC_EnableChannel接口完成。
3.2.3 ADC数据处理
ADC数据处理的推荐步骤为:
1. 调用ADC_PopFifoData(或DMA搬运buff)读取FIFO中的ADC原始数据;
2. 调用ADC_GetDataChannel得到原始数据中的数据所属通道(如需要);
3. 调用ADC_GetData得到原始数据中的ADC数据;
也可以通过调用ADC_ReadChannelData接口直接得到指定通道的ADC数据,但这样会丢弃其他通道数据,请谨慎使用。其可以作为辅助接口使用,非主要方式。
对于单个数据的读取我们建议采用取若干数据求其平均值的方式,可以明显提高数据稳定性。
我们提供了方便开发者移植的求平均值程序,如有需求请参考SDK例程peripheral_battery。
3.3 编程指南
3.3.1 驱动接口
ADC控制:
ADC_Reset:ADC复位
ADC_Start:ADC使能
ADC_AdcClose:ADC关闭
ADC配置:
ADC_ConvCfg:ADC转换参数配置
ADC_EnableChannel:通道使能
ADC_DisableAllChannels:关闭所有通道
数据处理相关:
ADC_GetFifoEmpty:读取FIFO是否为空
ADC_PopFifoData:读取FIFO原始数据
ADC_GetDataChannel:读取原始数据中通道号
ADC_GetData:读取原始数据中ADC数据
ADC_ReadChannelData:读取特定通道ADC数据(注意:该接口会丢弃其他通道数据)
ADC_ClrFifo:清空FIFO
ADC_HardwareCalibration: 硬件校准,ADC模块每次重新使能都需要调用硬件校准函数
ADC_GetCalibValueVRefVBat: 获取经过校准后的ADC的值。
ADC_GetVBatVoltage: 获取Vbat的当前电压值
以上是ADC常用接口,还有部分接口不推荐直接使用,在此不进行罗列,详见头文件声明。
3.3.2 代码示例
下面展示ADC的基本用法:
(注:以下ADC参数设置仅供参考,具体参数请结合实际需要进行配置)
3.3.2.1 单次中断搬运
#define ADC_CHANNEL ADC_CH_0
#define ADC_CLK_MHZ 6
static uint32_t ADC_cb_isr(void *user_data)
{
uint32_t data = ADC_PopFifoData();
float calib_data;
SADC_channelId channel = ADC_GetDataChannel(data);
if (channel == ADC_CHANNEL) {
uint16_t sample = ADC_GetData(data);
calib_data = ADC_GetCalibValueVRefVBat(ADC_CHANNEL, sample);
// do something with 'sample'
}
return 0;
}
void adc_init(void)
{
SYSCTRL_ClearClkGate(SYSCTRL_ITEM_APB_ADC);
SYSCTRL_SetAdcClkDiv(24 / ADC_CLK_MHZ);
SYSCTRL_ReleaseBlock(SYSCTRL_ITEM_APB_ADC);
ADC_Reset();
ADC_ConvCfg(SINGLE_MODE, ADC_CHANNEL, 0, 0, 0);
platform_set_irq_callback(PLATFORM_CB_IRQ_SADC, ADC_cb_isr, 0);
ADC_Start(1);
}