定时器时序的具体分析
a0.1时序分析
在a0.1的固件中,我们通过多次尝试,实现了一个可用的双向计数:
void EXTI6_IRQHandler() {
// ph_b
...
TIM_EncoderInterfaceConfig(
TIM1,
TIM_EncoderMode_TI1,
TIM_ICPolarity_Rising,
TIM_ICPolarity_Rising
);
TIM_ITConfig(TIM1, TIM_IT_CC1, DISABLE);
TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
...
}
void EXTI7_IRQHandler() {
// ph_a
...
TIM_EncoderInterfaceConfig(
TIM1,
TIM_EncoderMode_TI2,
TIM_ICPolarity_Rising,
TIM_ICPolarity_Falling
);
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_CC2, DISABLE);
...
}
所以我们总结了这样的规律
| 从哪里插入 | 计数模式 EncoderMode | 启用中断的CC通道 | 极性翻转 ICPolarity |
|---|---|---|---|
| PH_A | TI2(PH_A) | CC1(PH_B) | IC1(PH_B)不反相(rising),IC2(PH_A)反相(falling) |
| PH_B | TI1(PH_B) | CC2(PH_A) | IC1(PH_B)不反相(rising),IC2(PH_A)不反相(rising) |
以下是从ph_a侧插入时的时序图。
源代码
{
"signal": [
{"name": "ph_a", "wave": "hLhlhlhlhlhlh..."},
{"name": "ph_b", "wave": "h...LHLHLHLHLHLH", "phase": 0.5},
{"name": "TIM_en", "wave": "01..............", "data": "TIM_enabled"},
{"name": "TIM_cnt", "wave": "z2.333333333333z", "data": "0 1 2 3 4 5 6 7 8 9 10 9 10"},
{"name": "TIM_cc_irq", "wave": "l....PlPlPlPlPlP", "phase": 0.5},
{"name": "cnt", "wave": "2..5.....3...3...3...3...3...3.z.", "data": "0 1 2 3 4 5 6 6", "period": 0.5, "phase": 0.5}
]
}
可以看见,在第一个ph_a下降沿之后,TIM被启用,cnt被设为1。之后TIM在每次ph_b上升下降沿时,采样ph_a的电平,以此决定TIM_cnt增减。每一次ph_b上升沿产生CC1中断,将TIM_cnt计算之后更新给cnt。
a0.2时序分析
以下是a0.2四向计数的标准时序,未来实现出来的结果应该完全符合这个时序。 (是的,时至今日a0.2固件主要功能依然没有完全实现)
从1a侧插入,孔在ph1
源代码
{
"signal": [
["input",
{"name": "ph1_a", "wave": "hLhlhlhlhlhlh....."},
{"name": "ph1_b", "wave": "h...LHLHLHLHLHLH..", "phase": 0.5},
{"name": "ph2_a", "wave": "h...l..........h..", "phase": 0.5},
{"name": "ph2_b", "wave": "h.....l..........h"},
],
["ph1_TIM",
{"name": "en", "wave": "01................"},
{"name": "cnt", "wave": "z2.333333333333z..", "data": "0 1 2 3 4 5 6 7 8 9 10 9 10"},
{"name": "cc_irq", "wave": "l....PlPlPlPlPlPl.", "phase": 0.5},
],
["ph2_TIM",
{"name": "en", "wave": "0.1......0.", "data": "ph_2_TIM_en", "period": 0.5},
{"name": "cnt", "wave": "z.2......z.", "data": "0", "period": 0.5},
{"name": "cc_irq", "wave": "l..........", "period": 0.5},
],
{"name": "cnt", "wave": "2.5.....3...3...3...3...3...3.z.....", "data": "0 1 2 3 4 5 6 6", "period": 0.5}
]
}
从1a侧插入,孔在ph2
源代码
{
"signal": [
["intput",
{"name": "ph1_a", "wave": "hL..........h....."},
{"name": "ph1_b", "wave": "h...L..........h..", "phase": 0.5},
{"name": "ph2_a", "wave": "h...lhlhlhlhlhlh..", "phase": 0.5},
{"name": "ph2_b", "wave": "h.....LHLHLHLHLHLH"},
],
["ph1_TIM",
{"name": "en", "wave": "01.....0"},
{"name": "cnt", "wave": "z2.3...z", "data": "0 1"},
{"name": "cc_irq", "wave": "l......."},
],
["ph2_TIM",
{"name": "en", "wave": "01................", "data": "ph_2_TIM_en"},
{"name": "cnt", "wave": "z.2........4.4.4.4.4.4.4.4.4.4.4.4.z", "data": "0 1 2 3 4 5 6 7 8 9 10 9 10", "period": 0.5},
{"name": "cc_irq", "wave": "l......PlPlPlPlPlP"},
],
{"name": "cnt", "wave": "2.5..........4...4...4...4...4...4.z", "data": "0 1 2 3 4 5 6 6", "period": 0.5}
]
}
其余的情况
和前面两种差得不多。我不想再画波形图了😭。
后续
显然些时序图是有问题的。
上面绘制的a0.1版本时序图,和现实无法对应。按照图里的逻辑,计数器是无法正常工作的,而现实里却能很稳定地工作。
于是依照a0.1时序图所画的a0.2时序图也有问题。
我放弃思考了。

后续2
我花了好几个小时试图弄清楚为什么,终于给我研究出来了
我一直以为TIM_EncoderMode_TI1是“在TI1的上升下降沿计数”。然而实际的定义是这样的:
TIM_EncoderMode_TI1: 在TI2的上升下降沿检测TI1的电平TIM_EncoderMode_TI2: 在TI1的上升下降沿检测TI2的电平TIM_EncoderMode_TI12: 在两者上升下降沿检测对方的电平
实际上库里有注释,但是我没看。我真tm活该啊。
现在,上面时序图的错误已经修正了。