当前位置:   article > 正文

基于esp32IDF的简单频率计(1-20M)_esp32频率计

esp32频率计

//结合乐鑫官方文档的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));//开计数器

}

}

}

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号