编码器测速详情解释:PID闭环控制

一、基本设定(为了理解)

复制代码
ARR = 10(你设定的测试值)
CNT范围:0, 1, 2, 3, 4, 5, 6, 7, 8, 9(共10个值)
溢出:从9→0(正向)或从0→9(反向)

二、为什么 n * 10 是溢出部分的总脉冲?

先看一个直观的例子:

假设: 电机一直在正向旋转,我们观察CNT变化:

复制代码
时间:t0   t1   t2   t3   t4   t5   t6   t7   t8   t9   t10  t11
CNT: 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 0 → 1 → 2
标志:                    ↑                    ↑        ↑
                       正常计数        溢出!    正常计数

计数过程分解:

  1. 第一次完整循环:0→9(10个脉冲)

    • 当CNT从9变成0时,发生溢出

    • n++(n从0变成1)

    • 这10个脉冲就是n * 10中的第一个10

  2. 第二次计数:0→2

    • 这是当前未完成的循环

    • 计数值x=2

    • 这部分还没溢出,所以不计入n

数学表达:

复制代码
总脉冲数 = 已完成的完整循环数 × 每循环脉冲数 + 当前部分脉冲数
         = n × 10 + x

其中:

  • n完整循环的次数(每次溢出记一次)

  • 10:每个完整循环的脉冲数(0-9共10个值)

  • x当前循环已走的脉冲数(0到当前值)

三、分解说明 n × 10 的含义

情景1:n = 1(溢出1次)

复制代码
n × 10 = 1 × 10 = 10个脉冲
含义:已经完整地走完了1个0→9的循环

情景2:n = 3(溢出3次)

复制代码
n × 10 = 3 × 10 = 30个脉冲
含义:已经完整地走完了3个0→9的循环

用更生活化的比喻:

比喻1:汽车的里程表(老式,会归零)

复制代码
里程表范围:00000-99999(相当于ARR=100000)
1. 你开了50000公里:里程表显示50000
2. 你再开50000公里:里程表回到00000(溢出)
3. 你又开了30000公里:里程表显示30000

实际总里程 = 溢出的100000 + 当前的30000 = 130000公里
这里的100000就是 n×ARR(n=1, ARR=100000)

比喻2:时钟(12小时制)

复制代码
时钟范围:1-12点(ARR=12)
1. 从3点开始
2. 经过24小时(溢出2圈)
3. 停在5点

实际经过时间 = 2圈×12小时 + 从3点到5点的2小时
             = 2×12 + 2 = 26小时

四、具体数值示例(ARR=10)

示例1:正向旋转,中等速度

复制代码
初始状态:TIM2开始时,CNT=0, n=0

旋转过程:
脉冲#  | CNT | n   | 说明
-------|-----|-----|----------
第1个   | 1   | 0   | 正常计数
第2个   | 2   | 0   | 正常计数
...    | ... | ... | ...
第9个   | 9   | 0   | 正常计数
第10个  | 0   | 1   | 溢出!n++
第11个  | 1   | 1   | 新循环开始
第12个  | 2   | 1   | 新循环继续

TIM2结束时:
x = CNT = 2
n = 1

计算:
total = x + n×10
      = 2 + 1×10
      = 2 + 10
      = 12个脉冲

验证:确实经过了12个脉冲(第1-12个)

示例2:正向旋转,更快速度

复制代码
初始:CNT=0, n=0
过程:旋转了32个脉冲

详细过程:
第1-10个脉冲:CNT:0→9,然后溢出,n=1
第11-20个脉冲:CNT:0→9,再次溢出,n=2
第21-30个脉冲:CNT:0→9,再次溢出,n=3
第31-32个脉冲:CNT:0→1,n=3

结束时:
x = 1
n = 3

计算:
total = 1 + 3×10
      = 1 + 30
      = 31个脉冲?等等,应该是32!

问题:这里有个差1的错误!

五、重要纠正:差1错误!

这里有一个常见的边界错误

正确理解:

  • 当CNT从9变成0时,n增加1

  • 但这表示已经完成了10个脉冲(0,1,2,...,9)

  • 所以n × 10确实对应了已完成的脉冲数

但是,我们的计数方式有微妙差异:

实际脉冲数计算应该是:

复制代码
总脉冲数 = n × 10 + x

但这里的x当前值 ,不是当前循环已走脉冲数

正确公式(考虑从0开始计数):

