- 背景
- 外设的驱动逻辑
- Low Level (LL) Layer
- Hardware Abstraction Layer (HAL)
- 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 - 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上升下降沿完全对齐。

- 官方示例1
- 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 中:

属于外设地址范围








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