1引言
實時控製係統程序設計中,常涉及到小數運算問題.計算機係統中用二進製表示小數的方法有定點數表示法和浮點數表示法.采用浮點數表示法表示的小數範圍大、精度高,但程序代碼長,運算速度慢.定點數表示的小數範圍小、精度低,但程序代碼短,運算速度快.
使用C語言設計程序具有程序可讀性強,編程方便等優(you) 點,但按常規方法設計程序時,實時性不如采用匯編語言設計的程序,這在涉及到小數運算時表現更為(wei) 突出.這樣就限製了C語言的應用.如果采用合適的計算方法,使用C語言編程可以獲得與(yu) 匯編語言編程同樣的實時性.
實時控製係統中的前向通道采集的原始數據大多是定點整數,例如前向模擬通道的A/D轉換器的轉換結果,定時/計數器的計數結果等,都是定點整數.而係統的後向通道能接受的輸入量也都為(wei) 整數,即由量化產(chan) 生的有限字長誤差不可避免,精確到小數位的控製量因執行機構無法接受而不得不舍去.因而,雖然采用定點數表示小數的方法精度低,但在大多數情況下,仍能滿足實時控製係統的控製精度要求.
MCS-51單片機的內(nei) 部程序存儲(chu) 器僅(jin) 有4K,運算速度較慢.對於(yu) 實時性、代碼長度限製要求較高的控製係統,采用MCS-51單片機控製時,不宜大量采用浮點運算.本文介紹Keil C51下的16位定點小數的乘法程序.
2 定點小數運算算法
1.1 控製算法的特點.
計算機實時控製係統中,控製算法通常可用下麵的差分方程表示.
式中y[n]為(wei) 第n個(ge) 采樣周期的輸出,通常為(wei) 二進製整數;x [n]為(wei) 第n個(ge) 采樣周期的輸入,通常也為(wei) 二進製整數;ai、bi為(wei) 實係數.在保證計算精度的條件下,計算上述差分方程時,將係數ai、bi轉換成整數或定點小數,會(hui) 大幅度提高運算速度和大幅度減少代碼長度.這對於(yu) 在程序存儲(chu) 器容量或運算速度有限的嵌入式控製器中實現快速控製算法計算有重要意義(yi) .
1.2 定點小數
小數可分為(wei) 整數部分為(wei) 0的純小數和帶整數的小數.純小數可直接用定點小數表示,當使用16位定點小數時,分辯率可達2-16,可以獲的足夠的運算精度.
1.3 定點算法
設x為(wei) 十進製純小數,M為(wei) 16位二進製整數.若程序需計算y=(x·M)取整,則可先將x轉換成16位二進製定點小數.
X =(x·65536)取整 (2)
由於(yu) X的小數點在X的最高位前,2個(ge) 16位二進製數相乘結果為(wei) 32位二進製數,小數點在高16位和低16位間,乘法運算後的高16位為(wei) 計算結果的整數部分,低16位為(wei) 計算結果的小數部分.即
(x·M)取整=(X·M)取高16位 (3)
這樣處理後可以大幅度提高運算速度,且大幅度減少代碼長度.
匯編語言程序設計中的取整操作容易實現,在C語言中實現取整操作可以使用聯合體(ti) ,方法如下.
先定義(yi) 2個(ge) 聯合體(ti) .
union{
unsigned char a_byte[4];
long a_long;
}r;
union{
unigned char b_byte[2];
int b_int;
}p;
第一個(ge) 是長整數變量與(yu) 4字節變量的聯合體(ti) ,長整型變量用於(yu) 保存計算結果,第二個(ge) 是整型變量與(yu) 2個(ge) 字節型變量的聯合體(ti) ,用於(yu) 取整運算.在Keil C51中,長整數占4個(ge) 字節,在RAM中按從(cong) 高到低的順序存放,r.a_byte[0]、r.a_byte[1]存放計算結果的整數部分,r.a_byte[2]、r.a_byte[3]存放計算結果的小數部分.
通過下列程序,實現取整運算.
p.b_byte[0]=r.a_byte[0];
p.b_byte[1]=r.a_byte[1];
這樣p.b_int為(wei) 計算結果的整數部分.以上程序在編譯後僅(jin) 為(wei) 2條數據傳(chuan) 送指令,需要4個(ge) 機器周期的執行時間.與(yu) 采用除法運算或移位運算實現取整運算相比,具有更快的執行速度.
3 程序
設程序需要計算0.12345乘16位二進製數後取整,采用浮點數時的程序如下所示.
main()
{
int b;
b=20000;
a=0.12345*b;
}
本程序的運行結果a=2527,程序編譯後長度513字節,做浮點運算時需要602個(ge) 機器周期.
main()
{
int a,b;
union{
char c[4];
long d;
}u1;
union{
char e[2];
int f;
}u2;
b=20000;
u1.d=(long)8090*b;
u2.e[0]=u1.c[0];
u2.e[1]=u1.c[2];
}
本程序的運行結果u2.f=2527,程序編譯後長度129字節,做整數運算時僅(jin) 需134個(ge) 機器周期.
4 結束語
采用本文中所述方法,使用c語言設計MCS-51單片機控製算法程序,可獲得與(yu) 采用匯編語言設計的控製算法程序同樣的效果.充分發揮了
c語言設計程序的優(you) 點,筆者在設計的某控製係統時,采用這種方法在獲得了很好的效果.