Available on crate feature
unstable
only.Expand description
§Pulse Counter (PCNT)
§Overview
The PCNT module is designed to count the number of rising and/or falling edges of input signals. They may contain multiple pulse counter units in the module. Each unit is in effect an independent counter with multiple channels, where each channel can increment/decrement the counter on a rising/falling edge. Furthermore, each channel can be configured separately.
It consists of two main modules:
§Examples
§Decoding a quadrature encoder
static UNIT0: Mutex<RefCell<Option<unit::Unit<'static, 1>>>> =
Mutex::new(RefCell::new(None)); static VALUE: AtomicI32 = AtomicI32::new(0);
// Initialize Pulse Counter (PCNT) unit with limits and filter settings
let mut pcnt = Pcnt::new(peripherals.PCNT);
pcnt.set_interrupt_handler(interrupt_handler);
let u0 = pcnt.unit1;
u0.set_low_limit(Some(-100)).unwrap();
u0.set_high_limit(Some(100)).unwrap();
u0.set_filter(Some(min(10u16 * 80, 1023u16))).unwrap();
u0.clear();
// Set up channels with control and edge signals
let ch0 = &u0.channel0;
let pin_a = Input::new(peripherals.GPIO4, Pull::Up);
let pin_b = Input::new(peripherals.GPIO5, Pull::Up);
let (input_a, _) = pin_a.split();
let (input_b, _) = pin_b.split();
ch0.set_ctrl_signal(input_a.clone());
ch0.set_edge_signal(input_b.clone());
ch0.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
ch0.set_input_mode(channel::EdgeMode::Increment,
channel::EdgeMode::Decrement);
let ch1 = &u0.channel1;
ch1.set_ctrl_signal(input_b);
ch1.set_edge_signal(input_a);
ch1.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
ch1.set_input_mode(channel::EdgeMode::Decrement,
channel::EdgeMode::Increment);
// Enable interrupts and resume pulse counter unit
u0.listen();
u0.resume();
let counter = u0.counter.clone();
critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0));
// Monitor counter value and print updates
let mut last_value: i32 = 0;
loop {
let value: i32 = counter.get() as i32 + VALUE.load(Ordering::SeqCst);
if value != last_value {
last_value = value;
}
}
#[handler(priority = Priority::Priority2)]
fn interrupt_handler() {
critical_section::with(|cs| {
let mut u0 = UNIT0.borrow_ref_mut(cs);
let u0 = u0.as_mut().unwrap();
if u0.interrupt_is_set() {
let events = u0.events();
if events.high_limit {
VALUE.fetch_add(100, Ordering::SeqCst);
} else if events.low_limit {
VALUE.fetch_add(-100, Ordering::SeqCst);
}
u0.reset_interrupt();
}
});
}
Modules§
- PCNT - Channel Configuration
- PCNT - Unit Module
Structs§
- Pulse Counter (PCNT) peripheral driver.