以第一象限逆圆弧 AE(圆心在原点、半径 R)为例,动点 $P(X_i, Y_i)$,偏差判别式:

递推化简(免开方、免算 $R^2$):

顺圆 SR1~SR4、逆圆 NR1~NR4 共 8 种线形,分两组规则:
| 分组 | 线形 | F ≥ 0 进给 | F < 0 进给 |
|---|---|---|---|
| 第一组 | SR1、NR2、SR3、NR4 | 沿 Y 轴(SR1/NR2 走 −Y,SR3/NR4 走 +Y) | 沿 X 轴(SR1/NR4 走 +X,NR2/SR3 走 −X) |
| 第二组 | NR1、SR2、NR3、SR4 | 沿 X 轴(NR1/SR4 走 −X,SR2/NR3 走 +X) | 沿 Y 轴(NR1/SR2 走 +Y,NR3/SR4 走 −Y) |
递推公式形式不变,只是符号与 X/Y 对调:$F_{i+1} = F_i - |2Y_i| + 1$(|Y| 减 1 的场合)或 $F_{i+1} = F_i + |2X_i| + 1$(|X| 加 1 的场合)。

终点判别用总步长法:$n = |X_e - X_a| + |Y_e - Y_a|$,每进给一步 n 减 1,减到 0 结束。实际每步位移比头发丝还小,宏观轨迹看起来就是光滑圆弧。
/* 终点判别:总步长法 */
g_pol_par.end_pulse--; /* 总步数减一 */
if (g_pol_par.end_pulse == 0) {
g_motor_sta = STATE_STOP; /* 到达终点 */
TIM_CCxChannelCmd(ATIM_TIMX_PWM,
st_motor[g_pol_par.act_axis].pulse_channel, TIM_CCx_DISABLE);
HAL_TIM_Base_Stop_IT(&g_atimx_handle); /* 停止定时器 */
}/* 偏差递推:F = F + 2*符号*新坐标 + 1 */
g_pol_par.f_e = g_pol_par.f_e + 2 * sign_dir[g_pol_par.act_axis]
* g_pol_par.start_point[g_pol_par.act_axis] + 1;硬件与直线插补实验完全相同(接口三 = X 轴、接口四 = Y 轴,1.0A、8 细分 1600 脉冲/圈)。setarcdir() 按起点坐标和顺/逆方向确定象限、两轴旋转方向及偏差符号位;arc_incmove() 校验起终点满足同一圆方程($X^2+Y^2$ 相等)并计算总步数。
if (key == KEY0_PRES) { /* 按下 KEY0 开始插补 */
arc_incmove(800 * 5, 0, 0, -800 * 5, 2000, CW); /* 第四象限圆弧 */
while (g_motor_sta);
arc_incmove(0, -800 * 5, -800 * 5, 0, 2000, CW); /* 第三象限圆弧 */
/* 依次再走第二、第一象限圆弧,合成一个顺时针整圆 */
}验证现象:按下 KEY0,笔尖依次走完四个象限圆弧,画出一个顺时针整圆,LCD/串口有对应提示。