乐鑫技术交流
直播中

的撒的

10年用户 742经验值
擅长:可编程逻辑
私信 关注
[问答]

ESP-IDF V5.2使用pnct例程时得到的脉冲数总是为1是什么原因导致的?

ESP-IDF V5.12/V5.2 使用pnct例程时 得到的脉冲数总是为1???用之前的旧的驱动文件是可以。。。
以下这个源码 请帮助分析一下什么原因????

/* Pulse counter module - Example

   For other examples please check:
   https://github.com/espressif/esp-idf/tr ... r/examples

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/pulse_cnt.h" //新的驱动文件
#include "driver/gpio.h"
#include "esp_sleep.h"
#include "driver/ledc.h"

static const char *TAG = "example";

#define EXAMPLE_PCNT_HIGH_LIMIT 30000
#define EXAMPLE_PCNT_LOW_LIMIT -30000

#define EXAMPLE_EC11_GPIO_A 23
#define EXAMPLE_EC11_GPIO_B 2

#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_OUTPUT_IO (5) // Define the output GPIO
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
#define LEDC_DUTY (4096)                // Set duty to 50%. (2 ** 13) * 50% = 4096
#define LEDC_FREQUENCY (100)            // Frequency in Hertz. Set frequency at 4 kHz

/* A sample structure to pass events from the PCNT
* interrupt handler to the main program.
*/
typedef struct
{
    int unit;        // the PCNT unit that originated an interrupt
    uint32_t status; // information on the event type that caused the interrupt
} pcnt_evt_t;

/* Decode what PCNT's unit originated an interrupt
* and pass this information together with the event type
* the main program using a queue.
*/
bool pcnt_on_reach(pcnt_unit_handle_t unit, const pcnt_watch_event_data_t *edata, void *user_ctx)
{
    BaseType_t high_task_wakeup;
    QueueHandle_t queue = (QueueHandle_t)user_ctx;

    xQueueSendFromISR(queue, &(edata->watch_point_value), &high_task_wakeup);
    return (high_task_wakeup == pdTRUE);
};

/* Configure LED PWM Controller
* to output sample pulses at 1 Hz with duty of about 10%
*/

static void example_ledc_init(void)
{
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_MODE,
        .timer_num = LEDC_TIMER,
        .duty_resolution = LEDC_DUTY_RES,
        .freq_hz = LEDC_FREQUENCY, // Set output frequency at 4 kHz
        .clk_cfg = LEDC_AUTO_CLK};
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel = {
        .speed_mode = LEDC_MODE,
        .channel = LEDC_CHANNEL,
        .timer_sel = LEDC_TIMER,
        .intr_type = LEDC_INTR_DISABLE,
        .gpio_num = LEDC_OUTPUT_IO,
        .duty = 0, // Set duty to 0%
        .hpoint = 0};
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}

