Nordic52810入门篇-ADC模数转换

一、前言

Nordic52810使用的是逐次逼近式模拟数字转换器(SAR),在每一次转换过程中,通过遍历所有的量化值并将其转为为模拟值,将输入信号与其逐一比较,最终得到输出的数字信号(百度百科)
ps:如有错误,请留言指正,谢谢

二、工作原理

功能特点

  • 支持8位/10位/12位分辨率,过采样支持14位分辨率
  • 支持8个输入通道(单端输入与差分输入)
  • 可以配合PPI主动触发采样任务(低功耗模式下,RTC定时唤醒后进行采样)
  • 支持EasyDMA进行数据采样
  • 采样电压值范围(0 ~ VDD)
  • 支持连续循环采样模式
  • 可配置内部输入负载阻抗,可检测采样值门限

共享资源

  • 外设COMP也使用模拟输入引脚AIN0-AIN7,为了防止出现冲突,不建议配置到同一个模拟输入引脚

原理框图

ADC默认配置为单端输入模式,此时负极输入内部会接地。但是由于芯片引脚会存在电感电容等寄生参数,会造成地弹噪声,测量数据会存在偏差,对采样数据有要求的情况下可以使用差分输入模式
在这里插入图片描述

数字输出
输出结果主要由CH[n].CONFIGRESOLUTION寄存器来设置,公式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIyBt6dz-1573728834529)(en-resource://database/2647:1)]

  • :正极输入电压
  • 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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章