時間:2014-07-30 17:12:36來源:萬有盛 朱路群
關鍵詞:TI:美國德州儀器公司
DSP:泛指TI生產的數字處理器芯片,此處專指TI生產的TMS2803x系列芯片
FLASH:電可擦除只讀存儲器
OTP:一次可編程存儲器
RAM:DSP內部的讀寫存儲器
眾所周知,美國德州儀器(TI)公司的DSP芯片28xx系列由于其優(yōu)異的性能、強大的功能和極高的可靠性廣泛應用于電機控制領域,筆者也在對這款芯片的開發(fā)應用中有不少心得在這里提出來與大家共同探討一下。本次先討論一下對這款芯片的引導程序部分的個人見解。
關于該類芯片的存儲器的地址分配很多資料都有詳細介紹這里不覆訴,下面先看看該類芯片出廠固化的部分的程序或數據空間的分配:
看上述表格可以得知默認的情況下當CPU復位時會自動跳轉到0X3FFFC0處執(zhí)行程序,同時看到該處的空間只有64個字的空間而每個向量都占用會兩個字空間,所以0X3FFFC0到0X3FFFFF處可以放下32個中斷向量,但TI只用了其中16個,按順序包含“RESET”、“INT1…INT14”,“DLOGINT”等。其中最重要的一個矢量就是CPU復位矢量RESET占用0X3FFFC0、0X3FFFC1這兩個字的地址,一般這里放的都是跳轉到用戶主程序的執(zhí)行代碼:
WD_DISABLE.set1
.ref_c_int00
.globalcode_start
.sect"codestart"
code_start:
.ifWD_DISABLE==1
LBwd_disable
.else
LB_c_int00
.endif
.ifWD_DISABLE==1
.text
wd_disable:
SETCOBJMODE
EALLOW
MOVZDP,#7029h>>6
MOV@7029h,#0068h
EDIS
LB_c_int00
.endif
.end
以上是TI公布的標準的一段啟動代碼,“code_start”代碼段被“*.cmd”文件定位于0X3FFFC0地址處。可以看到該段代碼是用匯編編寫的,條件編譯偽指令使得:若用戶想禁用看門狗就在最前面定義WD_DISABLE常量為1,編譯后0X3FFFC0處就編譯為“LBwd_disable”語句,將執(zhí)行完關掉看門狗代碼段后跳轉到“_c_int00”處,否則若定義WD_DISABLE=0的情況,地址0X3FFFC0處直接編譯為“LB_c_int00”。稍微留意一點可以發(fā)現:兩種編譯方式最終結果都要跳轉到“_c_int00”處,這個“_c_int00”就是主程序main()的首地址,當然用戶也可以用匯編編寫一個用“_c_int00”申明首地址的匯編代碼處。當然,若用戶即申明了以“_c_int00”為名稱的匯編段,而且即使有main()為主程序的C源代碼段也不矛盾,執(zhí)行完“_c_int00”代碼段后執(zhí)行一個“LB_main”指令,編譯后也是能跳轉到主程序處的。
0X3FFFC2~0X3FFFDE的其他的向量在ENPIE標志(PIECTRL寄存器中的位)為0時才真正有效,實際使用中這些向量大家都會放到PIE的向量表里,由于PIE向量表位于RAM區(qū),這樣做有利于增加中斷響應的速度,所以這些向量這里不做詳細敘述。
其實,并非CPU復位總是從0X3FFFC0處開始執(zhí)行,它有一個這樣的過程:CPU復位時真正的PC值是指向0X3FF8A1處,該處將執(zhí)行一段廠家固化的代碼然后檢查TRST引腳和GPIO的引腳決定進入那種引導模式,下面討論一下2803X的復位后的工作順序:
第一步:初始化各標志位:VMAP=1,OBJMODE=0,AMODE=0,M0M1MAP=1;
第二步:初始化主時鐘控制寄存器,將廠內優(yōu)化的ADC偏置值和ADC的REF值寫入ADC相應寄存器以提高ADC轉換精度;
第三步:初始化仿真寄存器、外設時鐘寄存器,初始化引腳電平弱上拉,初始化AIO引腳為ADC;
第四步:判斷TRST引腳是否為1:
是-則代表仿真器已連接,若EMU_KEY和EMU_MODE位都無效則等待用戶設置這兩個位,用戶設置后進入不同的引導狀態(tài),進入第五步B;
否-則代表仿真器未連接,檢查兩個GPIO引腳的狀態(tài),進入不同的引導狀態(tài)進入第五步A。
第五步A:GPIO選擇引導狀態(tài)表如下:
注:1等待模式:2803X只是進入ROM死循環(huán),其他的C2000芯片這里不討論。
2:獲取模式:在默認情況下,只要OTP_KEY寄存器不等于0x55AA或者OTP_BMODE寄存器無效,程序跳轉至0X3FFFC0處執(zhí)行。
從以上可以看出用于電機驅動的
第五步B:仿真引導模式見下表:
以上都有一種“獲取模式”該模式詳細內容見下表:
可以看到CPU重上電或硬件復位時都要經過以上過程而我們常用的都是基于FLASH的引導運行,仿真也是這樣除非小程序會載入RAM運行,而用于電機驅動的程序由于功能需要越來越多,它們都不是小程序所以這里重點討論FLASH的引導問題。
很多使用DSP的用戶認為:DSP讀取FLASH時需要等待周期,而讀RAM時卻不需要等待,所以認為把程序載入到RAM里運行才能發(fā)揮DSP的最高效率,這種想法固然有一定的道理但是當程序量遠遠超過DSP的RAM容量時載入無法使用,更何況電機控制要占用很大的數據RAM空間,若分段載入執(zhí)行還不如直接在FLASH內執(zhí)行來的快。
其實TI公司早就考慮到FLASH的等待時間問題,使用了所謂“管道”技術,即一次從FLASH按順序載入64字(一頁)的指令到流水線,除了發(fā)生轉移而不必考慮FLASH的等待時間影響了DSP的運行速度。但是默認情況下CPU上電或復位時是關掉“管道”功能且等待時間都設到最大,這就要用戶根據芯片具體型號重新設定FLASH的工作模式,下面看一段TI公布的標準代碼:
voidInitFlash(void){
EALLOW;
FlashRegs.FPWR.bit.PWR=3;//FLASH電源正常打開—最大
FlashRegs.FOPT.bit.ENPIPE=1;//管道模式使能
FlashRegs.FBANKWAIT.bit.PAGEWAIT=1;//頁讀取等待時間
FlashRegs.FBANKWAIT.bit.RANDWAIT=1;//隨機讀取等待時間
FlashRegs.FOTPWAIT.bit.OTPWAIT=1;//一次可編程OTP讀取等待時間,未用可不設
FlashRegs.FSTDBYWAIT.bit.STDBYWAIT=0x01FF;//電源組泵從待機到激活的等待時間
FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT=0x01FF;//FLASH從待機到激活的等待時間
EDIS;
asm("RPT#7||NOP");//設置完成需等待一段空操作時間
}
代碼中,關鍵動作步驟是:
1.打開電源;
2.打開管道模式;
3.設置頁讀取等待時間(查看芯片具體型號的資料);
4.設置隨機讀取等待時間(查看芯片具體型號的資料);
5.等待一段空操作周期;
其他部分可以不必設置,默認情況已經設置完成。
需要注意的是FLASH的寄存器操作代碼是不能放在FLASH空間來執(zhí)行的,否則會造成意外情況如:CPU復位等,那系統(tǒng)是怎么做的呢?看看以下TI公布的標準代碼:
voidMemCopy(Uint16*SourceAddr,Uint16*SourceEndAddr,Uint16*DestAddr)
{
while(SourceAddr
{
*DestAddr++=*SourceAddr++;
}
return;
}
#pragmaCODE_SECTION(RAM_InitFlash,"ramfun");//“ramfun”被定義在RAM處
voidRAM_InitFlash(void)//預留空程序以方便拷貝
{;
}
而在主程序中:
//……
MemCopy((Uint16*)&InitFlash,(Uint16*)&ServiceDog,(Uint16*)&RAM_InitFlash);//“InitFlash()”函數結束位置定義了“ServiceDog”段
RAM_InitFlash();
//……
通過以上代碼可以看到:先將FLASH的InitFlash()函數段全部拷貝到RAM里,然后調用該段RAM函數就完成了FLASH的寄存器操作。當然這里需要特別注意“*.CMD”文件中對兩段程序段的地址重定義。
以上介紹了C環(huán)境下的FLASH的設置,但是筆者認為:雖然TI的編譯系統(tǒng)CCS對C和C++都支持,但是由于編譯器不能靈活應用全部的DSP指令,所以要編一個效率高節(jié)省資源的好程序還是要應用匯編指令編程。這里隨便舉個例子進行對比,例子的作用是判斷某標志位Sign的bit0是否置位,若置位則調用一段子程序Subroutine()然后清除該位,下面看看兩種方法效率的對比:
C++程序:
//申明變量:
structBIT
{
Uint16Bit0:1;
Uint16Bit1:1;
Uint16Bit2:1;
Uint16Bit3:1;//寫完成延時:完成
//……
};
unionSIGN
{unsignedintall;
structBITbit;
};
main()
{//……
externvoidSubroutine(void);
unionSIGNSign;
//……
if(Sign.bit.Bit0)
{Sign.bit.Bit0=0;
Subroutine();
}
//……
}
該段程序經過CCS編譯后看一看該段程序反匯編的結果:
“MOVZDP,#0X200
TBIT@0X12,#0
SBFC$DW$L$_main$37$E,NTC
TCLR@0X12,#0
LCR_Subroutine
”
匯編程序:
MOVZDP,#0X200
TCLR@Sign,#0
XCALL_Subroutine,TC
可以看到存儲空間C編譯結果占:13個字,匯編的結果占9個字,而執(zhí)行速度:若條件為假C的編譯結果為6個時鐘,流水線打斷指令預取可能需重裝;匯編占用6個周期,無打斷流水線的操作。若條件為真,不包含調用函數部分但包含返回:C編譯結果需要19個(加上LRET的8個時鐘)時鐘,而匯編需要16個(加上XRET的7個時鐘)時鐘,二者都有打斷了流水線的操作。而打斷流水線的話以前預取的指令就可能丟掉,重新在新地址預取指令,可以看到不管是從節(jié)省占用存儲空間的角度還是從執(zhí)行速度的角度都是匯編產生的結果來的優(yōu)越,特別是像判斷一個條件決定放那個數到變量的情況匯編可以利用如“MOV@DATA,AL,GT”等條件存儲指令而不用跳轉以致打亂流水線使“命中率”提高以提高指令執(zhí)行效率,而且代碼的長度也會縮小,諸如此類就不一一例舉了。
別看以上的例子好像優(yōu)勢不是很大,但是當程序足夠大,足夠復雜時產生的總和就相當可觀,正因為如此所以下面再談一談匯編組成的FLASH控制寄存器初始化的例子:
MOVLXAR0,#8000H
MOV*XAR0++,#2800H;mov@0a80h,#1
MOV*XAR0++,#1H
MOV*XAR0++,#2806H;mov@0a86h,#0
MOV*XAR0++,#0101H
MOV*XAR0++,#2807H;mov@0a87h,#1
MOV*XAR0++,#1H
MOV*XAR0++,#0F6FFH
MOV*XAR0++,#7700H;RPT#7||NOP
MOV*XAR0++,#07H
MOV*XAR0++,#06H;7614h=lret
MOVZDP,#_FLASH
LC#8000H
以上代碼直接將初始化FLASH寄存器的機器碼寫入至從0x8000地址開始的RAM空間而后直接調用,程序短小精悍執(zhí)行速度快。
經過以上引導處理就可以高效的執(zhí)行用戶代碼了,下面再看看引導區(qū)里還有那些其他比較重要的內容:
一.IQmath表
1:正弦/余弦表,對于電機控制而言該表最為重要,開始地址為0x3FE000,長度為1282個字,為長整型Q30格式,所以每個數據占用兩個字的空間,0~511個數據相對于0~360度的正弦值,后面還有90度(128個數據)的數據,這樣只要用戶將角度值加90度(π/2)查表就能非常方便獲得余弦值而再查余弦值時無需重復考慮溢出問題。
2:歸一化反轉表,使歸一化反轉計算過程收斂更快。
3:歸一化平方根表,使開方計算收斂更快。
4:還有反正切、舍入飽和表等等表此處不一一介紹了。
二.片上引導ROMIQmath函數:包含常用的有:開方運算、反正切運算、等等。
總結:
一.DSP由于其復位后引導方式的特殊性所以我們通常使用FLASH運行程序的用戶應該注意以下幾點:
1:硬件上GPIO37和GPIO34引腳要保證上電時為高電平狀態(tài),最好將懸空或其設計為輸出引腳使用以保證電平的確定性;
2:軟件上需要初始化FLASH的寄存器,把DSP效率提升到最高。
3:其他外設也要根據芯片參數盡量的提高芯片性能,如初始化PLL、PWM等寄存器,限于篇幅且其他資料詳盡這里就不介紹了。
二:編程時注意的效率提升:
1:盡量使用效率高的指令,能一條指令完成的不用兩條,如:乘和加直接用乘加指令,取數和移位直接用移位取數指令,檢測某位和置位某位直接置位標志就會檢測原來的位……諸如此類等等;
2:盡量不打斷流水線,盡量減少跳轉語句,熟練使用條件置數、條件調用、MAX、MIN等指令就可以做到這點。
3:程序跳轉時盡量使用短跳轉如SBF、BF等指令提高跳轉速度,當然這要看需跳轉的位置地址的距離。
標簽:
上一篇:冷媒技術在防爆變頻器上的應用
中國傳動網版權與免責聲明:凡本網注明[來源:中國傳動網]的所有文字、圖片、音視和視頻文件,版權均為中國傳動網(www.wangxinlc.cn)獨家所有。如需轉載請與0755-82949061聯系。任何媒體、網站或個人轉載使用時須注明來源“中國傳動網”,違反者本網將追究其法律責任。
本網轉載并注明其他來源的稿件,均來自互聯網或業(yè)內投稿人士,版權屬于原版權人。轉載請保留稿件來源及作者,禁止擅自篡改,違者自負版權法律責任。
產品新聞
更多>2025-05-19
2025-04-30
性能躍升20%!維宏NK300CX Plus數控系統(tǒng)...
2025-04-11
2025-04-08
2025-03-31
應用案例 | 使用宏集TELE監(jiān)控繼電器監(jiān)控...
2025-03-26