ESP32的功能非常强大(我现在已经是一名猛吹粉了)本期介绍ESP32使用其脉冲计数器来测量频率。
可以看到,ESP32支持最多八个通道的脉冲接收和发送。
因此本期将利用两块ESP32来进行实验。其中一块ESP32用来输出PWM波,并且利用电容触摸引脚实现触摸时递增输出频率。
另一块ESP32使用脉冲计数器统计PWM波频率,并且定时器设置1s进行统计得到频率数据。 ** 配置频率计数器 **
void setup() { // put your setup code here, to run once: Serial.begin(115200); attachInterrupt(digitalPinToInterrupt(15), counterISR, RISING);}
unsigned int num = 0;void counterISR(){ num++;}
void loop() { // put your main code here, to run repeatedly: Serial.println("A:"+String(num)); delay(1000);}
首先是 digitalPinToInterrupt 是一个Arduino函数,其作用是将数字引脚(Digital
Pin)映射到相应的中断号(Interrupt Number),这里我们为了将引脚15映射到脉冲计数器的中断上。
当接收到脉冲时,对应的回调函数为counterISR(),这个函数名自己可以定义,在这个中断回调函数中我们将计数加一。
最后的一个参数为触发模式,通常脉冲有上升沿触发和下降沿触发,我们选择的是上升沿触发的模式。
在主函数中,我们延时一秒打印我们统计的脉冲数(这里我的脉冲源是10KHZ)
可以看到每次输出增加的都是10000 定时器配置
hw_timer_t *timer = NULL;//定时器句柄
void setup() { // put your setup code here, to run once: Serial.begin(115200); attachInterrupt(digitalPinToInterrupt(15), counterISR, RISING); timer = timerBegin(0, 80, true); // 选择定时器编号、分频器,true表示计数器自动重载 timerAttachInterrupt(timer, &timerISR, true); // 关联中断处理程序 timerAlarmWrite(timer, 1000000, true); // 设置定时器阈值为 1000000 微秒(1秒) timerAlarmEnable(timer); // 启用定时器}
unsigned int num = 0;void counterISR(){ num++;}int Fre;void timerISR() { // 定时器中断处理程序 Fre = num; num=0;}
void loop() { // put your main code here, to run repeatedly: Serial.println("A:"+String(Fre)); delay(1000);}
我们设置定时器一秒钟触发一次,在定时器的中断回调函数中统计一下频率数实现精准的频率计数。
可以看到精准的10KHZ频率计数。
触摸改变PWM频率
int Fre = 5000;void setup() { // put your setup code here, to run once: ledcSetup(0, Fre, 8); // 通道 0,频率 5kHz,分辨率 8 位 ledcAttachPin(15, 0); // 将 PWM 通道 0 关联到 GPIO 15 ledcWrite(0,128);//通道0 设置占空比为50%}
void loop() { // put your main code here, to run repeatedly: if(touchRead(4)<40) { while(touchRead(4)<40);//等待松开 Fre+=1000; ledcSetup(0, Fre, 8); }}
可以发现改变PWM的频率稳定之后也可以准确的测量PWM频率(不准的因为测的时候频率改变了)。
受PWM限制,到高频的时候PWM的波形严重失真,但是可以看到脉冲计数器的测量还是非常稳定的。