RaspberryPi/RP2350

[RP2350_W6100] 다채널 ADC, ADC DMA 테스트

nexp 2025. 1. 18. 12:01

 

 

 

RP2350는 온도 센서 포함 5채널의 12bit ADC가 있다.

 

 

아쉬운점은 채널수도 적고 샘플링 속도나 ADC성능(9.5bit ENOB)은 우수하지 않다.

간단한 아날로그 전압 측정용으로 사용하면 좋을것 같다.

 

 

우선 2채널의 가변저항이 있는 확장 테스트 보드에서 전압값을 측정해 보자.

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"

int main() {

    uint16_t result = 0;
    const float conversion_factor = 3.3f / (1 << 12);

    stdio_init_all();
    sleep_ms(2000);
    
    printf("ADC Example, measuring GPIO26\n");

    adc_init();

    // Make sure GPIO is high-impedance, no pullups etc
    adc_gpio_init(26);
    adc_gpio_init(27);
    // Select ADC input 0 (GPIO26)
    adc_select_input(0);

    while (1) {

        adc_select_input(0);

        // 12-bit conversion, assume max value == ADC_VREF == 3.3 V

        result = adc_read();
        printf("CH0: 0x%03x, voltage: %f V\n", result, result * conversion_factor);

        adc_select_input(1);

        // 12-bit conversion, assume max value == ADC_VREF == 3.3 V
        result = adc_read();
        printf("CH1: 0x%03x, voltage: %f V\n", result, result * conversion_factor);        
        sleep_ms(500);
    }
}

 

 


ADC DMA 테스트

ADC의 최대 샘플레이트는 500 kS/s 이다. STM32와 비교하면 성능이 많이 떨어지는것 같다.

DMA 를 사용하면 최대 샘플레이트를 구현 할 수 있다.

 


Raspberry Pi Pico에서 DMA(Direct Memory Access)를 사용하여 ADC(Analog-to-Digital Converter)로부터 샘플을 캡처하고,  결과를 출력하는 예제. 

#include <stdio.h>
#include "pico/stdlib.h"
// ADC 입력을 위한 헤더 파일:
#include "hardware/adc.h"
#include "hardware/dma.h"

// 이 예제는 DMA를 사용하여 ADC로부터 많은 샘플을 캡처합니다.
//
// - ADC를 0.5 Msps의 주파수로 자유 실행 모드(free-running mode)로 설정합니다.
//
// - DMA 채널을 ADC 샘플 FIFO에 연결합니다.
//
// - 샘플을 8비트로 우측으로 시프트하여 DMA를 통해 바이트 버퍼로 전송합니다.
//


// ADC 채널 0을 GPIO26에 연결
#define CAPTURE_CHANNEL 0
#define CAPTURE_DEPTH 1000


// 샘플을 저장할 버퍼
uint8_t capture_buf[CAPTURE_DEPTH];

int main() {
    stdio_init_all();  // 표준 입출력을 초기화합니다.

    sleep_ms(2000);
    printf("Start ADC \n");

    gpio_init(0);
    gpio_set_dir(0, GPIO_OUT);
    gpio_put(0, 0);  

    // GPIO 26을 아날로그 입력으로 설정: 하이-Z, 풀업/풀다운 해제, 디지털 입력 버퍼 비활성화.
    adc_gpio_init(26 + CAPTURE_CHANNEL);


    adc_init();  // ADC 초기화
    adc_select_input(CAPTURE_CHANNEL);  // 캡처 채널을 선택
    adc_fifo_setup(
        true,    // 완료된 변환을 샘플 FIFO에 작성
        true,    // DMA 데이터 요청(DREQ) 활성화
        1,       // 1개의 샘플이 FIFO에 있을 때 DREQ 및 IRQ 발생
        false,   // 8비트로 읽기 때문에 ERR 비트를 볼 필요 없음
        true     // 샘플을 FIFO에 쓸 때 8비트로 시프트
    );

    // ADC 클럭을 최대 속도(0으로 설정)로 설정
    adc_set_clkdiv(0);

    printf("Arming DMA\n");
    sleep_ms(1000);  // 1초 대기 후 DMA 준비


    // DMA를 설정하여 FIFO에 데이터가 들어오면 즉시 전송
    uint dma_chan = dma_claim_unused_channel(true);  // 사용하지 않는 DMA 채널 요청
    dma_channel_config cfg = dma_channel_get_default_config(dma_chan);

    // 상수 주소에서 읽고, 증가하는 바이트 주소에 쓴다.
    channel_config_set_transfer_data_size(&cfg, DMA_SIZE_8);  // 8비트 크기 설정
    channel_config_set_read_increment(&cfg, false);  // 읽기 주소 증가 안 함
    channel_config_set_write_increment(&cfg, true);  // 쓰기 주소 증가


    // ADC 샘플이 준비될 때마다 DMA 전송
    channel_config_set_dreq(&cfg, DREQ_ADC);

    // DMA 채널 구성 및 시작
    dma_channel_configure(dma_chan, &cfg,
        capture_buf,    // 데이터 목적지
        &adc_hw->fifo,  // 데이터 출발지
        CAPTURE_DEPTH,  // 전송할 샘플 수
        true            // 즉시 시작
    );

    printf("Starting capture\n");
    while(1)
    {
        gpio_put(0, 1);
        adc_run(true);  // ADC 캡처 시작
        // DMA가 끝날 때까지 기다리고, 끝나면 새로운 변환을 시작하지 않도록 설정
        dma_channel_wait_for_finish_blocking(dma_chan);
        //printf("Capture finished\n");
        adc_run(false);  // ADC 실행 중지
        adc_fifo_drain();  // FIFO 비우기
        gpio_put(0, 0);


        // 캡처한 샘플을 표준 출력으로 출력 (PyPlot, Excel, MATLAB 등에 표시 가능)
        for (int i = 0; i < CAPTURE_DEPTH; ++i) {
            /*printf("%-3d, ", capture_buf[i]);
            if (i % 10 == 9)  // 10개마다 새 줄로 출력
                printf("\n");
                */
               gpio_put(0, 1);
               printf("%-3d\n", capture_buf[i]);
               gpio_put(0, 0);
        }
    }
}

 

 

ADC DMA 사용시 수행시간

 

 

반응형