复制代码
总脉冲数 = n × 10 + (x - 开始时的CNT值)

如果开始时CNT=0,结束时CNT=x,那么:

复制代码
总脉冲数 = n × 10 + x

这是正确的!

验证示例2(32个脉冲):

复制代码
开始:CNT=0
过程:
第1-10个脉冲:CNT从0→9,溢出时n=1
第11-20个脉冲:CNT从0→9,溢出时n=2
第21-30个脉冲:CNT从0→9,溢出时n=3
第31-32个脉冲:CNT从0→1

结束:
x = 1
n = 3

计算:
total = 1 + 3×10 = 1 + 30 = 31 ❌

问题在哪?

实际上,当第30个脉冲时,CNT=9

第31个脉冲:CNT=0,n=4(不是3!)

第32个脉冲:CNT=1

所以应该是:

复制代码
x = 1
n = 4
total = 1 + 4×10 = 41 ❌(更错了)

六、正确的思考方式

关键在于:溢出发生在CNT回到0的那一刻,而不是在9的时候。

重新思考:

复制代码
每个完整循环:CNT变化 0→1→2→...→9→0
                            ↑
                       这里发生溢出

脉冲计数:
当CNT=0时,表示:
1. 要么还没开始(0脉冲)
2. 要么刚完成一个循环(10个脉冲)

所以,当CNT=x时:
- 如果x>0,表示当前循环已走了x个脉冲
- n表示之前已完成的全循环数

正确示例(32个脉冲):

复制代码
开始:CNT=0(表示尚未开始,或刚复位)

过程:
脉冲# 变化        CNT   n
1      0→1        1     0
2      1→2        2     0
...
10     9→0        0     1  ← 溢出!完成10个脉冲
11     0→1        1     1
12     1→2        2     1
...
20     9→0        0     2  ← 溢出!又完成10个脉冲(共20)
21     0→1        1     2
22     1→2        2     2
...
30     9→0        0     3  ← 溢出!又完成10个脉冲(共30)
31     0→1        1     3
32     1→2        2     3  ← 停止

结束:
x = 2
n = 3

计算:
total = x + n×10
      = 2 + 3×10
      = 2 + 30
      = 32 ✓

七、总结公式

对于ARR=M(你的情况M=10)的编码器:

正向旋转(n≥0):

复制代码
总脉冲数 = 当前CNT值 + n × M

解释:

  • n × M:已完成的全循环脉冲数

  • 当前CNT值:当前循环已走的脉冲数(从0开始)

反向旋转(n<0):

复制代码
总脉冲数 = 当前CNT值 + n × M

注意: n是负数,所以结果是负数,表示反向脉冲数

例如: n=-2, x=3, M=10

复制代码
total = 3 + (-2)×10 = 3 - 20 = -17
表示反向17个脉冲

八、为什么你的代码反向公式不同?

代码:

复制代码
total = (10-x) - (n+1)*10;  // 对于反向

这其实是在尝试计算绝对值,但会丢失方向信息。

建议统一公式:

复制代码
// 无论正反向,统一使用:
total = x + n * M;  // n可正可负

这样:

  • 结果>0:正向旋转

  • 结果=0:静止

  • 结果<0:反向旋转

数值的正负直接表示了方向!

这就是n × M作为溢出部分总脉冲的完整解释。关键是理解:每次溢出代表完成了一个完整的M个脉冲循环

相关推荐
MarkHD2 小时前
智能体在车联网中的应用:第5天 车联网导论与体系认知:驶向智能出行的未来
学习
bulingg2 小时前
集成模型:gbdt,xgboost,lightgbm,catboost
人工智能·算法·机器学习
福大大架构师每日一题2 小时前
ollama v0.13.4 发布——全新模型与性能优化详解
stm32·嵌入式硬件·性能优化·ollama
我想我不够好。2 小时前
电工学习 实操考点及打分项
学习
麒qiqi2 小时前
【Linux 进程间通信】信号通信与共享内存核心解析
java·linux·算法
风123456789~2 小时前
【健康管理】第8章 身体活动基本知识 1/2
笔记·考证·健康管理
肆悟先生2 小时前
3.15 引用类型
c++·算法
(づど)2 小时前
一套齐全的环境设置:nvm\node\nrm\pnpm
前端·笔记
暗之星瞳2 小时前
随机森林(初步学习)
算法·随机森林·机器学习