关于编码器模式的一些疑问 想用在EC11手动编码器上
看了例程和视频,看的有点迷糊,现有如下疑问,1.这个编码器模式适合EC11这类手动编码器吗,还是说使用PWM捕获做中断更合适?
2.这个编码器模式 可以实现速度读取吗 实时改变步长 例如下
if (speed< 1) { // 超快速
step = 50;
} else if (speed< 10) { // 快速
step = 20;
} else if (speed< 15) { // 中速
step = 5;
} else { // 慢速
step = 1;
}
目前就这两个疑问。还请大佬指点个思路
关于编码器模式在EC11手动编码器上的应用,以下是对您提出的两个疑问的专业解答:
1. 编码器模式是否适合EC11手动编码器?
EC11手动编码器是一种常见的旋转编码器,通常用于检测旋转方向和步进。编码器模式(Encoder Mode)是一种专门用于处理旋转编码器信号的硬件功能,通常集成在微控制器的定时器模块中。它通过捕获编码器的A相和B相信号,自动计算旋转方向和步进数。
对于EC11这类手动编码器,使用编码器模式是非常合适的。编码器模式能够高效地处理编码器信号,减少CPU的负担,并且能够准确检测旋转方向和步进数。相比之下,使用PWM捕获做中断虽然也可以实现类似功能,但需要更多的软件处理,且实时性和准确性可能不如编码器模式。
2. 编码器模式是否可以实现速度读取并实时改变步长?
编码器模式本身主要用于检测旋转方向和步进数,但通过适当的软件处理,可以实现速度读取并实时改变步长。具体实现思路如下:
速度读取:可以通过定时器中断或定时器捕获功能,定期读取编码器的步进数,并计算旋转速度。例如,每隔一定时间(如10ms)读取一次编码器的步进数,然后根据步进数的变化计算速度。
实时改变步长:根据计算得到的速度,动态调整步长。您提供的代码片段已经展示了如何根据速度调整步长的逻辑。在编码器模式中,可以通过软件实现类似的逻辑,根据速度动态调整步长。
以下是一个简单的示例代码,展示如何实现速度读取和步长调整:
c
// 假设编码器步进数存储在变量encodercount中
int encodercount = 0;
int lastencodercount = 0;
int speed = 0;
int step = 1;
// 定时器中断服务程序,每隔10ms执行一次
void TIMERIRQHandler(void) {
// 计算速度
speed = (encodercount - lastencodercount)100; // 假设单位为步/秒
lastencodercount = encodercount;
// 根据速度调整步长
if (speed < 1) { // 超快速
step = 50;
} else if (speed < 10) { // 快速
step = 20;
} else if (speed < 15) { // 中速
step = 5;
} else { // 慢速
step = 1;
}
}
// 主循环中根据步长处理编码器步进
while (1) {
// 处理编码器步进
if (encodercountchanged) {
// 根据步长处理步进
// ...
}
}
总结
编码器模式非常适合EC11手动编码器,能够高效准确地处理编码器信号。
通过适当的软件处理,编码器模式可以实现速度读取并实时改变步长。
希望以上解答能够帮助您更好地理解编码器模式在EC11手动编码器上的应用。如有进一步疑问,欢迎继续探讨。
[本文内容由国芯人工智能辅助生成,仅供参考] 手动编码器的速度不快,并且拧动的时候有噪声,所以更适合直接使用I/O中断来读取脉冲和判断方向,同时软件内加入消抖部分即可 当按键读,用执行其他程序的时间消抖
void Encoder_Scan(void)
{
static bit encoder_up_flag,encoder_down_flag;
static unsigned char encoder_up_temp,encoder_down_temp;
if(PHASE_A==0&&PHASE_B==1&&encoder_down_temp==0&&encoder_down_flag==0&&encoder_up_flag==0&&encoder_up_temp==0)
{
encoder_down_flag=1;
encoder_down_temp=1;
encoder_up_flag=0;
encoder_up_temp=0;
}
if(PHASE_A==1&&PHASE_B==0&&encoder_up_temp==0&&encoder_up_flag==0&&encoder_down_flag==0&&encoder_down_temp==0)
{
encoder_up_flag=1;
encoder_up_temp=1;
encoder_down_flag=0;
encoder_down_temp=0;
}
if(PHASE_A==0&&PHASE_B==0&&encoder_down_temp==1&&encoder_down_flag==1&&encoder_up_flag==0&&encoder_up_temp==0)
encoder_down_temp=2;
if(PHASE_A==0&&PHASE_B==0&&encoder_up_temp==1&&encoder_up_flag==1&&encoder_down_flag==0&&encoder_down_temp==0)
encoder_up_temp=2;
if(PHASE_A==1&&PHASE_B==0&&encoder_down_temp==2&&encoder_down_flag==1&&encoder_up_flag==0&&encoder_up_temp==0)
encoder_down_temp=3;
if(PHASE_A==0&&PHASE_B==1&&encoder_up_temp==2&&encoder_up_flag==1&&encoder_down_flag==0&&encoder_down_temp==0)
encoder_up_temp=3;
if(PHASE_A==1&&PHASE_B==1&&encoder_down_temp==3&&encoder_down_flag==1&&encoder_up_flag==0&&encoder_up_temp==0)
encoder_down_temp=4;
if(PHASE_A==1&&PHASE_B==1&&encoder_up_temp==3&&encoder_up_flag==1&&encoder_down_flag==0&&encoder_down_temp==0)
encoder_up_temp=4;
if(PHASE_A==1&&PHASE_B==1&&encoder_down_temp!=4&&encoder_down_flag==1&&encoder_up_flag==0&&encoder_up_temp==0)
{
encoder_down_temp=0;
encoder_down_flag=0;
}
if(PHASE_A==1&&PHASE_B==1&&encoder_up_temp!=4&&encoder_up_flag==1&&encoder_down_flag==0&&encoder_down_temp==0)
{
encoder_up_temp=0;
encoder_up_flag=0;
}
if(encoder_down_temp==4)
{
encoder_down_flag=0;
encoder_down_temp=0;
encoder_up_temp=0;
encoder_up_flag=0;
//逆时针执行的操作
}
if(encoder_up_temp==4)
{
encoder_up_flag=0;
encoder_up_temp=0;
encoder_down_flag=0;
encoder_down_temp=0;
//顺时针执行的操作
}
}
DebugLab 发表于 2025-4-1 14:00
当按键读,用执行其他程序的时间消抖
这是拧一格执行1次的,这个函数要以100~1000Hz执行,再套一层函数,判断方向和时间,实现可变步长 DebugLab 发表于 2025-4-1 14:05
这是拧一格执行1次的,这个函数要以100~1000Hz执行,再套一层函数,判断方向和时间,实现可变步长 ...
这种轮询的 对于速度计算 并不可靠,并不是不能用,就是体验感不好,因为我们有些参数范围比较大,理想状态,我快拧一圈能实现0-2000,慢拧又能1个1个步进,现在看来,用IO中断更合适,谢谢大佬 菜鸟大神 发表于 2025-4-1 15:23
这种轮询的 对于速度计算 并不可靠,并不是不能用,就是体验感不好,因为我们有些参数范围比较大,理想状 ...
EC11一圈20个格,20就可以了
您希望的快拧快速调节可以再套一层函数,判断时间
放在主程序中只有中断会影响,也可以放在定时器中断中以固定频率执行
这个函数里又没有延时函数,完全就是状态机,也不会造成阻塞
页:
[1]