1)将一个电机的当前位置与目标位置进行比较,如果它们是相同的,则设置isMoving标志为false并返回.如果它们不同,则将isMoving标志设置为true.
2)如果目标位置大于当前位置,向前移动一步,然后增加当前位置.
3)如果目标位置小于当前位置,向后移动一步,然后减小当前位置.
这是代码:
void _ISR _NOPSV _T4Interrupt(void) { static char StepperIndex1 = 'A'; if(Device1.statusStr.CurrentPosition == Device1.statusStr.TargetPosition) { Device1.statusStr.IsMoving = 0; // Do Nothing } else if (Device1.statusStr.CurrentPosition > Device1.statusStr.TargetPosition) { switch (StepperIndex1) // MOVE OUT { case 'A': SetMotor1PosB(); StepperIndex1 = 'B'; break; case 'B': SetMotor1PosC(); StepperIndex1 = 'C'; break; case 'C': SetMotor1PosD(); StepperIndex1 = 'D'; break; case 'D': default: SetMotor1PosA(); StepperIndex1 = 'A'; break; } Device1.statusStr.CurrentPosition--; Device1.statusStr.IsMoving = 1; } else { switch (StepperIndex1) // MOVE IN { case 'A': SetMotor1PosD(); StepperIndex1 = 'D'; break; case 'B': SetMotor1PosA(); StepperIndex1 = 'A'; break; case 'C': SetMotor1PosB(); StepperIndex1 = 'B'; break; case 'D': default: SetMotor1PosC(); StepperIndex1 = 'C'; break; } Device1.statusStr.CurrentPosition++; Device1.statusStr.IsMoving = 1; } _T4IF = 0; // Clear the Timer 4 Interrupt Flag. }
当接收到移动请求时,目标位置在主程序循环中设置. SetMotorPos线只是用于打开/关闭特定端口引脚的宏.
我的问题是:有没有办法提高这段代码的效率?代码函数很好,如果位置是16位整数但是32位整数处理太多.该设备必须毫不犹豫地与PC通信,并且在写入时会有明显的性能损失.我真的只需要18位数学,但我不知道这样做的简单方法!任何建设性的意见/建议都将非常受欢迎.
警告:所有号码都已组成……假设上面的ISR有大约200(可能,更少)编译代码指令,那些包括在ISR之前和之后保存/恢复CPU寄存器的指令,每个指令占用5个时钟周期(可能是1到3)并且你调用其中2个每秒1000次,我们最终得到2 * 1000 * 200 * 5 =每秒2百万个时钟周期或2 MIPS.
你真的在其他地方消费38 MIPS吗?
唯一可能重要的是我无法看到它,就是在SetMotor * Pos *()函数内部完成的事情.他们做任何复杂的计算吗?它们是否与电机进行一些慢速通信,例如等待他们回应发送给他们的命令?
无论如何,使用32位整数而不是使用16位时,这种简单的代码会明显变慢,这是值得怀疑的.
如果您的代码很慢,请找出花费的时间和数量,然后对其进行分析.在ISR中生成方波脉冲信号(当ISR开始时变为1,当ISR即将返回时变为0)并用示波器测量其持续时间.或者做任何更容易找到的事情.测量在程序的所有部分花费的时间,然后优化真正需要的地方,而不是您之前认为的那样.