1. 程式人生 > >關於使用CCSV5利用斷點匯入外部資料在Graph中顯示波形的實踐

關於使用CCSV5利用斷點匯入外部資料在Graph中顯示波形的實踐

關於使用CCSV5利用斷點匯入外部資料在Graph中顯示波形的實踐


  1. 關於**.dat**檔案的介紹
  2. 關於DSP中定點浮點數的表示與轉換
  3. 關於補碼的計算

.dat檔案不是一種標準的檔案格式,許多軟體都在使用這個副檔名,但是各個軟體對.dat檔案的定義格式不一定相同
現在講CCS,DSP可以識別的.dat檔案的格式,

圖示為用記事本開啟的(有些.dat檔案記事本開啟是亂碼原因可能是生成這個.dat檔案的軟體有自己的加密方式)利用matlab按照自己的格式生成的.dat檔案,這種格式的.dat檔案是CCS支援的格式:第一行為五個資料,第一個1651,固定數;第二個為.dat檔案儲存的下面資料的格式“1”代表十六進位制整型、“2”代表十進位制整型、“3“代表十進位制長整型、”4“代表十進位制浮點型;第三個數代表DSP的儲存地址,說明從檔案讀取的資料要存放的位置;第四個數代表頁型別,可以是程式也可以是資料;第五個數表示的是資料的長度。其中後面三項可以全部為0。


以上是對CCS\DSP可以識別的.dat檔案的格式的介紹,下面介紹關於DSP當中定點數與浮點數的介紹
暫時理解為當儲存位數一定時,DSP是如何儲存小數的,例如用十六位來儲存小數,要介紹定標法

這裡寫圖片描述

這裡寫圖片描述
這裡寫圖片描述

其中紅色的位標識的是符號位,利用的是補碼錶示,從介紹中可以看到(就以Q定標為例吧)當無定標的時候除符號位以外其它位按照二進位制位數從高到低表示數的大小,當定標以後(以Q14為例)無定標也可以理解為(Q0)意思就是小數點在第0位的前面就是在第一位的後面,前十五位(除去符號位)都是表示的整數部分,自然Q15表示的就是小數點在第十五位的前面,後面的十五位都是表示小數部分因此Q15和Q0所表示的數的取值範圍不同,Q15中第十五位上的”1“實際上是處於小數部分第一位,他的”1“表示的是0.5,因此第十四位上的”1“表示的是0.25,以此類推。具體我們在定標時採用Q多少來定標就是說小數點向左移動幾位,這個東西是由我們要表示的數的最大值以及小數位數的精度來決定的,就是說,用N位來儲存資料,出去符號位後小數點向左移動,要保證左邊留出的位數夠大右面的位數夠小數進度,現在我們知道了DSP是如何定標的了。那麼我們如何在DSP中儲存0.5這個小數呢,我們發現0.5在16位儲存時是可以利用Q15來定標的,那麼我們如何把這個浮點數表示出來呢
這裡寫圖片描述


我們讓這個浮點數乘以2的Q多少次方就可以將這個浮點數轉化成一個定點數,而這個定點數用二進位制表示出來後如果用定標的約定去解讀這個二進位制數的話求出來就正好是這個浮點數的大小,其實前面讓這個浮點數去乘以2的多少次方其實就是小數點的左移造成的,然而實際當中DSP儲存的還是那個定點數的二進位制,DSP本身不知道定標這件事情,這個事情只不過是程式設計師自己的約定罷了,我們要儲存0.5,(16位儲存,定標Q15)的情況下,我們先求出0.5*2^15這個數,然後在DSP中儲存這個定點數,當我們從記憶體中讀取出這個數之後再利用定點數與浮點數的轉換求出我們實際上儲存的浮點數。
這樣就實現了在DSP中儲存浮點數。實際當中我們的float,double等都是這樣的規則,只不過他們的儲存位數以及定標數都是確定的所以這些轉化就是系統自動轉化的,當我們要自己編寫記憶體資料檔案然而恰巧又有浮點數時我們就要這樣儲存了。


以上是關於DSP中浮點數的實際儲存問題的介紹,下面講資料儲存過程中補碼的問題

資料在計算機中儲存的是其補碼,對於有符號數,用N位來儲存資料,最高位為符號位,正數的補碼為其二進位制碼本身,符號位為0;負數的符號位為1,負數的補碼是:符號位不變,數值位在原來二進位制碼的基礎上按位取反然後加上一,得到的二進位制碼為其補碼,下面介紹一些概念
模和補數
假如現在是6點,想知道3個小時前是幾點,我們可以直接把時針逆時針旋轉3個小時,也可以順時針旋轉9個小時,得到的時間是一樣的。用數學語言我們可以這樣表示:
6 - 3 = 6 +(12 - 3)
還有,我們可以發現把物體左轉60度,和把物體右轉300度的結果也是一樣的。
數字 87,減去 25,和加上 75,在不考慮百位數的條件下,效果也是相同的。
上述幾組數字,有這樣的關係:
  3+9=12
  60 + 300 = 360
  25 + 75 = 100
式中的 12、360 和 100,就是“模”。
式中的 3 和 3、60 和 300,以及 25 和 75,就是一對對“互補”的數字。

知道了“模”,求某個數字的“補數”,就是輕而易舉的了:
如果模為 365,數字 120 的補數為:365 - 120 = 245。

