The PCNT (Pulse Counter) module is designed to count the number of rising and/or falling edges of an input signal. Each pulse counter unit has a 16-bit signed counter register and two channels that can be configured to either increment or decrement the counter. Each channel has a signal input that accepts signal edges to be detected, as well as a control input that can be used to enable or disable the signal input. The inputs have optional filters that can be used to discard unwanted glitches in the signal.
Description of functionality of this API has been broken down into four sections:
pcnt-api-configuration
- describes counter's configuration parameters and how to setup the counter.pcnt-api-operating-the-counter
- provides information on control functions to pause, measure and clear the counter.pcnt-api-filtering-pulses
- describes options to filtering pulses and the counter control signals.pcnt-api-using-interrupts
- presents how to trigger interrupts on specific states of the counter.
The PCNT module has eight independent counting "units" numbered from 0 to 7. In the API they are referred to using :cpppcnt_unit_t
. Each unit has two independent channels numbered as 0 and 1 and specified with :cpppcnt_channel_t
.
The configuration is provided separately per unit's channel using :cpppcnt_config_t
and covers:
- The unit and the channel number this configuration refers to.
- GPIO numbers of the pulse input and the pulse gate input.
- Two pairs of parameters: :cpp
pcnt_ctrl_mode_t
and :cpppcnt_count_mode_t
to define how the counter reacts depending on the the status of control signal and how counting is done positive / negative edge of the pulses.- Two limit values (minimum / maximum) that are used to establish watchpoints and trigger interrupts when the pulse count is meeting particular limit.
Setting up of particular channel is then done by calling a function :cpppcnt_unit_config
with above :cpppcnt_config_t
as the input parameter.
To disable the pulse or the control input pin in configuration, provide :cppPCNT_PIN_NOT_USED
instead of the GPIO number.
After doing setup with :cpppcnt_unit_config
, the counter immediately starts to operate. The accumulated pulse count can be checked by calling :cpppcnt_get_counter_value
.
There are couple of functions that allow to control the counter's operation: :cpppcnt_counter_pause
, :cpppcnt_counter_resume
and :cpppcnt_counter_clear
It is also possible to dynamically change the previously set up counter modes with :cpppcnt_unit_config
by calling :cpppcnt_set_mode
.
If desired, the pulse input pin and the control input pin may be changed "on the fly" using :cpppcnt_set_pin
. To disable particular input provide as a function parameter :cppPCNT_PIN_NOT_USED
instead of the GPIO number.
Note
For the counter not to miss any pulses, the pulse duration should be longer than one APB_CLK cycle (12.5 ns). The pulses are sampled on the edges of the APB_CLK clock and may be missed, if fall between the edges. This applies to counter operation with or without a filer <pcnt-api-filtering-pulses>
.
The PCNT unit features filters on each of the pulse and control inputs, adding the option to ignore short glitches in the signals.
The length of ignored pulses is provided in APB_CLK clock cycles by calling :cpppcnt_set_filter_value
. The current filter setting may be checked with :cpppcnt_get_filter_value
. The APB_CLK clock is running at 80 MHz.
The filter is put into operation / suspended by calling :cpppcnt_filter_enable
/ :cpppcnt_filter_disable
.
There are five counter state watch events, defined in :cpppcnt_evt_type_t
, that are able to trigger an interrupt. The event happens on the pulse counter reaching specific values:
- Minimum or maximum count values: :cpp
counter_l_lim
or :cppcounter_h_lim
provided in :cpppcnt_config_t
as discussed inpcnt-api-configuration
- Threshold 0 or Threshold 1 values set using function :cpp
pcnt_set_event_value
.- Pulse count = 0
To register, enable or disable an interrupt to service the above events, call :cpppcnt_isr_register
, :cpppcnt_intr_enable
. and :cpppcnt_intr_disable
. To enable or disable events on reaching threshold values, you will also need to call functions :cpppcnt_event_enable
and :cpppcnt_event_disable
.
In order to check what are the threshold values currently set, use function :cpppcnt_get_event_value
.
Pulse counter with control signal and event interrupt example: peripherals/pcnt
.