赞
踩
//结合乐鑫官方文档的demo改动,官方文档链接:通用定时器 - ESP32 - — ESP-IDF 编程指南 latest 文档 (espressif.com)脉冲计数器 (PCNT) - ESP32 - — ESP-IDF 编程指南 latest 文档 (espressif.com)
代码汇总如下:
#include "sdkconfig.h"
#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 "esp_timer.h"
static const char *TAG = "example"; //默认
#define EXAMPLE_PCNT_HIGH_LIMIT 20000 //向上计数的阈值
#define EXAMPLE_PCNT_LOW_LIMIT -30000 //下限(不需调)
#define EXAMPLE_EC11_GPIO_B 4 //信号输入端口
int f10K =0;
double fre=0.0;
int pulse_count = 0;
//int event_count = 0;
bool flag=false;//标志位
static bool example_pcnt_on_reach(pcnt_unit_handle_t unit, const pcnt_watch_event_data_t *edata, void *user_ctx)
{
//BaseType_t通常用于存储任务或中断的返回值,它可以是pdTRUE或pdFALSE
BaseType_t high_task_wakeup;
//数据类型强制转换
QueueHandle_t queue = (QueueHandle_t)user_ctx;
// send event data to queue, from this interrupt callback
xQueueSendFromISR(queue, &(edata->watch_point_value), &high_task_wakeup);
f10K++;//中断溢出后自加1
return (high_task_wakeup == pdTRUE);
}
#define TIMER_INTERVAL_SEC 1 //时间间隔
static void timer_callback(void* arg)//时间回调函数
{
// Your code here
flag=true;
}
/*
void app_main(void)
{
int timer_idx = TIMER_0;
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.intr_type = TIMER_INTR_LEVEL,
.auto_reload = TIMER_AUTORELOAD_EN,
};
// 初始化定时器
timer_init(TIMER_GROUP_0, timer_idx, &config);
// 设置定时器中断服务例程
timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
// 启动定时器
timer_start(TIMER_GROUP_0, timer_idx);
}*/
void app_main(void)
{
esp_timer_handle_t timer_handle;
esp_timer_create_args_t timer_args =
{
.callback = timer_callback,//时间回调
.name = "my_timer"
};
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer_handle));
/*------------------------------------------------------------------------*/
//安装pcnt单元
ESP_LOGI(TAG, "install pcnt unit");//打印日志
pcnt_unit_config_t unit_config =
{
.high_limit = EXAMPLE_PCNT_HIGH_LIMIT,
.low_limit = EXAMPLE_PCNT_LOW_LIMIT,
};
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 =
{
.max_glitch_ns = 25,
};
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 =
{
.edge_gpio_num = EXAMPLE_EC11_GPIO_B, //边沿触发
.level_gpio_num = -1, //禁止电平触发
};
//pcnt通道设置:
pcnt_channel_handle_t pcnt_chan_a = NULL;
ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a));
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_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD));
ESP_LOGI(TAG, "add watch points and register callbacks");//设置观察点
//中断溢出观察点:
ESP_ERROR_CHECK(pcnt_unit_add_watch_point(pcnt_unit, EXAMPLE_PCNT_HIGH_LIMIT));
pcnt_event_callbacks_t cbs =
{
.on_reach = example_pcnt_on_reach,
};
QueueHandle_t queue = xQueueCreate(10, sizeof(int));//队列设置
ESP_ERROR_CHECK(pcnt_unit_register_event_callbacks(pcnt_unit, &cbs, queue));
ESP_LOGI(TAG, "enable pcnt unit");
ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));//使能pcnt
ESP_LOGI(TAG, "clear pcnt unit");
ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));//清除pcnt
// Start the timer
ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle, TIMER_INTERVAL_SEC * 1000000));
ESP_LOGI(TAG, "start pcnt unit");
ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));
// Interval is specified in microseconds
while (1) {
if(flag){
ESP_ERROR_CHECK(pcnt_unit_stop(pcnt_unit));//关计数器
ESP_ERROR_CHECK(esp_timer_stop(timer_handle));//关定时器
ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit, &pulse_count));//获取计数值
fre=f10K*20000.0+pulse_count;//获取频率(hz)
ESP_LOGI(TAG, "Pulse count: %f Hz", fre);
f10K=0;//清零
flag=false;//标志位取反
ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));//计数器清空
// Delay for a while
vTaskDelay(1000 / portTICK_PERIOD_MS);//延迟
// Start the timer
ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle, TIMER_INTERVAL_SEC * 1000000));//开定时器
ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));//开计数器
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。