ESP32 的 IDF 內已經有 PCNT(Pulse Counter / 脈衝計數器)範例程式,可以直接編譯使用,首先是設置 PCNT 的輸入和輸出引腳,將輸入和輸出引腳連接一起,輸出引腳會輸出 1Hz 10%佔空比(Duty Cycle)的訊號,觸發 PCNT 中斷處理程序傳遞到主程序,主程序處理 PCNT 接收的訊號,通過串口輸出結果資料。
ESP32 PCNT脈衝計數器電路製作 |
- 編譯並加載示例。
- 打開串口監視器以查看屏幕上打印的消息。
- 將 GPIO17 連接到 GPIO18。
- GPIO5 是控制信號,您可以通過內部上拉使其懸空,或將其連接到地。 如果懸空,脈衝計數值將增加。 如果將 GPIO5 連接到 GND,則計數將減少。
脈衝計數器值時將觸發中斷:
- 達到 thresh1 或 thresh0 值
- 達到 l_lim 值或 h_lim 值
- 將重置為零。
- 檢查範例是否打印出當前計數器值和事件。
ESP32 PCNT 脈衝計數器程式 IO 設定:
#define PCNT_TEST_UNIT PCNT_UNIT_0
#define PCNT_H_LIM_VAL 10
#define PCNT_L_LIM_VAL -10
#define PCNT_THRESH1_VAL 5
#define PCNT_THRESH0_VAL -5
#define PCNT_INPUT_SIG_IO 17 // Pulse Input GPIO
#define PCNT_INPUT_CTRL_IO 5 // Control GPIO HIGH=count up, LOW=count
down
#define LEDC_OUTPUT_IO 18 // Output 1 Hz pulse generator
|
ESP32 PCNT 脈衝計數器程式 Output 1Hz 設定:
static void ledc_init(void)
{
//
Prepare and then apply the LEDC PWM timer configuration
ledc_timer_config_t ledc_timer;
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_timer.timer_num = LEDC_TIMER_1;
ledc_timer.duty_resolution = LEDC_TIMER_10_BIT;
ledc_timer.freq_hz = 1; // set
output frequency at 1 Hz
ledc_timer_config(&ledc_timer);
//
Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel;
ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel.channel = LEDC_CHANNEL_1;
ledc_channel.timer_sel = LEDC_TIMER_1;
ledc_channel.intr_type = LEDC_INTR_DISABLE;
ledc_channel.gpio_num = LEDC_OUTPUT_IO;
ledc_channel.duty = 100; // set duty at about 10%
ledc_channel_config(&ledc_channel);
}
|
ESP32 PCNT 脈衝計數器程式 Input 設定:
static void pcnt_example_init(void)
{
/*
Prepare configuration for the PCNT unit */
pcnt_config_t pcnt_config = {
//
Set PCNT input signal and control GPIOs
.pulse_gpio_num = PCNT_INPUT_SIG_IO,
.ctrl_gpio_num = PCNT_INPUT_CTRL_IO,
.channel = PCNT_CHANNEL_0,
.unit = PCNT_TEST_UNIT,
//
What to do on the positive / negative edge of pulse input?
.pos_mode = PCNT_COUNT_INC, //
Count up on the positive edge
.neg_mode = PCNT_COUNT_DIS, //
Keep the counter value on the negative edge
//
What to do when control input is low or high?
.lctrl_mode = PCNT_MODE_REVERSE, // Reverse counting direction if low
.hctrl_mode = PCNT_MODE_KEEP,
// Keep the primary counter mode if high
//
Set the maximum and minimum limit values to watch
.counter_h_lim = PCNT_H_LIM_VAL,
.counter_l_lim = PCNT_L_LIM_VAL,
};
/*
Initialize PCNT unit */
pcnt_unit_config(&pcnt_config);
/*
Configure and enable the input filter */
pcnt_set_filter_value(PCNT_TEST_UNIT, 100);
pcnt_filter_enable(PCNT_TEST_UNIT);
/* Set
threshold 0 and 1 values and enable events to watch */
pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_1,
PCNT_THRESH1_VAL);
pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_1);
pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_0,
PCNT_THRESH0_VAL);
pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_0);
/*
Enable events on zero, maximum and minimum limit values */
pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_ZERO);
pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_H_LIM);
pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_L_LIM);
/*
Initialize PCNT's counter */
pcnt_counter_pause(PCNT_TEST_UNIT);
pcnt_counter_clear(PCNT_TEST_UNIT);
/*
Register ISR handler and enable interrupts for PCNT unit */
pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, NULL);
pcnt_intr_enable(PCNT_TEST_UNIT);
/*
Everything is set up, now go to counting */
pcnt_counter_resume(PCNT_TEST_UNIT);
}
|
ESP32 PCNT 脈衝計數器程式:
void app_main()
{
/*
Initialize LEDC to generate sample pulse signal */
ledc_init();
/*
Initialize PCNT event queue and PCNT functions */
pcnt_evt_queue = xQueueCreate(10, sizeof(pcnt_evt_t));
pcnt_example_init();
int16_t
count = 0;
pcnt_evt_t evt;
portBASE_TYPE res;
while
(1) {
/*
Wait for the event information passed from PCNT's interrupt handler.
*
Once received, decode the event type and print it on the serial monitor.
*/
res
= xQueueReceive(pcnt_evt_queue, &evt, 1000 / portTICK_PERIOD_MS);
if
(res == pdTRUE) {
pcnt_get_counter_value(PCNT_TEST_UNIT, &count);
printf("Event PCNT unit[%d]; cnt: %d\n", evt.unit, count);
if (evt.status &
PCNT_STATUS_THRES1_M) {
printf("THRES1 EVT\n");
}
if (evt.status & PCNT_STATUS_THRES0_M) {
printf("THRES0 EVT\n");
}
if (evt.status & PCNT_STATUS_L_LIM_M) {
printf("L_LIM EVT\n");
}
if (evt.status & PCNT_STATUS_H_LIM_M) {
printf("H_LIM EVT\n");
}
if (evt.status & PCNT_STATUS_ZERO_M) {
printf("ZERO EVT\n");
}
}
else {
pcnt_get_counter_value(PCNT_TEST_UNIT, &count);
printf("Current counter value :%d\n", count);
}
}
}
|
操作系統:Windows 7 64-bit 版本
開發環境:AiThinker05 版本
原程碼: ESP32 ESP-IDF V3.0rc1
程式:DIY-ESP32-029-PCNT_01_IDF-20181124
ESP32 PCNT 脈衝計數器電路製作運行中 |
ESP32 PCNT 脈衝計數器電路製作顯示 |
ESP32 PCNT 脈衝計數器電路輸出 1Hz |
ESP32 PCNT 脈衝計數器電路串行監視器上的示例輸出 |
※ DIY - ESP32:ESP32 PCNT 脈衝計數器電路(三十八)
※ DIY - ESP32:ESP32 PCNT API 函數模塊介紹(四十)
※ DIY - ESP32:ESP32 PCNT API 函數(四十一)
※ DIY - ESP32:ESP32 PCNT API 函數結構件及其它(四十二)
2018年 11月 27日 天氣報告
氣溫:19.2度 @ 19:20
相對濕度:百分之 92%
天氣:雨
沒有留言:
張貼留言