前言
本筆記首先對DSP的特點及其選型進行了描述,然后重點記錄DSP開發環境的搭建及基礎工程示例,對為DSP開發新手有一定的指導作用。
1. DSP簡介
1.1 主要特點
- 在一個指令周期內可完成一次乘法和一次加法;
- 程序和數據空間分開,可以同時訪問指令和數據;
- 片內具有快速RAM,通常可通過獨立的數據總線在兩塊中同時訪問;
- 具有低開銷或無開銷循環及跳轉的硬件支持;
- 快速的中斷處理和硬件I/O支持;
- 具有在單周期內操作的多個硬件地址產生器;
- 可以並行執行多個操作;
- 支持流水線操作,使取指、譯碼和執行等操作可以重疊執行。
1.2 主要廠商
TI
- 面向數字控制、運動控制的TMS320C2000系列;
- 面向低功耗、手持設備、無線終端應用的TMS320C5000系列;
- 面向高性能、多功能、復雜應用領域的TMS320C6000系列
ADI
- 21xx系列:16位定點dsp,主要以218x和219x系列為代表,性能優異,內部RAM大,外圍接口多,適合作為控制類芯片使用;
- SigmaDSP:完全可編程的單芯片音頻DSP;
- blackfin系列:ADI最新推出的一款dsp,是高性能16位DSP信號處理能力與通用微控制器使用方便的性能結合;
- SHARC 系列:32位浮點dsp,包括前期的2106x系列,和目前的主力21160,21161系列,提供與大內存容量結合的簡單浮點算法,具有高水平的浮點性能;
- TigerSHARC系列:從SHARC系列發展而來,比SHARC具有更高的浮點運算功能;
其他
- Motorola:定點DSP 處理器MC56001,浮點DSP芯片MC96002;
- Freescale(Nxp):MSC8xx系列,DSP56Fxx;
國產
- 進芯電子:仿TI的c2000系列;
1.3 DSP性能參數
- 運算速度
- MIPS:百萬條指令/秒,定點DSP芯片運算速度的衡量指標。
- MOPS:百萬操作/秒,通常操作包括CPU操作外,還包括地址計算、DMA訪問數據傳輸、I/O操作等。一般說MOPS越高意味着乘積-累加和運算速度越快。MOPS可以對DSP芯片的性能進行綜合描述。
- MFLOPS:百萬次浮點操作/秒,這是衡量浮點DSP芯片的重要指標。
- ACS:指令周期,即執行一條指令所需的時間,通常以ns(納秒)為單位。
- FFT/FIR執行時間:運行一個N點FFT或N點FIR程序的運算時間,該指標可以作為衡量芯片性能的綜合指標。
- 運算精度
- 16位、32位定點:動態范圍小,需要注意定標及溢出,功耗低,成本低;
- 32位浮點:動態范圍大,編程相對簡單一些,功耗高;
1.4 DSP選型其他因素
- 外設、特定功能需求
如:同步/異步串口、A/D、D/A、以太網、音頻處理等; - 片內存儲
DSP片內存儲器可用來放程序和數據; - 封裝、功耗
一般定點功耗較低,當然也有低功耗版浮點dsp但其速度很低;
QFP封裝對底板要求較低,BGA封裝需求多層板;
初次選型建議:
最先考慮C2000系列,如果滿足需求,選型型號: TMS320F28335(支持FPU,150MHz,100元左右);
其次考慮C674X系列,如TMS320C6747(375~456-MHz,3648 MIPS and 2736 MFLOPS,100元左右);
2. DSP基礎開發
從初版學習開發考慮,建議選用TI的DSP,其資源和技術支持均非常成熟。
2.1 開發環境
TI
- 開發工具
CCS(Code Composer Studio),提供免費版本。 - 編程語言
匯編語言和C語言。 - 仿真器
XDS100、XDS110、XDS200、XDS560等,通常使用性價比較高的XDS100即可。 - 軟件庫
c2000系列:controlSUITE、C2000Ware(新版)
其他:有對應的sdk,如TMS320C6747,提供 PROCESSOR-SDK-C6747(包含TI-RTOS)
ADI
- 開發工具
VISUAL DSP++,提供90天測試版(正版2w左右,每個系列對應一個版本)。 - 編程語言
匯編語言和C語言。 - 仿真器
不同系列仿真器不同;
一般低性能版2000元左右; - 軟件庫
Technical Library
2.2 DSP開發環境搭建(TI)
本章搭建示例基於c2000系列,主要為裸機開發,資源有限不建議運行OS,其他系列可參考搭建。
CCS安裝
經實際測試ccs版本選擇應注意以下事項:
ccs版本較多,win10系統不支持ccs6以下的版本;
ccs6以上的版本去掉了軟件仿真功能;
ccs9版本只支持64位系統(該版本不能移植老版本的軟件仿真功能);
本文選擇安裝 ccs6
軟件庫安裝
最新ccs9版本推薦使用 c2000ware;
ccs9之前版本使用 controlSUITE;
CCS基礎工程示例
新建工程
新建一個基於TMS320F28335的工程,如下所示:
空工程組成介紹:
-
cmd文件
由於嵌入式DSP資源比較緊張,存在內部RAM、Flash 和外部RAM與Flash,需要人工干預來進行合理的資源分配;
鏈接配置文件,給出了程序空間和數據空間的設置,及編譯后各程序段在程序或數據空間的具體位置。類似於IAR的 icf文件和 keil 的sct文件。
一般ccs工程有兩個cmd文件,一個對寄存器進行存儲映射,一個是對Flash, Ram進行存儲分配。
上圖中的 28335_RAM_lnk.cmd 定義了程序、數據等在Ram上的分配,即程序運行與ram,通常用於仿真調試,一般情況下直接用TI給的,不需要做修改即可滿足調試用。
當程序需要下載固化時,選擇 F28335.cmd。
DSP2833x_Headers_nonBIOS.cmd 這個文件就是寄存器的存儲映射,當工程實際操作硬件時需要添加到工程中。
-
targetConfigs
仿真器的配置,直接雙擊文件選擇使用的仿真器和對應芯片型號即可,后面講述怎么添加軟件仿真器功能。
工程添加軟件庫
已安裝好 controlSUITE。
設備基礎軟件庫:D:\ti\controlSUITE\device_support\f2833x\v142;
- DSP2833x_common 文件夾:存放了DSP2833x 開發所需的外設、內核、DSP運算庫、CMD 等文件。
- DSP2833x_headers 文件夾:存放了DSP2833x 開發所需的外設頭文件、帶和不帶BIOS CMD 等文件。
其他的應用庫到時按需添加。
下面我們移植官方軟件庫實現簡單的GPIO控制功能。
在工程目錄下面 DSP2833x_Libraries 文件夾,用於存放從controlSUITE中拷貝出來的庫文件。
將 DSP2833x_common 和 DSP2833x_headers 拷貝到 DSP2833x_Libraries目錄中。
在工程中新建 APP(用戶應用驅動),User(用於程序),Libraries(官方庫),cmd等文件夾
最小工程所需文件按下圖所示添加到工程中
工程頭文件路徑包含
GPIO反轉程序編寫
#include"DSP2833x_Device.h" //芯片型號、外設使能相關宏定義
#include"DSP2833x_Examples.h" //
/**
* @brief LED使用GPIO外設初始化
*/
void LED_Init(void)
{
EALLOW; //關閉寫保護
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 開啟GPIO時鍾
//LED1端口配置
GpioCtrlRegs.GPCMUX1.bit.GPIO68=0; //設置為通用GPIO功能
GpioCtrlRegs.GPCDIR.bit.GPIO68=1; //設置GPIO方向為輸出
GpioCtrlRegs.GPCPUD.bit.GPIO68=0; //使能GPIO上拉電阻
GpioDataRegs.GPCSET.bit.GPIO68=1; //設置GPIO輸出高電平
EDIS; //開啟寫保護
}
/*
* @brief 主程序
*/
void main(void)
{
InitSysCtrl(); //系統時鍾初始化,默認已開啟F28335所有外設時鍾
LED_Init();
while(1)
{
GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;//設置GPIO輸出翻轉信號
DELAY_US(1000);
}
}
編譯沒有錯誤,基礎工程搭建成功。
CCS6添加軟件仿真功能
本方法適用於從 ccs6-ccs8.
1.下載仿真功能文件
鏈接: https://pan.baidu.com/s/1eZT7SGoGIRRsxPYCOLz3Xw 提取碼: z94n
2.拷貝文件到ccs指定位置
找到CCS安裝路徑,將網盤中的simulator文件夾復制到CCS安裝路徑中的ccs_base文件夾內;
將網盤中的configurations文件夾復制到ccs_base\common\targetdb\文件夾下;
將網盤中的tisim_connection.xml復制到ccs_base\common\targetdb\connections\文件夾下;
將網盤中的devicer文件夾中的內容復制到安裝路徑ccs_base\common\targetdb\drivers\文件夾下;
重新打開ccs,即可為工程配置軟件仿真如下:
接下來工程就支持軟件仿真了,當然涉及到外設相關操作時會出錯(比如ADC采集)。
2.3 DSP運算仿真實驗
專業術語
功能術語
- FPU:Float Point Unit,浮點運算單元;
- FixedPoint:定點;
- VCU:Viterbi and complex unit,用來執行高效 Viterbi、復雜算術運算,16 位快速傅里葉變換 (FFT) 和 CRC 算法的加速器;
- CLA: 控制律加速器,把一些與控制系統性能息息相關的代碼放到CLA中獨立運行,不占用CPU時間;
庫術語
- RTS:實時運行庫,DSP編程開發,則RTS庫提供C/C++代碼的運行環境,不同功能可能需要選擇器對應的rts庫;
- SGEN:信號產生庫;
數學術語
- DFT:離散傅里葉變換;
- FFT:快速傅里葉變換,是離散傅立葉變換的快速算法;
- CFFT:對復數進行fft變換;
- RFFT:對實序列進行fft變換;
- FIR濾波器:Finite Impulse Response 有限脈沖響應濾波器;
- IIR濾波器:無限沖激響應濾波器;
正弦函數仿真顯示
測試代碼如下
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "math.h"
#define PI 3.1415926 //定義圓周率
#define Fs 1000 //定義采樣頻率 Hz
#define F1 100 //信號頻率 Hz
#define F2 20
#define Sample_points 1024 //采樣點數
float signal1[Sample_points];
float signal2[Sample_points];
int main(void)
{
int i;
float t;
for(i=0;i<Sample_points;i++)
{
t = i*1.0/Fs;
signal1[i] = sin(2*PI*F1*t);
signal2[i] = sin(2*PI*F2*t);
}
while(1);
}
很簡單的一段代碼,大致意思就是生成了兩個不同頻率的正弦信號,分別保存在了數組signal1和signal2中。
下面我們通過軟件仿真功能將代碼運行起來,同時同步graph工具圖形化顯示函數計算數據。
Graph設置如下:
運行程序,顯示效果如下
接着我們看其傅里葉變換,Graph提供直接生成fft功能,點擊菜單欄Tools->Graph->FFT Magnitude,如圖所示:
正玄函數fft變換顯示如下:
DSP函數庫實現RFFT
這一節將需要進行稍微復雜一點的操作,涉及到變量存儲的分配及cmd文件修改,FFT計算原理,函數庫及其運行支持庫的設置,CFFT相關庫函數等知識點。
#pragma DATA_SECTION
利用CCS進行DSP編程時,如果不指定變量的存儲位置,那么編譯器會自動給變量分配存儲位置。但是,有些時候,需要將某個變量存放到某個特定的位置,這個時候就可以利用#pragma DATA_SECTION指令了。
如進行CFFT和ICFFT都要求輸入的數組格式對齊,即變量存儲的起始地址為2xFFTsize*sizeof(float),例如256點的FFT變換,則變量的起始地址必須是1024的倍數,格式對齊的方式利用變量定義的方式進行。
如:
#pragma DATA_SECTION(RFFTin1Buff, "RFFTdata1");
float32 RFFTin1Buff[RFFT_SIZE];
定義 RFFTin1Buff 數組到 RFFTdata1的RAM段;
RFFTdata1再cmd文件中進行RAM分配,后面實例代碼中進行說明。
#pragma CODE_SECTION
利用#pragma CODE_SECTION指令可以將程序從Flash搬到RAM中運行,從而提高程序執行速率。
這個部分后面涉及程序優化時再進行詳細描述。
RFFT工程實例
1.拷貝dsp FPU運算庫到工作區間,便於工程引用;
2.給工程添加dsp FPU運算庫,從controlSUITE拷貝;
3.FPU庫頭文件路徑引用及編譯器相關設置
選擇fpu運行庫
FPU頭文件路徑添加
示例程序:
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "math.h"
#include "float.h"
#include "FPU.h" //dsp 浮點運算庫
#define RFFT_STAGES 8 //RFFT運算階數
#define RFFT_SIZE (1 << RFFT_STAGES)
#pragma DATA_SECTION(RFFTin1Buff,"RFFTdata1"); //Buffer alignment for the input array,
float32 RFFTin1Buff[RFFT_SIZE]; //RFFT_f32u(optional), RFFT_f32(required)
//Output of FFT overwrites input if
//RFFT_STAGES is ODD
#pragma DATA_SECTION(RFFToutBuff,"RFFTdata2");
float32 RFFToutBuff[RFFT_SIZE]; //Output of FFT here if RFFT_STAGES is EVEN
#pragma DATA_SECTION(RFFTmagBuff,"RFFTdata3");
float32 RFFTmagBuff[RFFT_SIZE/2+1]; //Additional Buffer used in Magnitude calc
#pragma DATA_SECTION(RFFTF32Coef,"RFFTdata4");
float32 RFFTF32Coef[RFFT_SIZE]; //Twiddle buffer
float RadStep = 0.1963495408494f; // Step to generate test bench waveform
float Rad = 0.0f;
RFFT_F32_STRUCT rfft;
void main(void)
{
Uint16 i;
// InitSysCtrl(); //沒有硬件支撐時,予以注銷
DINT;
// InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
// InitPieVectTable();
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// 清空輸入緩存
for(i=0; i < RFFT_SIZE; i++)
{
RFFTin1Buff[i] = 0.0f;
}
// 測試樣例波形
Rad = 0.0f;
for(i=0; i < RFFT_SIZE; i++)
{
RFFTin1Buff[i] = sin(Rad) + cos(Rad*2.3567); // 實部輸入信號
Rad = Rad + RadStep;
}
rfft.FFTSize = RFFT_SIZE; // FFT變換的長度,FFTSize=2^stage
rfft.FFTStages = RFFT_STAGES; // 傅里葉變換的階數
rfft.InBuf = &RFFTin1Buff[0]; // 輸入數組
rfft.OutBuf = &RFFToutBuff[0]; // 輸出數組
rfft.CosSinBuf = &RFFTF32Coef[0]; // 轉化因子數組
rfft.MagBuf = &RFFTmagBuff[0]; //
RFFT_f32_sincostable(&rfft); // 計算傅里葉變換的轉化因子 Calculate twiddle factor
for (i=0; i < RFFT_SIZE; i++)
{
RFFToutBuff[i] = 0; //Clean up output buffer
}
for (i=0; i < RFFT_SIZE/2; i++)
{
RFFTmagBuff[i] = 0; //Clean up magnitude buffer
}
RFFT_f32(&rfft); //實數傅里葉變換
RFFT_f32_mag(&rfft); //計算幅值 Calculate magnitude
for(;;);
} //End of main
上面示例程序中使用 #pragma DATA_SECTION 定義了一些數組到RAM段,這些RAM段須在cmd文件中定義分配。
設置仿真器為軟件仿真器,編譯程序沒有錯誤,然后運行。
設置Graph及數據波形顯示如下:
樣例輸入波形:
RFFT變換之后的波形:
2.4 DSP常用外設
待續......
3. DSP進階開發
本章開發基於TMS320C6748,運行TI-RTOS.
3.1 術語介紹
- RTSC:Real-Time Software Component,實時軟件組件。RTSC是一個基於C的編程模型,用於開發創建或實施嵌入式平台實時軟件組件。
- XDC:eXpress DSP Components,是一個為嵌入式實時系統提供可重用組件(稱作:包)的標准。
- XDCtools:包含使用RTSC的工具和運行時組件,提供了TI-RTOS及其組件(包括SYS/BIOS)需要的底層核心工具。 其功能如同Linux開發中發編譯工具鏈。
總體來說就是TI提供XDC標准的SDK(里面包含如函數庫、BIOS、DSP庫等),通過XDCtools進行編譯,整體以包的形式操作,而無需添加c文件到工程中。
理解CCS的這個工程框架,有利於工程的搭建。
3.2 C6748工程搭建
工程環境
ti-processor-sdk-rtos-omapl138-lcdk-05.03.00.07
這個組合經測試正常,因為使用TI的sdk需要考慮到 ccs、XDCtools、及sdk三者的版本匹配問題,否則程序無法正確編譯。
很遺憾的是首先老版本軟件仿真器不支持C6748芯片,CCS8.3更是運行軟件仿真器出錯,如需深入調試還是需要硬件支持來調試功能。
工程創建
-
CCS添加sdk包
Window-->Preferences-->Code Composer Studio-->Products
點擊Add,添加我們安裝的sdk軟件包
我們會看到下面會出現我們芯片所需要的軟件包,點擊Apply,然后ccs會提示安裝sdk里面包含的包,安裝完成后ccs重啟。
-
新建SYS/BIOS工程
File-->New-->CCS Project
選擇工程需要的組件
這樣一個基礎的RTOS工程就創建完成,程序編譯正常。