使用ESP32S3 测频率(频率计)4

针对第二篇的内容,有个小问题,每次读取后需要把定时器的内容清零

timerWrite(timer,0);

下面程序优化后,并把计数溢出值改的比较高,这样避免反复进入定时器中断可以优化一点。但效果也不行

#include <Arduino.h>
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;  //声明一个portMUX_TYPE类型的变量,利用其对主代码和中断之间的同步进行处理
hw_timer_t *timer = NULL;
volatile uint32_t timerCount = 0;

volatile int interruptFlag = 0;        //(中断回调函数与主程序共享的变量要加上 volatile 关键字)
volatile int interruptFlag_clear = 0;  //(中断回调函数与主程序共享的变量要加上 volatile 关键字)
const int interruptPin = 5;            // 外部中断引脚

void IRAM_ATTR interruptHandler() {
  portENTER_CRITICAL_ISR(&mux);  // 处理并发
  interruptFlag_clear = 1;
  portEXIT_CRITICAL_ISR(&mux);
}

void setup() {
  Serial.begin(115200);

  // 配置定时器
  timer = timerBegin(10000000);  //10M
  timerAttachInterrupt(timer, []() {
    timerCount++;
  });
  timerAlarm(timer, 10000000, true, 0);  // 设置定时器中断时间间隔
  timerStart(timer);
  // 配置外部中断
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, FALLING);
}

void loop() {
  // Serial.print("Timer count: ");
  // Serial.println(timerCount);
  // timerCount = 0;
  // delay(1000);
  if (interruptFlag_clear == 1) {

    interruptFlag++;
    if (interruptFlag == 1) {
      timerCount = 0;  //第一个脉冲,计数清零
    } else if (interruptFlag == 101) {

      //第二次进入,统计计数个数,并计算频率
      // timerStop(timer);                  //停止计数器
      double timer_other = timerRead(timer);
      double dre_time = timerCount + timer_other / 10000.0;  //单位为微秒
      double fre = 100000.0 / (dre_time);
      Serial.println("timerCount: " + String(timerCount));
      Serial.println("timer_other: " + String(timer_other, 6));
      Serial.println("dre_time: " + String(dre_time, 6));
      Serial.println("fre: " + String(fre, 6));
      
      timerWrite(timer,0);// This function is used to set counter value of the timer.
      timerCount = 0;  //清零
      interruptFlag = 0;
      // timerAlarm(timer, 100, true, 0);  // 设置定时器中断时间间隔(这里是 1 秒)
      // timerStart(timer);  // 重启定时器
    }

    interruptFlag_clear = 0;
  }
}

输入1KHz,得出频率相差快10Hz。

### ESP32-S3 微控制器开发指南 #### 环境搭建 对于初次接触ESP32-S3的开发者来说,环境配置可能是最大的挑战之一。使用VSCode加上ESP-IDF工具链能够极大地简化这一过程,在遵循特定指导的情况下可以在短时间内完成设置[^2]。 安装完成后,建议熟悉ESP32-S3的数据手册以及引脚布局图来更好地理解硬件特性[^1]。这不仅有助于编写更高效的程序,还能防止因错误连接而损坏设备的风险。 #### 功能模块介绍 ##### PWM与LED控制 内置于ESP32-S3中的LEDC(LED Controller)提供了多达8个独立通道用于生成PWM信号,非常适合用来调节灯光亮度或是作为其他外围设备的速度控制系统的一部分[^3]。下面是一个简单的Python代码片段展示如何初始化并操作这些通道: ```python from machine import Pin, PWM pwm = PWM(Pin(18)) # 使用GPIO18作为PWM输出端口 pwm.freq(500) # 设置频率为500Hz pwm.duty_u16(32768) # 占空比设为50% ``` ##### 传感器集成实例 当涉及到运动追踪应用时,结合MPU6050这样的六轴加速度计/陀螺仪组合可以实现精确的姿态量。值得注意的是,虽然这类器件能提供丰富的空间位置数据,但对于旋转角度特别是围绕垂直方向的变化则显得力不从心;此时引入磁力计辅助计算便成为必要选项,从而构建完整的三维方位感知能力[^4]。 ```cpp #include "Wire.h" #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps_V6_12.h" MPU6050 accelgyro; uint8_t devStatus; Quaternion q; VectorFloat gravity; void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // 初始化 MPU6050 并加载 DMP 固件... } void loop() { mpu.dmpGetQuaternion(&q, fifoBuffer); // 获取四元数值 mpu.dmpGetGravity(&gravity, &q); // 计算重力向量 float yawPitchRoll[3]; mpu.dmpGetYawPitchRoll(yawPitchRoll, &q, &gravity); // 打印欧拉角 () Serial.print("yaw: "); Serial.println(yawPitchRoll[0] * 180/M_PI); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值