用補數代替原數,可把減法轉變為加法。出現的進位就是模,此時的進位,就應該忽略不計。

我們可以把減法理解成加一個負數。於是我們在計算減法時只要加上模減去這個負數的絕對值就可以得到正確的結果。
這樣就給我們在計算機中做減法提供了一個良好的思路。

二進位制的模
十進位制下,兩位數的模是100,三位數的模是1000,n位數的模式10n。在二進位制下,我們可以發現兩位數的模是100(十進位制的4)。模表示數字的容量和狀態,兩位二進位制能表示4個數。所以可以推出,n位二進位制的數的模式2n,也就是1後面有n個0。

如果是 3 位二進位制數參加運算,模就是 1000(2^3),即 1 的後面加上 3 個 0;
那麼當 8 位二進位制數參加運算,模就是 1 0000 0000(2^8),即 1 的後面加上 8 個 0。
16 位二進位制數參加運算,模可就大了,是 1 的後面加上 16 個 0。

二進位制的補碼
在計算機裡,數字、字串等等會被稱為“碼”,還有機器碼。那麼補數也就變個稱呼,顯得專業一點,我們稱之為補碼。
前面我們說了補碼的提出是為了解決減法計算的問題。所以在計算時,加法運算我們仍然按照原來的機器碼(原碼)進行計算。
我們一般是在8位二進位制的情況下討論補碼。
例如-3的原碼是10000011,其絕對值的原碼是00000011。那麼-3的補碼就是100000000-00000011=11111101。

總結

首先“補”和“模”的概念適用於像色相環、鐘錶這種有個環的事物,模就相當於那個環。十一點加一個小時就是零點,在8位二進位制的數字中,11111111加1就是00000000。當你忘了補碼的樣子,就想一想鐘錶吧。正是有了模,才有所謂的補。
其次在二進位制中,n位數的模就是2^n,也就是1後面有n個0。
負值在記憶體中以補碼形式存貯
負數X的補碼 = |X|按位求反+1
= X按拉求反(除符號位外)+1
= 模 - |X| (強調了補碼運算本質上是一種模運算,這就是稱其為“補碼”的緣由)
-128的補碼是10000000,等於128的原碼。


上面介紹瞭如何用模來求負數的補碼,下面我們來介紹是如何同matlab產生DSP所需的記憶體.dat檔案的

fs = 50;
t = 1/fs:1/fs:20;
k = 2;
A = 2sin(2pikt);
//產生資料【-2,2】採用十六位儲存的話用Q14定標

B = (4*(A<0)+A); //求出補碼(浮點數,還沒有最後轉化為相對應的定點數)其中4是十六位儲存時Q14定標下的模(二進位制100,4 = 2^(16-14)原本是16位儲存現在小數點左移了14位相當於只留下了2位)

C = (4*(A<0)+A)*2^14;//產生相應的定點數,浮點數與定點數的轉化

fid = fopen(‘test.dat’,‘wt’);
fprintf(fid,‘1651 1 0 0 0\n’);
fprintf(fid,‘0x%x\n’,C);
fclose(fid)
//上面程式碼為寫DSP所可以識別的.dat檔案,由於格式第二個資料為”1“所以DSP會以十六進位制整型數儲存所讀資訊32位,然而matlab中預設的fprintf是輸出16位,所以DSP讀取到資訊後會在前面16位全部置零,這樣我們的補碼的符號位資訊就失效了

這裡寫圖片描述

matlab寫出來的資料是這樣的,從圖中可以看出來十六進位制的第四位數表示的二進位制是第13~16位(第十六位是符號位),前12個數的第四位數都是小於8(1000)的所以可見這些數是正數,後面幾個是大於8的所以第十六位肯定是1所以他們是負數
但是如果對matlab的寫入程式不加修改的話DSP讀取之後儲存得到的資料是這樣的

這裡寫圖片描述

這樣的話DSP就都認為是正數了因為這些數的最高位第32位都是0。為了避免這個誤會,我們在做matlab的輸出時做了一些調整
就補碼而言,正數的補碼前面加多少0都不影響這個數真正表示的數例如0x1fd5表示的是8149,0x00001fd5也表示8149,唯一不同的就是第一種是十六位儲存的8149而第二種是32位儲存的8149,不影響所表示的數的值;對於負數而言正好相反,因為正數的補碼是其本身,而負數要數值位取反因此負數是其補碼前面不管加多少1都是不影響其實際存數的數的值的,例如0xeff5表示-4107,0xffffeff5表示的也是-4107,這個叫做補碼的符號拓展,實際上符號拓展不影響儲存資料的值,只是儲存資料的位數變化了。由於DSP要用32為存數所讀資料,因此我們要保證資料正確的前提下擴充套件到32位就用到了下面的語句:

D = ((A<0)*4294901760) +C;
4294901760用十六進位制表示是0xffff0000這樣的話再加上原來的十六位數就是相當於32位表示了,所以DSP讀取的資料就是
這裡寫圖片描述

根據前面的介紹,對於補碼來說正數做0符號位擴充套件負數做1符號位擴充套件不影響所表示資料的大小,只是說資料存數的位數變了,
利用CCSv3裡面的volume例項利用程式斷點,在斷點處從.dat檔案裡面讀取資料,然後在Tools的Graph裡面演示波形得到:

這裡寫圖片描述