
微控制器單元(MCU)作為嵌入式系統(tǒng)的核心,廣泛應(yīng)用于物聯(lián)網(wǎng)設(shè)備、工業(yè)控制、消費(fèi)電子等領(lǐng)域。
隨著應(yīng)用場(chǎng)景的復(fù)雜化,MCU需要處理的數(shù)學(xué)運(yùn)算也從簡單的整數(shù)運(yùn)算擴(kuò)展到浮點(diǎn)運(yùn)算。
然而,由于MCU的資源限制,浮點(diǎn)計(jì)算的處理方式與通用處理器有著顯著差異。
本文將探討MCU處理浮點(diǎn)計(jì)算的原理、面臨的挑戰(zhàn)以及常見的優(yōu)化策略。
浮點(diǎn)數(shù)采用IEEE 754標(biāo)準(zhǔn)表示,主要由三部分組成:
MCU處理浮點(diǎn)運(yùn)算有兩種主要方式:
硬件浮點(diǎn)單元(FPU):
軟件浮點(diǎn)庫:
// Q15格式示例:1位符號(hào)+15位小數(shù)
int16_t q15_a = 0.5 * 32768; // 0.5表示為16384
int16_t q15_b = 0.25 * 32768; // 0.25表示為8192
int16_t q15_result = (q15_a * q15_b) >> 15; // 結(jié)果為0.125
const float sin_table[360] = {0, 0.017452, ...};
float fast_sin(uint16_t degree)
{
return sin_table[degree % 360];
}
// 快速平方根倒數(shù)(Quake III算法變體)
float fast_inv_sqrt(float x)
{
float xhalf = 0.5f * x;
int i = *(int*)&x;
i = 0x5f3759df - (i >> 1);
x = *(float*)&i;
x = x*(1.5f-(xhalf*x*x));
return x;
}
__attribute__((always_inline)) inline float cubic(float x)
{
return x*x*x;
}
VADD.F32 S0, S1, S2 ; 單精度浮點(diǎn)加法
VMLA.F32 S4, S5, S6 ; 乘加運(yùn)算 S4 = S5*S6 + S4
void enable_fpu(void)
{
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); // 啟用CP10,CP11
__DSB();
__ISB();
}
// 使用Q15格式實(shí)現(xiàn)的PID算法
typedef struct
{
int16_t Kp, Ki, Kd;
int16_t integral_max;
int32_t integral;
int16_t prev_error;
} PID_Controller;
int16_t PID_Update(PID_Controller* pid, int16_t error)
{
// 比例項(xiàng)
int32_t p_term = (int32_t)pid->Kp * error;
// 積分項(xiàng)
pid->integral += error;
if(pid->integral > pid->integral_max * 32768)
{
pid->integral = pid->integral_max * 32768;
}
elseif(pid->integral < -pid->integral_max * 32768)
{
pid->integral = -pid->integral_max * 32768;
}
int32_t i_term = (int32_t)pid->Ki * pid->integral;
// 微分項(xiàng)
int16_t deriv = error - pid->prev_error;
pid->prev_error = error;
int32_t d_term = (int32_t)pid->Kd * deriv;
// 綜合輸出
int32_t output = (p_term + i_term + d_term) >> 15;
return (int16_t)(output > 32767 ? 32767 : (output < -32768 ? -32768 : output));
}
// 使用硬件FPU的傳感器校準(zhǔn)
void calibrate_sensor(float* readings, uint32_t count, float* offset, float* scale)
{
__enable_fpu(); // 確保FPU啟用
float sum = 0.0f, sum_sq = 0.0f;
float min_val = readings[0], max_val = readings[0];
for(uint32_t i = 0; i < count; i++)
{
sum += readings[i];
sum_sq += readings[i] * readings[i];
min_val = fminf(min_val, readings[i]);
max_val = fmaxf(max_val, readings[i]);
}
float mean = sum / count;
float std_dev = sqrtf((sum_sq - sum*sum/count) / (count-1));
*offset = mean;
*scale = 1.0f / (max_val - min_val);
__disable_fpu(); // 為省電關(guān)閉FPU
}
MCU的浮點(diǎn)計(jì)算處理需要在性能、精度和資源消耗之間找到平衡點(diǎn)。
通過合理選擇硬件、優(yōu)化算法和編寫高效代碼,開發(fā)者可以在資源受限的環(huán)境中實(shí)現(xiàn)令人滿意的浮點(diǎn)計(jì)算性能。
隨著MCU技術(shù)的進(jìn)步,未來浮點(diǎn)計(jì)算在嵌入式系統(tǒng)中的應(yīng)用將更加廣泛和高效。
理解這些原理和技術(shù)將使開發(fā)者能夠?yàn)樘囟☉?yīng)用選擇最佳解決方案。

覺得文章不錯(cuò),點(diǎn)擊“分享”、“贊”、“在看” 唄!