2025年【ESP32学习-4】外设

【ESP32学习-4】外设背景 编程指南基于 4 4 2 版本 代码基于 4 4 1 版本 外设的驱动逻辑 外设包括 定时器 I2C SPI UART RTC ADC DAC 等等 由于每块芯片的外设都有所不同 地址 功能等 所以驱动代码天然需要进行功能分层 一方面保证驱动的逻辑性 一方面可以将代码功能进行解耦 如下表目录所示

大家好,我是讯享网,很高兴认识大家。
  1. 背景
  2. 外设的驱动逻辑
    1. Low Level (LL) Layer
    2. Hardware Abstraction Layer (HAL)
    3. Driver Layers
    分层 功能 目录
    Low Level 与硬件打交道的最底层,向HAL层提供服务 component\hal\esp32\include\hal
    HAL 基于ll层,将ll层进行逻辑封装,向Driver层提供服务 component\hal
    Driver 向上层应用提供服务 componnet\driver

    举例:
    driver层timer.c 提供定时器的操作接口:timer_init
    timer_init会调用hal层的定时器接口:timer_hal_reset_periph
    timer_hal_reset_periph会调用ll层的接口:timer_ll_intr_disable

  3. PCNT-- pulse counter 统计上升和下降沿的个数

    esp32包含多个 pcnt unit,每个pcnt unit包含一个16bit计数器两个channel,每个channel接入两个信号:ctrl、sig
    在这里插入图片描述
    讯享网

    学习中对于ctrl信号的模式(keep、inverse、hold)比较困惑,下边结合官方示例说明:

    • 官方示例1
      examples\peripherals\pcnt\pulse_count_event\main\pcnt_event_example_main.c
      该例子通过IO18产生PWM波形(1HZ),IO4作为PCNT的sig输入与IO18短接,IO5作为PCNT的ctrl输入接地
       // sig信号的计数模式 .pos_mode = PCNT_COUNT_INC, // 上升沿增加计数器 .neg_mode = PCNT_COUNT_DIS, // 下降沿不操作计数器 // ctrl信号的控制模式 .lctrl_mode = PCNT_MODE_REVERSE, // 反转模式:当ctrl为低电平,pos_mode配置为增加计数时,那么上升沿到来时减少计数器 // 当ctrl为低电平,pos_mode配置为减少计数时,那么上升沿到来时增加计数器  // 当ctrl为低电平,neg_mode配置为增加计数时,那么上升沿到来时减少计数器  // 当ctrl为低电平,neg_mode配置为减少计数时,那么上升沿到来时增加计数器  .hctrl_mode = PCNT_MODE_KEEP, // 保持模式:当ctrl为高电平时,保持原有的上升下降计数模式 

      讯享网

      综上,由于IO5接地,所以ctrl的信号控制模式固定为翻转模式。所以每隔1s读到计数器值在递减,达到边界值后,计数器恢复0后继续减1递减

      讯享网// 样例输出 Current counter value :-1 Current counter value :-2 Current counter value :-3 Current counter value :-4 Event PCNT unit[0]; cnt: -5 THRES0 EVT Current counter value :-5 Current counter value :-6 Current counter value :-7 Current counter value :-8 Current counter value :-9 Event PCNT unit[0]; cnt: 0 L_LIM EVT ZERO EVT Current counter value :0 Current counter value :-1 
    • 官方示例2
      examples\peripherals\pcnt\rotary_encoder\main\rotary_encoder_example_main.c
      该用例使用EC11(旋转编码器)作为PCNT的输入 (旋转编码器原理),将旋钮的物理选转转化为正负数。PCNT两个通道的关键配置罗列如下
       // Configure channel 0 pcnt_config_t dev_config1 = { 
              .pulse_gpio_num = GPIO14, // channel 0/1 输入颠倒 .ctrl_gpio_num = GPIO15, .channel = PCNT_CHANNEL_0, // channel 0/1  .pos_mode = PCNT_COUNT_DEC, // channel 0/1 配置相反 .neg_mode = PCNT_COUNT_INC, // channel 0/1 配置相反 .lctrl_mode = PCNT_MODE_REVERSE, .hctrl_mode = PCNT_MODE_KEEP, }; pcnt_config_t dev_config2 = { 
              .pulse_gpio_num = GPIO14, .ctrl_gpio_num = GPIO15, .channel = PCNT_CHANNEL_1, .pos_mode = PCNT_COUNT_INC, .neg_mode = PCNT_COUNT_DEC, .lctrl_mode = PCNT_MODE_REVERSE, .hctrl_mode = PCNT_MODE_KEEP, }; 

      当顺时针旋转EC11时,IO14领先IO15相位90度(参见后边的棘轮定位基准点图,实际应该小于90°),波形如下

      在这里插入图片描述
      t0时刻:channel0配置生效,IO14作为sig信号是上升沿(PCNT_COUNT_DEC),此时IO15作为ctrl信号为低电平(PCNT_MODE_REVERSE),因此此时增加计数器

      t1时刻:channel1配置生效,IO15作为sig信号是上升沿(PCNT_COUNT_INC),测试IO14作为Ctrl信号为高电平(PCNT_MODE_KEEP),因此此时增加计数器

      t2时刻:channel0配置生效,IO14作为sig信号是下降沿(PCNT_COUNT_INC),此时IO15作为ctrl信号为高电平(PCNT_MODE_KEEP),因此此时增加计数器

      t3时刻:channel1配置生效,IO15作为sig信号为下降沿(PCNT_COUNT_DEC),此时IO15作为ctrl信号为低电平(PCNT_MODE_REVERSE),因此此时增加计数器

      逆时针旋转EC11时,每次上升或下降沿都是递减计数器

      疑问来了 为何是以4为单位进行计数。示例打印如下

      I () example: Encoder value: 0
      I () example: Encoder value: 0
      I () example: Encoder value: -12
      I () example: Encoder value: -18
      I () example: Encoder value: -24
      I () example: Encoder value: 4
      I () example: Encoder value: 8

      查看ec11某款产品参数:定位数(旋钮棘轮个数)为脉冲数(脉冲个数/360°)的两倍,因此计数器的最小增长单位应该是2才对,这点理解不了。(可能样例使用的是定位数=脉冲数的选转编码器)
      在这里插入图片描述
      此外说明书中也没有明确指出定位基准点(棘轮卡位处)与B signal上升下降沿完全对齐。
      在这里插入图片描述

  4. MCPWM - motor control pulse width module 电机脉宽调制
    该外设学习使用的示例1为有刷电机控制: examples\peripherals\mcpwm\mcpwm_brushed_dc_control
    1)需要对PID(proportional integral differential 百分比 积分 微分)控制模式有基本的了解 此外两种数字处理方式(增量、位置)的推导也很简单
    该示例通过将马达与旋转编码器(EC11)相连,旋转编码器与PCNT相连,来感知马达的转速;通过PID的控制模式,利用MCPWM将马达调整至期望转速。
    在这里插入图片描述

该外设学习使用的示例2为无刷电机控制: examples\peripherals\mcpwm\mcpwm_bldc_hall_control
需掌握:
1 无刷电机(brushless direct current motor)的基本原理
2 无刷电机与霍尔传感器的配合
3 死区的概念 避免桥驱动的过程中出现上桥和下桥同时打开的情况

Q&A:

  • 全局变量 TIMERG0 的定义未找到

    \esp-idf-v4.4.1\components\soc\esp32\include\soc\timer_group_struct.htimer_group_struct.h

    讯享网extern timg_dev_t TIMERG0; extern timg_dev_t TIMERG1; 

    根据该变量的使用,可以通过它控制定时器。
    其实该变量的定义在ld文件 esp32.peripherals.ld 中:
    在这里插入图片描述
    属于外设地址范围
    在这里插入图片描述

小讯
上一篇 2025-02-17 18:38
下一篇 2025-03-29 19:19

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/63417.html