一、前言
Nordic52810使用的是逐次逼近式模拟数字转换器(SAR),在每一次转换过程中,通过遍历所有的量化值并将其转为为模拟值,将输入信号与其逐一比较,最终得到输出的数字信号(百度百科)
ps:如有错误,请留言指正,谢谢
二、工作原理
功能特点
- 支持8位/10位/12位分辨率,过采样支持14位分辨率
- 支持8个输入通道(单端输入与差分输入)
- 可以配合PPI主动触发采样任务(低功耗模式下,RTC定时唤醒后进行采样)
- 支持EasyDMA进行数据采样
- 采样电压值范围(0 ~ VDD)
- 支持连续循环采样模式
- 可配置内部输入负载阻抗,可检测采样值门限
共享资源
- 外设COMP也使用模拟输入引脚
AIN0-AIN7
,为了防止出现冲突,不建议配置到同一个模拟输入引脚
原理框图
ADC默认配置为单端输入模式,此时负极输入内部会接地。但是由于芯片引脚会存在电感电容等寄生参数,会造成地弹噪声,测量数据会存在偏差,对采样数据有要求的情况下可以使用差分输入模式
数字输出
输出结果主要由CH[n].CONFIG和RESOLUTION寄存器来设置,公式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIyBt6dz-1573728834529)(en-resource://database/2647:1)]
- V§:正极输入电压
- V(N):负极输入电压
- GAIN:增益
- REFERENCE:参考电压
三、工作模式
ADC可配置成三种工作模式:单次模式、连续模式、扫描模式
- 单次模式(One hsot mode):仅配置了一个有效的采样通道
- 连续模式(Continuous mode):连续采样主要是通过内部定时器进行定时采样,也可配合PPI触发采样
- 扫描模式(scan mode):当有效通道大于1个时,通过扫描模式进行逐个有效通道的采样
四、寄存器
- INTEN:中断控制寄存器,写1使能中断,写0禁用中断(按位配置中断)
- INTENSET:中断使能寄存器,写1有效
- INTENCLR:中断禁用寄存器,写1有效
- STATUS:状态寄存器,读取到0为ADC空闲(当前未在转换),读取到1位ADC忙(转换过程中)
- ENABLE:ADC外设使能寄存器,写1使能,写0禁用;使能前必须确认输入引脚已经被配置
- CH[0-7].PSELP:选择通道0-7中正极输入引脚
- CH[0-7].PSELN:选择通道0-7中负极输入引脚
- CH[0-7].CONFIG:配置寄存器,可配置为输入模式(差分、单端)、增益、参考电压与转换速率
- CH[0].LIMIT:门限监控事件配置,高于门限或低于门限可触发事件中断
五、相关接口
SAADC的驱动目录在modules\nrfx\drivers\src\nrfx_saadc.c中
- nrfx_saadc_init:初始化saadc,主要配置分辨率与过采样
- nrfx_saadc_channel_init:配置采样模式(单端、差分),通道与关联引脚
- nrfx_saadc_buffer_convert:触发adc转换,形参为adc转换的缓存与需要转换的缓存大小
六、实例代码
saadc初始化
实例使用的工程目录为examples\peripheral\saadc saadc.eww,使用通道0,引脚为PIN2,可以修改channel_config结构修改参数
void saadc_init(void)
{
ret_code_t err_code;
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
err_code = nrf_drv_saadc_init(NULL, saadc_callback);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(0, &channel_config);//通道0
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);//接收缓存
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
}
主函数
int main(void)
{
uint32_t err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEFAULT_BACKENDS_INIT();
ret_code_t ret_code = nrf_pwr_mgmt_init();
APP_ERROR_CHECK(ret_code);
saadc_init();
saadc_sampling_event_init();
saadc_sampling_event_enable();
NRF_LOG_INFO("SAADC HAL simple example started.");
while (1)
{
nrf_pwr_mgmt_run();
NRF_LOG_FLUSH();
}
}