void app_main(void)
{
   
    ESP_LOGI(TAG, "install pcnt unit");
    pcnt_unit_config_t unit_config;
    unit_config.high_limit = EXAMPLE_PCNT_HIGH_LIMIT;
    unit_config.low_limit = EXAMPLE_PCNT_LOW_LIMIT;
    unit_config.intr_priority = 0;
    unit_config.flags.accum_count = 1;

    pcnt_unit_handle_t pcnt_unit = NULL;
    ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit));

    ESP_LOGI(TAG, "set glitch filter");
    pcnt_glitch_filter_config_t filter_config;
    filter_config.max_glitch_ns = 1000;

    ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config));

    ESP_LOGI(TAG, "install pcnt channels");
    pcnt_chan_config_t chan_a_config;
    chan_a_config.edge_gpio_num = EXAMPLE_EC11_GPIO_A;
    chan_a_config.level_gpio_num = EXAMPLE_EC11_GPIO_B;

    pcnt_channel_handle_t pcnt_chan_a = NULL;
    pcnt_channel_handle_t pcnt_chan_b = NULL;
    ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a));
    pcnt_chan_config_t chan_b_config;
    chan_b_config.edge_gpio_num = EXAMPLE_EC11_GPIO_B;
    chan_b_config.level_gpio_num = EXAMPLE_EC11_GPIO_A;

    ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_b_config, &pcnt_chan_b));

    ESP_LOGI(TAG, "set edge and level actions for pcnt channels");
    ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE));
    ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
    ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_b, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE));
    ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_b, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));

    ESP_LOGI(TAG, "add watch points and register callbacks");
    int watch_points[] = {EXAMPLE_PCNT_LOW_LIMIT, -50, 0, 50, EXAMPLE_PCNT_HIGH_LIMIT};
    for (size_t i = 0; i < sizeof(watch_points) / sizeof(watch_points[0]); i++)
    {
        ESP_ERROR_CHECK(pcnt_unit_add_watch_point(pcnt_unit, watch_points));
    }
    pcnt_event_callbacks_t cbs;
    cbs.on_reach = pcnt_on_reach;

    QueueHandle_t pnct_queue = xQueueCreate(10, sizeof(int));
    ESP_ERROR_CHECK(pcnt_unit_register_event_callbacks(pcnt_unit, &cbs, pnct_queue));

    ESP_LOGI(TAG, "enable pcnt unit");
    ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));
    ESP_LOGI(TAG, "clear pcnt unit");
    ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));
    ESP_LOGI(TAG, "start pcnt unit");
    ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));

    int pulse_count = 0;
    int event_count = 0;

    example_ledc_init();

    while (1)
    {

        if (xQueueReceive(pnct_queue, &event_count, pdMS_TO_TICKS(10)))
        {
            ESP_LOGI(TAG, "Watch point event, count: %d", event_count);
        }
        else
        {
            ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit, &pulse_count));
            ESP_LOGI(TAG, "Pulse count: %d", pulse_count);
        }
        vTaskDelay(10 / portTICK_PERIOD_MS);
    };
}
                                                                                                                                                                                                                        
               
               

回帖(1)

刘丰标

2024-6-6 18:15:59
在分析这个问题之前,我们需要了解ESP-IDF V5.2中的pnct例程以及脉冲计数器模块。脉冲计数器(PCNT)模块是一种用于计数输入脉冲的硬件模块,它可以用于测量脉冲信号的数量、频率和持续时间。

首先,我们需要检查您的代码和配置是否正确。以下是一些建议和可能的问题:

1. 确保您的硬件连接正确:检查您的脉冲输入信号是否正确连接到ESP32的PCNT输入引脚。

2. 检查PCNT配置:确保您在代码中正确配置了PCNT模块,包括选择正确的输入引脚、设置计数模式(上升沿计数、下降沿计数或双边沿计数)以及配置控制寄存器。

3. 检查中断配置:如果您的代码依赖于中断来处理脉冲计数,确保您正确配置了中断,并在中断服务程序中正确处理脉冲计数。

4. 检查代码逻辑:检查您的代码逻辑是否正确处理脉冲计数事件。例如,确保您在适当的时候读取计数器的值,以及在需要时重置计数器。

5. 更新ESP-IDF:如果您使用的是较旧版本的ESP-IDF,尝试更新到最新版本,以确保您使用的是最新的驱动和库。

6. 检查ESP-IDF V5.2的更改:由于您提到使用旧的驱动文件可以正常工作,建议您查看ESP-IDF V5.2相对于V5.1的更改,看看是否有任何与PCNT模块相关的更改可能影响到您的代码。

7. 调试和日志:在您的代码中添加调试和日志输出,以便更好地了解PCNT模块的行为和计数器的值。

如果您已经检查了以上建议,但问题仍然存在,请提供更多关于您的代码和配置的详细信息,以便我们能够更准确地分析问题并提供解决方案。
举报

更多回帖

×
20
完善资料,
赚取积分