李 飛,黃子牛
(石家莊機械化步兵學院 河北 石家莊 050083)
運動控制卡與PC機的接口主要有ISA總線和PCI總線兩種方式,由于ISA總線已基本被PC機所淘汰,而PCI總線則以其速度快、性能優等特點成為主流接口規范[1],因此目前運動控制卡多基于PCI總線設計。
實現PCI接口的方法主要有兩種:一是使用復雜可編程邏輯器件或現場可編程門陣列(如CPLD或FPGA),二是使用專用電路(如PCI9052或CH365),采用第一種方法盡管靈活性高且性能好,但成本較高;而第二種方法采用專用電路,雖然靈活性差,但性能尚可,成本較低,并且開發周期較短,能夠滿足科研開發的一般場合,因此本設計選用第二種方案。
PCI接口芯片選用南京沁恒公司推出的CH365,該器件完全符合PCI接口規范[2]。圖1為設計的運動控制卡的功能框圖,定時中斷設為4 ms,依據PCI總線上送來的數據,在每個中斷周期內由定時計數器輸出一定數量的方波信號,控制伺服電機單軸或四軸的擺動頻率,實現對內燃機的拖動;同時,該卡還對光電編碼器的反饋脈沖進行計數,以實現對伺服電機的閉環控制。伺服電機光電編碼器反饋信號經過高速光耦隔離后輸入GAL進行四倍頻處理,以提高反饋信號分辨率。

圖1 運動控制卡框圖Fig.1 Block diagram of motion control card
圖2 為部分原理圖,定時計數器U1、U2負責對輸入軸反饋脈沖計數,以判斷電機實際運行位置,U3、U4則對工作頻率進行分頻,在每一中斷周期輸出程序中設定頻率的方波,從而控制電機的擺動頻率,定時中斷信號由U4的定時器2產生,中斷信號與PCI總線的IRQ7相連,每一中斷周期為4 ms。

圖2 計數與分頻部分Fig.2 Count and frequency divider
為提高信號抗干擾能力,定時計數器輸出脈沖應經過差分處理,以“脈沖/方向”形式向伺服電機發出指令,設計中采用DS26C31對輸出信號進行差分發送;光電編碼器的反饋信號體現伺服電機的實際擺動頻率,對此信號除需差分處理外,還應進行整形、濾波等處理,以提高定時計數器對輸入信號的計數精度[3-4],設計中采用DS26C32對輸入信號進行差分接收。
圖3為研制的PCI總線運動控制卡,可實現四軸及單軸控制,每軸高達4 MPPS脈沖輸出、1 MHz編碼器輸入,該運動控制卡還具有以下特點:
1)實現基于32位PCI總線的從設備接口。
2)可設定PCI板卡的設備標示。
3)自動分配I/O基址,支持長度達240字節的I/O端口。
4)支持本地硬件定址功能,自由選擇I/O地址,在指定地址實現I/O端口。
5)轉換為主動并行接口:8位數據、16位地址、I/O讀寫。
6)4個16位定時/計數器。
7)脈沖輸出形式為上下或脈沖/方向。
8)通用的 Windows98/ME/2000/XP驅動程序,通過 DLL提供應用層API。

