nrf52840 saadc 多通道的使用

static void saadc_init(void) {
    nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
    saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;
    saadc_config.oversample = (nrf_saadc_oversample_t)NRF_SAADC_OVERSAMPLE_256X;
    saadc_config.interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY;
    saadc_config.low_power_mode = NRFX_SAADC_CONFIG_LP_MODE;

    nrf_saadc_channel_config_t channel_0_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    channel_0_config.gain = NRF_SAADC_GAIN1_6;
    channel_0_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
    channel_0_config.burst = NRF_SAADC_BURST_ENABLED;
    //nrf_saadc_burst_set(0, NRF_SAADC_BURST_ENABLED);

    nrf_saadc_channel_config_t channel_1_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
    channel_1_config.gain = NRF_SAADC_GAIN1_6;
    channel_1_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
    channel_1_config.burst = NRF_SAADC_BURST_ENABLED;
    //nrf_saadc_burst_set(1, NRF_SAADC_BURST_ENABLED);

    nrf_saadc_channel_config_t channel_2_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
    channel_2_config.gain = NRF_SAADC_GAIN1_6;
    channel_2_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
    channel_2_config.burst = NRF_SAADC_BURST_ENABLED;
    //nrf_saadc_burst_set(2, NRF_SAADC_BURST_ENABLED);

    nrf_saadc_channel_config_t channel_3_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
    channel_3_config.gain = NRF_SAADC_GAIN1_6;
    channel_3_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
    channel_3_config.burst = NRF_SAADC_BURST_ENABLED;
    //nrf_saadc_burst_set(3, NRF_SAADC_BURST_ENABLED);

    ERROR_CHECK(nrf_drv_saadc_init(&saadc_config, saadc_event_handler));

    ERROR_CHECK(nrf_drv_saadc_channel_init(0, &channel_0_config));
    ERROR_CHECK(nrf_drv_saadc_channel_init(1, &channel_1_config));
    ERROR_CHECK(nrf_drv_saadc_channel_init(2, &channel_2_config));
    ERROR_CHECK(nrf_drv_saadc_channel_init(3, &channel_3_config));

    //https://devzone.nordicsemi.com/f/nordic-q-a/63074/buffer-order-swap-of-saadc-used-with-nrf-mesh
    nrf_ppi_channel_t saadc_buffer_swap_ppi_channel;
    nrf_drv_ppi_channel_alloc(&saadc_buffer_swap_ppi_channel);
    nrf_drv_ppi_channel_assign(saadc_buffer_swap_ppi_channel,
                               (uint32_t)&NRF_SAADC->EVENTS_END,
                               (uint32_t)&NRF_SAADC->TASKS_START);
    nrf_drv_ppi_channel_enable(saadc_buffer_swap_ppi_channel);

    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Starting initial SAADC calibration\n");
    while(nrf_drv_saadc_calibrate_offset() != NRF_SUCCESS); //trigger calibration task
    saadc_calibrate = false;
}



static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event) {
    static uint16_t saadc_event_counter = 1;  //used for recalibrating adc, start at 1 otherwise will calibrate right away

    if(p_event->type == NRF_DRV_SAADC_EVT_DONE) {
        //Read buffer
        for(int i=0; i<SAADC_SAMPLES_IN_BUFFER; i++) {
            saadc_value_current[i] = p_event->data.done.p_buffer[i];
        }

        if((saadc_event_counter % SAADC_CALIBRATION_INTERVAL) == 0) {
            nrf_drv_saadc_abort();      //abort all ongoing conversions because calibration cannot be run if SAADC is busy
            saadc_calibrate = true;     //set flag to trigger calibration in main context when SAADC is stopped
            saadc_event_counter = 0;    //reset
        }

        if(saadc_calibrate == false) {
            //Set buffer, double-buffering
            ERROR_CHECK(nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER));

            //Print samples
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "\nsaadc_value_current[0]: %u\nsaadc_value_current[1]: %u\nsaadc_value_current[2] %u\nsaadc_value_current[3]: %u\n", saadc_value[0], saadc_value[1], saadc_value[2], saadc_value[3]);
        }
        
        saadc_event_counter++;
    }
    else if(p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE) {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "SAADC calibration complete\n");

        //Need to setup both buffers, as they were both removed with the call to nrf_drv_saadc_abort before calibration
        ERROR_CHECK(nrf_drv_saadc_buffer_convert(saadc_buffer_pool[0], SAADC_SAMPLES_IN_BUFFER));
        ERROR_CHECK(nrf_drv_saadc_buffer_convert(saadc_buffer_pool[1], SAADC_SAMPLES_IN_BUFFER));
    }
}





//======================================================//
    //SAADC
    if(saadc_calibrate) {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Starting interval SAADC calibration\n");
        while(nrf_drv_saadc_calibrate_offset() != NRF_SUCCESS); //trigger calibration task
        saadc_calibrate = false;

        /*
        //PAN-212 workaround: https://devzone.nordicsemi.com/f/nordic-q-a/45339/saadc-burst-problems-in-scan-vs-non-scan-acquisitions/
        //Above three lines commented out
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Power-cycling and re-initalizing SAADC for calibration\n");
        nrf_drv_saadc_uninit();
        *(volatile uint32_t *)0x40007FFC = 0;
        *(volatile uint32_t *)0x40007FFC = 1;
        saadc_init();
        saadc_timeout_counter = 0; //reset
        */
    }
    else if((saadc_timeout_counter % SAADC_SAMPLE_INTERVAL) == 0) {
        ERROR_CHECK(nrf_drv_saadc_sample());
        saadc_timeout_counter = 0; //reset
    }
    
    saadc_timeout_counter++; 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值