diff --git a/plsr/accel_curve/plsr_accel_curve.c b/plsr/accel_curve/plsr_accel_curve.c index 808ca27..9cda636 100644 --- a/plsr/accel_curve/plsr_accel_curve.c +++ b/plsr/accel_curve/plsr_accel_curve.c @@ -100,6 +100,42 @@ static uint32_t PlsrAccelCurveShapeLinearPermille(uint32_t u) return (u > 1000U) ? 1000U : u; } +/** + * 正弦加减速形状:raised-cosine p=(1-cos(πu))/2 + * + * 不用 libm sin/cos(软浮点很重,不宜进脉冲 ISR)。 + * 用 33 点预计算表 + 线性插值,O(1)、Flash 约 66 字节,示波器上与直线/S7 可辨。 + */ +static const uint16_t s_plsr_sine_shape_tab[33] = { + 0U, 2U, 10U, 22U, 38U, 59U, 84U, 113U, + 146U, 183U, 222U, 264U, 309U, 355U, 402U, 451U, + 500U, 549U, 598U, 645U, 691U, 736U, 778U, 817U, + 854U, 887U, 916U, 941U, 962U, 978U, 990U, 998U, + 1000U +}; + +static uint32_t PlsrAccelCurveShapeSinePermille(uint32_t u) +{ + uint32_t idx; + uint32_t frac; + uint32_t a; + uint32_t b; + + if (u >= 1000U) + { + return 1000U; + } + /* u/1000 → 表下标 0..32,相邻点线性插值 */ + idx = (u * 32UL) / 1000UL; + if (idx >= 32U) + { + return 1000U; + } + frac = (u * 32UL) - (idx * 1000UL); /* 0..999 对应段内进度 */ + a = (uint32_t)s_plsr_sine_shape_tab[idx]; + b = (uint32_t)s_plsr_sine_shape_tab[idx + 1U]; + return a + (((b - a) * frac) / 1000UL); +} /** * 七段一侧 1:2:1:头尾更圆、中间更陡(相对直线可辨) @@ -139,7 +175,7 @@ static uint32_t PlsrAccelCurveShapePermille(uint32_t u, PlsrAccelMode_e mode) } if (mode == PLSR_ACCEL_SINE) { - //return PlsrAccelCurveShapeSinePermille(u); + return PlsrAccelCurveShapeSinePermille(u); } return PlsrAccelCurveShapeLinearPermille(u); }