NRF52芯片硬件设备初探之—SAADC

SAADC设备

  • 什么是SAADC
  • SAADC寄存器及结构
  • SAADC驱动程序
    • SAADC使能
    • SAADC关闭
    • SAADC中断设置
    • SAADC通道配置
    • SAADC任务触发
    • SAADC通道关闭
  • 典型应用代码示例
  • 参考网站

什么是SAADC

SAADC — Successive approximation analog-todigital converter,逐次逼近模数转换器。
八路模拟信号单端或者差分输入,支持8/10/12位采样精度,多次采样模式下采样精度可以达到14位,支持电压采样范围0-VDD,支持RTC或者外部高精度时钟定时执行,同时也支持PPI配置的事件触发执行,支持采样门限值检测,支持EasyDMA可以连续采样到指定RAM空间。NRF52芯片硬件设备初探之—SAADC_第1张图片

SAADC寄存器及结构

NRF52芯片硬件设备初探之—SAADC_第2张图片

SAADC驱动程序

SAADC使能

NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);

SAADC关闭

NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos);

SAADC中断设置

NRF_SAADC->INTENSET = saadc_int_mask;

/** @brief Analog-to-digital converter interrupt masks. */
typedef enum
{
NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event.
NRF_SAADC_INT_DONE = SAADC_INTENSET_DONE_Msk, ///< Interrupt on EVENTS_DONE event.
NRF_SAADC_INT_RESULTDONE = SAADC_INTENSET_RESULTDONE_Msk, ///< Interrupt on EVENTS_RESULTDONE event.
NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE event.
NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event.
NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event.
NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event.
NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event.
NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event.
NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event.
NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event.
NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event.
NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event.
NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event.
NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event.
NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event.
NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event.
NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event.
NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event.
NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event.
NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts.
} nrf_saadc_int_mask_t;

SAADC通道配置

NRF_SAADC->CH[channel].CONFIG =
((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk)
| ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
| ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
| ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
| ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk)
| ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk)
| ((config->burst << SAADC_CH_CONFIG_BURST_Pos) & SAADC_CH_CONFIG_BURST_Msk);

NRF_SAADC->CH[channel].PSELN = pseln;
NRF_SAADC->CH[channel].PSELP = pselp;

SAADC任务触发

*((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)task)) = 0x1UL;

/** @brief Analog-to-digital converter tasks. */
typedef enum
{
NRF_SAADC_TASK_START = offsetof(NRF_SAADC_Type, TASKS_START), ///< Start the ADC and prepare the result buffer in RAM.
NRF_SAADC_TASK_SAMPLE = offsetof(NRF_SAADC_Type, TASKS_SAMPLE), ///< Take one ADC sample. If scan is enabled, all channels are sampled.
NRF_SAADC_TASK_STOP = offsetof(NRF_SAADC_Type, TASKS_STOP), ///< Stop the ADC and terminate any ongoing conversion.
NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration.
} nrf_saadc_task_t;

SAADC通道关闭

NRF_SAADC->CH[channel].PSELN = NRF_SAADC_INPUT_DISABLED;
NRF_SAADC->CH[channel].PSELP = NRF_SAADC_INPUT_DISABLED;

典型应用代码示例

//SAADC初始化
nrfx_saadc_config_t saadc_config = NRFX_SAADC_DEFAULT_CONFIG;
saadc_config.resolution = NRF_SAADC_RESOLUTION_10BIT;
saadc_config.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;
saadc_config.low_power_mode = false;
saadc_config.interrupt_priority = UART_VIR_IRQ_PRIORITY;
nrfx_err = nrfx_saadc_init(&saadc_config, saadc_event_handler);

// For some reason, setting Continuous Mode is not a part of the driver/HAL...
uint32_t cc_value = ADC_SAMPLERATE_CC_VALUE(sample_rate) + 2;
NRF_SAADC->SAMPLERATE = (ADC_SAMPLERATE_MODE_TIMER << ADC_SAMPLERATE_MODE_OFFSET) | cc_value;

//SAADC通道初始化
channel_config.mode = NRF_SAADC_MODE_SINGLE_ENDED;
channel_config.acq_time = NRF_SAADC_ACQTIME_3US;
channel_config.burst = NRF_SAADC_BURST_DISABLED;
channel_config.gain = ADC_SAMPLE_GAIN;
channel_config.pin_p = input_p;
channel_config.pin_n = NRF_SAADC_INPUT_DISABLED;
channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;//NRF_SAADC_RESISTOR_PULLDOWN;
channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
channel_config.reference = NRF_SAADC_REFERENCE_INTERNAL;

nrfx_err = nrfx_saadc_channel_init(ADC_CHANNEL, &channel_config);

//SAADC中断函数

/**@brief Function for handling events from nrfx_saadc */
static void saadc_event_handler(nrfx_saadc_evt_t const * p_event)
{
switch (p_event->type)
{
case NRFX_SAADC_EVT_DONE:
{
NRF_LOG_INFO(“saadc_event_handler ptr = %x, size = %d, ticks = %d…”, p_event->data.done.p_buffer, p_event->data.done.size, NRF_RTC0->COUNTER);
break;

    }

    case NRFX_SAADC_EVT_CALIBRATEDONE:
    {
        break;
    }

    case NRFX_SAADC_EVT_LIMIT:
    {
        break;
    }

    default:
    {
        break;
    }
}

}

//SAADC关闭
nrfx_saadc_channel_uninit(ADC_CHANNEL);
nrfx_saadc_uninit();

参考网站

1: http://www.nordicsemi.com/
2: https://infocenter.nordicsemi.com/index.jsp
3: https://devzone.nordicsemi.com/

你可能感兴趣的:(技术)