我正在尝试以 192kHz 的采样率从 gpio 模拟输入实现 ADC 转换。然后我通过 tcp 将它们发送给客户端。
如何以非阻塞模式(DMA)实现ADC。像这样的东西:
// DMA
let dma = pdma::Dma::new(system.dma, &mut system.peripheral_clock_control);
dma.alloc_buffer::<u64>(256);
let dmaChannel = dma....
...
#![no_std]
#![no_main]
#![allow(non_snake_case)]
use esp_backtrace as _;
use esp_println::println;
use esp32_hal::{
prelude::*,
peripherals::Peripherals,
clock::{ClockControl, CpuClock},
Rtc,
timer::TimerGroup,
adc::{self, ADC1, AdcConfig, ADC, Attenuation},
IO,
Delay,
};
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let mut system = peripherals.DPORT.split();
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Disable the RTC and TIMG watchdog timers
let rtcCntl = Rtc::new(peripherals.RTC_CNTL);
let mut rwdt = rtcCntl.rwdt;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let mut wdt1 = timer_group1.wdt;
rwdt.disable();
wdt0.disable();
wdt1.disable();
// ADC
let analog = peripherals.SENS.split();
let mut adcConfig: AdcConfig<ADC1> = adc::AdcConfig::new();
let mut adcPin = adcConfig.enable_pin(
io.pins.gpio34.into_analog(),
Attenuation::Attenuation11dB,
);
let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adcConfig).unwrap();
let mut delay = Delay::new(&clocks);
loop {
match nb::block!(adc1.read(&mut adcPin)) {
Ok(value) => {
println!("{}", value);
value
},
Err(err) => {
println!("ADC1 read error: {:?}", err);
0
},
};
delay.delay_ms(1_u32);
};
}
它仅在较低频率(最高 1 kHz)下工作。
需要在非阻塞模式 (DMA) 中实现 ADC,以释放 cpu 用于其他任务,例如通过以太网从 adc 传输样本和一些 DSP 任务。