圖3 PCI總線運動控制卡Fig.3 Motion control card based on PCI bus
在使用PCI板卡之前,需要查找板卡并獲取其配置信息。計算機BIOS已經為PCI設備設定了合適的工作環境,而我們編寫程序的目的是為了使用此工作環境。
PCI設備有3個空間——內存地址空間、IO地址空間和配置空間。由于PCI支持即插即用,所以PCI設備不是占用固定的內存地址空間或I/O地址空間,而是可以由操作系統決定其映射的基址,這也就是配置空間的作用。
用于PCI板卡轉換的CH365芯片同時提供了基于DOS的開源驅動函數庫(包括 Ch365dos.c和 Ch365dos.h)和基于Windows的驅動程序及動態鏈接庫[5]。在 DOS系統和Windows 9X系統下編寫PCI板卡程序時,可以直接調用Ch365dos.c中的函數,實現對設備的驅動和控制。
調用Ch365dos.c中的CH365CheckDevice函數,檢查PCI設備是否存在,CH365CheckDevice內部使用int86函數,調用DOS的1AH中斷,即PCI BIOS中斷,輸入寄存器AH為固定值B1H,AL為02H時表示判斷指定設備是否存在。
printf( “Check PCI Device...” );
mPciAddr=CH365CheckDevice( );
if(mPciAddr==0)
{
printf(“Failed. ”);
return-1;
}
printf(“OK. ”);
獲取PCI設備標識和廠商標識,這兩個十六進制數代表此板卡區別于其他類型設備的唯一標志。CH365ReadCfgWord內部使用int86函數,調用DOS的1AH中斷,輸入寄存器AH為固定值B1H,AL為08H時表示讀取PCI設備配置空間的信息。配置空間中最重要的有:
Vendor ID:廠商ID。用來判斷PCI設備是否存在。
Device ID:設備ID。操作系統依據 Vendor ID和Device ID找到對應的驅動程序。
Class Code:類代碼。共三字節,分別是類代碼、子類代碼、編程接口。類代碼不僅用于區分設備類型,還是編程接口的規范。
IRQLine:IRQ編號。支持管理24個中斷源。
IRQ Pin:中斷引腳。PCI有4個中斷引腳,該寄存器表明該設備連接的是哪個引腳。
以下代碼用于讀取PCI配置空間中的設備標識和廠商標識:
mCfgID=CH365ReadCfgWord(0x00);
printf(“Vender ID:%04X. ”, mCfgID);
mCfgID=CH365ReadCfgWord(0x02);
printf(“Device ID:%04X. ”, mCfgID);
查找設備IO端口地址,獲取設備IO端口的基地址之后,可通過指定偏移地址的方法,向板卡相應的端口輸入或讀取數據。注意此處被注釋的函數CH365SetIoBaseAddr,在DOS系統下可以使用此函數自行指定一個IO基地址,但是Windows系統通常為硬件預設了IO基地址,用戶強制指定的地址往往起不到效果。
CH365GetIoBaseAddr內部使用int86函數,調用了DOS的1AH中斷,輸入寄存器AH為固定值B1H,AL為07H~09H時 分 別表 示 按 字 節 (BYTE), 字 (WORD) 和 雙 字(DWORD)讀取PCI設備配置空間的信息。
//CH365SetIoBaseAddr((mPCH365_IO_REG)0x200);
mIoBase=CH365GetIoBaseAddr();
iIoBase= (unsigned int)mIoBase;
printf( "IOBase Addr:%04X. ", iIoBase );
檢查和設定硬件中斷,使用函數CH365SetIntLine和CH365GetIntLine指定或讀取系統中保存的板卡中斷號。CH365SetIntLine內部使用int86函數,調用DOS的1AH中斷,輸入寄存器AH為固定值B1H,AL為0BH~0DH時分別表示按字節(BYTE),字(WORD)和雙字(DWORD)寫入到PCI設備配置空間。
注意此處被注釋的宏mCH365_INT_LINE_AUTO,它表示程序將使用缺省的中斷號。在DOS和Windows 9x環境中,也允許用戶自行指定中斷號,如下的代碼強行指定中斷號為7。
printf( “Set Interrput Line...” );
if(CH365SetIntLine(7/*mCH365_INT_LINE_AUTO*/)==FALSE)
{
mIntLine= -1;
printf( “Failed. ” );
}
else
{
printf( “OK. ” );
mIntLine=CH365GetIntLine();
}
printf( "Interrupt Line:%X. ", mIntLine);
中斷服務程序是具有特定格式的函數,為保證運動控制卡的正常工作,中斷服務子程序的編寫必不可少。
查找并設定設備中斷號,指定相應中斷服務程序,系統在收到設備的中斷信號時自動執行此函數的內容,如果不指定中斷服務程序,那么中斷將不會產生任何效果。
作為PCI板卡的前端設備,CH365控制中斷信號的發送,在執行中斷之前,應對mCh365IoCtrl發送控制字進行清零,否則可能無法開啟中斷。
mChipIoCtrl=inportb ( (USHORT) &mIoBase ->mCh365IoCtrl);
outportb ( (USHORT) &mIoBase ->mCh365IoCtrl,mChipIoCtrl&0xfb);
在DOS下,應向計算機系統申請打開中斷。此處假設中斷采用屏蔽中斷(INTR)的方式。PC機上的8088INTR中斷請求線與8259A中斷控制器的INT相連,而8259A有8個輸入端,可連8個外設,8259A接收來自外設的中斷請求信號,并把中斷源的類型號送給CPU[6]。從外設的中斷請求到CPU響應中斷有兩個控制條件起決定作用:
第一個條件,該外設中斷請求是否屏蔽,對于8259A中斷屏蔽寄存器IMR(口地址為21H)的某一位,若為0,則表示允許中斷;為1,該外設的中斷請求被屏蔽。
第二個條件,CPU是否允許中斷,即標志寄存器中IF是否等于1,若IF=0,CPU禁止中斷;IF=1,允許CPU響應中斷。
由此編寫代碼如下:
outportb(0x20, 0x20);
outportb(0x21, inportb(0x21) &0x7f); //IRQ7
此外,還應當注意PCI卡是如何產生中斷脈沖的,如果需要用戶向指定IO地址執行輸入才能夠觸發中斷,那么還需要編寫相應的板卡觸發代碼。
運行時系統將根據中斷周期自動進入中斷服務程序,中斷服務程序中必要的工作有:
檢查中斷信號是否來自此設備,因為其他的PCI設備可能產生同樣的中斷信號。
mChipIoCtrl=inportb ( (USHORT) &mIoBase ->mCh365IoCtrl);
if(mChipIoCtrl&0x04) ……
此次中斷執行完成之后,應編寫退出代碼,必要的退出代碼包括CH365控制位清零,以及向系統申請退出中斷服務程序。注意,如果缺少退出語句,或者中斷服務程序中用戶要執行的工作太多,則可能造成中斷套疊以至計算機死鎖。
outportb ( (USHORT) &mIoBase ->mCh365IoCtrl,mChipIoCtrl& ~0x04 );
if(mIntLine>=8)
{
outportb(0xa0,0x20 );
if(inportb(0xa0)==0)outportb(0x20,0x20);
}
else outportb(0x20,0x20 );
之后向計算機系統發出申請,退出中斷,也可以同時指定中斷服務程序為NULL。
outportb(0x21, inportb(0x21) |0x80);
運用國產芯片CH365,設計開發了一塊PCI總線的運動控制卡,并編寫了配套的驅動程序,經實際測試,伺服電機選用日本信濃公司的交流伺服電機,型號為5CB06-1SE,驅動器選用其配套的HO 10AB CB 600C 17 F型數字式交流伺服驅動器,可進行步進式及脈沖式伺服電機控制,并能充分發揮電機性能,方便地實現運動控制。
[1]阮毅,陳維鈞.運動控制系統[M].北京:清華大學出版社,2006.
[2]南京沁恒電子有限公司.PCI總線接口芯片CH365[EB/OL].(2005-12-21) http://wch.cn/download/list.asp?id=10.
[3]覃琴.基于FPGA的PCI接口運動控制卡的研究 [D].成都:四川大學,2006.
[4]林劍豪.基于CH365型接口和MCX314As型運動控制器的PCI總線運動控制卡設計[J].電子設計工程,2005(12):22-26.LIN Jian-hao.Designing of PCI bus motion controlling card based on CH365 and MCX314As[J].Electronic Design Engineering,2005(12):22-26.
[5]游林儒,龐永鵬,譚子瑜.基于PCI總線的四軸運動控制卡的研制[J].微計算機信息,2007,31(21):12-14.YOU Lin-ru,PANG Yong-peng,TAN Zi-yu.Research and design of 4-Aexs motion controller based on PCI bus[J].Microcomputer Information,2007,31(21):12-14.
[6]馬忠梅.單片機的C語言應用程序設計[M].3版.北京:北京航空航天大學出版社,2005.