原文:
http://www.eemaker.com/esp32-pulse-cnt-use.html
下载代码:
https://download.csdn.net/download/qq_31806069/11527753
pcnt内部一共有8组单元,每个单元有两个通道,每个通道都有一个脉冲输入脚和控制脚。这个脉冲输入脚很好理解,那么这个控制脚有什么用呢?这个脚也不难,通过软件配置可以用这个脚控制计数器是向上还是向下计数,当然软件里面也可以配置不使用。当然还有个地方需要注意,就是每个单元两个通道是连接在一个计数器上面的,所以通过这两个通道就可以实现对编码器的计数功能。但是假如我要对两路霍尔进行计数就必须要用两个单元
pcnt的中断源呢一共有五个:
L_LIM:最小计数值中断,意思就是达到最小计数值的时候就会触发该中断,最小计数值在初始化的时候有配置
H_LIM:最大计数值中断,意思是达到最大计数值的时候回触发该中断
THRES_0:阈值0 中断,也就是自己设定一个值,当计数到达该值的时候就会触发中断
THRES_1:阈值1中断,和阈值0功能一样,只是可以设定两个阈值
ZERO:计数为0 中断,当计数器值记到0时产生该中断
1、 驱动代码
#define HALL_GPIO_L 4
#define HALL_GPIO_R 12
#define HALL_PCNT_UINT_L PCNT_UNIT_0
#define HALL_PCNT_UINT_R PCNT_UNIT_1
pcnt_unit_t hallPcntUint[2]={HALL_PCNT_UINT_L,HALL_PCNT_UINT_R};
void hallInit()
{
pcnt_config_t pcnt_config = {
// Set PCNT input signal and control GPIOs
.pulse_gpio_num = HALL_GPIO_L,
.ctrl_gpio_num = -1,
.channel = PCNT_CHANNEL_0,
.unit = HALL_PCNT_UINT_L,
// 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_KEEP, // 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 = 30000,
.counter_l_lim = 0,
};
/* Initialize PCNT unit */
pcnt_unit_config(&pcnt_config);
pcnt_config.pulse_gpio_num=HALL_GPIO_R;
pcnt_config.unit=HALL_PCNT_UINT_R;
pcnt_unit_config(&pcnt_config); //��ʼ��pcnt uint1
/* Configure and enable the input filter */
pcnt_set_filter_value(HALL_PCNT_UINT_L, 1000);
pcnt_filter_enable(HALL_PCNT_UINT_L);
pcnt_set_filter_value(HALL_PCNT_UINT_R, 1000);
pcnt_filter_enable(HALL_PCNT_UINT_R);
/* Initialize PCNT's counter */
pcnt_counter_pause(HALL_PCNT_UINT_L);
pcnt_counter_clear(HALL_PCNT_UINT_L);
pcnt_counter_pause(HALL_PCNT_UINT_R);
pcnt_counter_clear(HALL_PCNT_UINT_R);
/* Everything is set up, now go to counting */
}
void hallStartCounter(uint8_t hall)
{
pcnt_counter_pause(hallPcntUint[hall]);
pcnt_counter_clear(hallPcntUint[hall]);
pcnt_counter_resume(hallPcntUint[hall]);
}
void hallStopCounter(uint8_t hall)
{
pcnt_counter_pause(hallPcntUint[hall]);
pcnt_counter_clear(hallPcntUint[hall]);
}
void hallClearCounter(uint8_t hall)
{
pcnt_counter_clear(hallPcntUint[hall]);
}
int16_t hallGetCounter(uint8_t hall)
{
int16_t count;
pcnt_get_counter_value(hallPcntUint[hall],&count);
return count;
}
2、 测试程序
void app_main()
{
hallInit();
hallStartCounter(HALL_PCNT_UINT_L);
while(1)
{
printf("------->Event PCNT unit<-------------%d\n",hallGetCounter(HALL_PCNT_UINT_L));
hallClearCounter(HALL_PCNT_UINT_L);
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
3、 测试效果

网友评论