40 MIPS で動作し、C でプログラミングする 16 ビット PIC を使用する組み込みデバイス用のファームウェアに取り組んでいます。システムは 2 つのステッピング モーターの位置を制御し、各モーターのステップ位置を常に維持します。各モーターの最大位置は約 125000 ステップなので、16 ビット整数を使用して位置を追跡することはできません。32 ビット符号なし整数 (DWORD) を使用する必要があります。モーターは 1 秒あたり 1000 ステップで動きます。タイマー ISR でステップが処理されるようにファームウェアを設計しました。タイマー ISR は次のことを行います。
1) 1 つのモーターの現在位置を目標位置と比較し、同じ場合は isMoving フラグを false に設定して戻ります。それらが異なる場合は、isMoving フラグを true に設定します。
2) 目標位置が現在位置より大きい場合は、1 ステップ進めてから現在位置をインクリメントします。
3) 目標位置が現在位置より小さい場合は、1 ステップ後ろに移動し、現在位置をデクリメントします。
コードは次のとおりです。
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 ビット演算だけですが、それを行う簡単な方法がわかりません! 建設的な意見や提案をいただければ幸いです。