注意 16位有符號數 表示的范圍是 -32768~32767
假如 整形數在內存中以源碼的形式存放, 則0000 0000 0000 0000 表示正整數0
則 1000 0000 0000 0000 表示負整數0 ,顯然重復了。
另外采用補碼 可以將減法運算變為加法:
例如: -1-2=-3 可以變為 -1的補碼加上-2的補碼
對於整數: [A-B]補=[A]補+[-B]補
-1的補碼為
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
-2的補碼為
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
相加 變為
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
上邊的紅色1 為進位 去掉
則
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
減1 以后, 求反 可知道為-3
結論:故數據在內存中以補碼的形式存放。
數據在內存中以補碼的形式存放,
對於正整數 源碼=反碼=補碼
對於負數 例如-10
源碼為 1000 0000 0000 1010 1為符號位
反碼為 1111 1111 1111 0101
補碼為 1111 1111 1111 0110
假設對於有符號數A 在內存中的存放形式
補碼為以下:
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
則它表示的數為:
符號位不變,先減1 然后在求反, 可知 這個數不存在
於是 人為 規定 1000 0000 0000 0000 表示為-32768
對於IQ格式 數據的理解:
IQ30 表示的數據范圍:
31 |
30 |
Point |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
對IQ30小數點在30位和29位之間, 所以它表示的數值范圍是
-2-----1.999 999 999
同理對於 IQ16
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
POINT |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
即 -32768------32767.999984741
使用方法:
IQN實際沒你想的復雜,你就簡單的認為是把小數的乘法,變為整數的乘法而已。
只要計算的結果 不超過你規定的IQN的范圍就行。
只是這樣做 CPU的在處理浮點數時,更得心應手
例如 :
對與60kW永磁場同步電機的 直流母線電壓采樣環節
圖1
在EEPROM 參數設定的上位機 軟件中 Systemp->UDC_LEM_RATIO 的值為200
BASE_VOLTAGE的值為1000
已知IQ20的表示范圍為 -2048----2047.999 999 046
所以IQ20(200) 與IQ20(1000) 是合理的。 如果是IQ(3000)就不對了。
上圖1 的第一行temp 我在ADDWATCHWINDOW以后,用Q24 的格式去觀看,就是0.6
上圖1中的第二行的temp 我在watchwindow 里觀測, 其值為 0.0001465082169
如下圖所示
如用_iq格式觀看,其值為 2458 (這里iq 為全局IQ24 是整形數)
tmp=_IQdiv(tmp,_IQ15toIQ(Systemp->UDC_LEM_FACTOR));
Systemp->UDC_LEM_FACTOR的值為19661
19661 如果是IQ15格式 對應的數為
經過了IQ15toIQ以后, 我如果用IQ24查看,其值還是 0.6
關於對母線電壓采樣的說明:
直流母線采樣,1000V對應調理輸出為5V 然后經過電路板上分壓電阻3/5轉換為3V,(因為DSP要求的電壓是3V), 即ADC采樣得到的4095 對應的是1000V 那么假設ADC采樣得到的值是y
第一極的比例
第二極的比例
第三極的比例
那么 實際的電壓值應為
那么之流母線的標幺值為
在DSP程序中 通過上面的圖指導UDC_PU_GAIN 的值就是
所以上面的紅線高亮的udc是標幺值,上傳給上位機就需要轉換為真實值
當DSP把這個數據傳遞給上位機,在郵箱11中
用VB編寫的上位機的接收的是整數, 於是在VB中定義了一個浮點數,
然后將DSP傳遞上來的整數除以32768 在乘以1000 即可 。
下圖是VB上位機的處理
(2) IQ的乘法
描述:C編譯器將兩個不同的IQ格式的IQ數進行相乘。
關於對_IQNmpyIQX(_iqN1 A ,int N1 _iqN2 B ,int N2)
下面的程序 定義 temp135 為 IQ4 temp678 為IQ22 temp246為IQ16
實際計算的值
而我用IQ乘法計算得到的值為1166.952225
誤差為 0.154759
如下圖所示:
如果采用了 IQ4(450.256) 未超出IQ4的表示的數的數值范圍
IQ22(200.789) 未超出IQ22表示的范圍
而
這個90406.451984 超出了_iq16 表示的數值范圍,所以計算結果不對,如下圖所示。
若把temp246 改正為 _IQ10 那么計算結果會好嗎?
IQ10的數值范圍 -2097152------2097151.999023
計算結果為90405.24707
計算誤差為
精度基本上到萬分之一
精度已經很高了,能不能再高一些,
我的想法是:用IQ14代替IQ10 因為IQ14 的分辨率高於IQ10 提高精度的作用不大。
百度網盤
