楊 碩,沈振軍
(上海大學(xué)機(jī)電工程及自動(dòng)化學(xué)院,上海 200072)
?
基于Linux的步進(jìn)電機(jī)嵌入式控制系統(tǒng)
楊 碩,沈振軍
(上海大學(xué)機(jī)電工程及自動(dòng)化學(xué)院,上海 200072)
對(duì)現(xiàn)有的基于單片機(jī)的控制系統(tǒng)作出改進(jìn),采用ARM9+Linux架構(gòu)設(shè)計(jì),以Linux2.6.32內(nèi)核作為操作系統(tǒng),根據(jù)步進(jìn)電機(jī)工作原理開(kāi)發(fā)驅(qū)動(dòng)程序模塊,利用QtEmbedded-4.8.5-arm設(shè)計(jì)控制界面程序,通過(guò)觸摸屏實(shí)現(xiàn)對(duì)步進(jìn)電機(jī)的控制。系統(tǒng)可以獨(dú)立完成控制,并記錄保存系統(tǒng)工作的數(shù)據(jù)信息,具有良好的移動(dòng)性和穩(wěn)定性,可以實(shí)現(xiàn)步進(jìn)電機(jī)組的數(shù)字化和可視化控制。
步進(jìn)電機(jī);Linux;驅(qū)動(dòng)程序;Qt
以應(yīng)用為中心的嵌入式系統(tǒng),藉由軟硬件的可裁剪性,實(shí)時(shí)性和可靠性等優(yōu)點(diǎn),已成為目前熱門(mén)的計(jì)算機(jī)應(yīng)用技術(shù)[1];Linux是一種具有開(kāi)放性、支持多用戶(hù)多任務(wù)、設(shè)備獨(dú)立性、出色的處理速度、可靠地系統(tǒng)安全和良好的可移植性的操作系統(tǒng),其內(nèi)核可根據(jù)具體應(yīng)用需求作出裁剪,這使得基于Linux的嵌入式應(yīng)用系統(tǒng)被廣泛應(yīng)用到各個(gè)領(lǐng)域中。
系統(tǒng)為“神光Ⅱ”項(xiàng)目中晶源片調(diào)整架控制系統(tǒng)升級(jí),以ARM9+Linux為架構(gòu),LCD作為輸出顯示設(shè)備,電阻式觸摸屏作為輸入設(shè)備,通過(guò)控制多組步進(jìn)電機(jī)的轉(zhuǎn)動(dòng)達(dá)到控制調(diào)整架的姿態(tài)的目的,此外,開(kāi)發(fā)基于QT的圖形界面實(shí)現(xiàn)可視化操作。
系統(tǒng)硬件結(jié)構(gòu)如圖1所示。采用基于ARM920T內(nèi)核的S3C2440A微處理器作為控制系統(tǒng)的中央控制器,由它產(chǎn)生的步進(jìn)電機(jī)的控制信號(hào),通過(guò)信號(hào)處理模塊的隔離和放大后實(shí)現(xiàn)對(duì)步進(jìn)電機(jī)的控制,同時(shí)傳感器模塊實(shí)時(shí)的檢測(cè)步進(jìn)電機(jī)的實(shí)際轉(zhuǎn)動(dòng)步數(shù),反饋給處理器;系統(tǒng)的存儲(chǔ)模塊由256MB的NAND Flash(掉電非易失)+64MB SDRAM組成;整個(gè)控制過(guò)程通過(guò)觸摸屏實(shí)現(xiàn),7寸LCD用以控制界面圖形的顯示和結(jié)果的反饋;通過(guò)通訊接口模塊實(shí)現(xiàn)與系統(tǒng)外的通訊,JTAG口和串口用于操作系統(tǒng)的安裝調(diào)試,10 M/100 M以太網(wǎng)接口用于連接網(wǎng)絡(luò),實(shí)現(xiàn)遠(yuǎn)程通訊,USB口在系統(tǒng)開(kāi)發(fā)過(guò)程中用于完成NFS服務(wù)和連接U盤(pán)完成數(shù)據(jù)交換;電源模塊為以處理器為中心的弱電區(qū)提供3.3 V電壓,為以步進(jìn)電機(jī)為主的強(qiáng)電部分提供24 V電壓。
圖1 系統(tǒng)結(jié)構(gòu)圖
系統(tǒng)搭載運(yùn)行的Linux操作系統(tǒng)的內(nèi)核版本號(hào)為2.6.32.2,運(yùn)行make menuconfig裁剪定制系統(tǒng),根據(jù)實(shí)際情況配置相關(guān)選項(xiàng),安裝必要的設(shè)備驅(qū)動(dòng),配置yaff2s、NFS和FAT文件系統(tǒng),最后生成定制的內(nèi)核鏡像文件ZImage.bin;利用mkyaffs2image-128M制作yaffs格式的根文件系統(tǒng)root.img映像文件。
2.1 Linux下的設(shè)備驅(qū)動(dòng)程序
如圖2所示,設(shè)備驅(qū)動(dòng)程序是Linux內(nèi)核的重要組成部分,Linux內(nèi)核將所有的硬件設(shè)備通過(guò)相應(yīng)的設(shè)備驅(qū)動(dòng)程序映射成文件,對(duì)用戶(hù)空間的應(yīng)用程序而言,系統(tǒng)內(nèi)核隱藏了設(shè)備的具體細(xì)節(jié),而把硬件設(shè)備當(dāng)做文件進(jìn)行處理,應(yīng)用程序可以像操作普通文件一樣對(duì)硬件設(shè)備進(jìn)行操作,設(shè)備驅(qū)動(dòng)程序需要提供應(yīng)用程序操作接口,如open、read、write、ioctl、close[2]。應(yīng)用程序發(fā)出系統(tǒng)調(diào)用命令后,從用戶(hù)態(tài)轉(zhuǎn)到內(nèi)核態(tài),通過(guò)內(nèi)核將open()等系統(tǒng)調(diào)用轉(zhuǎn)換成對(duì)物理設(shè)備的操作。
圖2 Linux操作系統(tǒng)結(jié)構(gòu)圖
設(shè)備驅(qū)動(dòng)程序充當(dāng)了硬件和應(yīng)用軟件之間的紐帶,讓軟硬件在一定程度上各自獨(dú)立,應(yīng)用軟件工程師只需要調(diào)用操作系統(tǒng)提供的API就可以控制硬件。
2.2 步進(jìn)電機(jī)驅(qū)動(dòng)程序需求分析
在非超負(fù)載的情況下,電機(jī)的轉(zhuǎn)速、停止的位置只取決于脈沖信號(hào)的頻率和脈沖數(shù),而不受負(fù)載變化的影響,所以在驅(qū)動(dòng)程序中間只需要考慮這兩個(gè)方面的影響。
以單個(gè)三相六拍步進(jìn)電機(jī)的驅(qū)動(dòng)程序?yàn)槔帉?xiě)驅(qū)動(dòng)程序,控制信號(hào)由S3C2440A的GPIO口直接生成,相應(yīng)的S3C2440A的引腳資源和步進(jìn)電機(jī)的三相接頭的對(duì)應(yīng)分配情況如表1所示。
表1 三相接頭對(duì)應(yīng)S3C2440A引腳資源
三路脈沖輸出信號(hào)由GPB數(shù)據(jù)寄存器(硬件地址0x56000014)的bit5~bit7控制,bit5對(duì)應(yīng)MOTOR_A,bit6 對(duì)應(yīng)MOTOR_B,bit7 對(duì)應(yīng)MOTOR_C.
步進(jìn)電機(jī)正轉(zhuǎn)時(shí)三相的導(dǎo)電控制順序狀態(tài)的為:A-AB-B-BC-C-CA,反轉(zhuǎn)時(shí)三相的導(dǎo)電控制順序?yàn)椋篊A-C-BC-B-AB-A.六拍對(duì)應(yīng)的GPBDAT寄存器值分配表如表2 所示。
表2 六拍對(duì)應(yīng)GPBDAT寄存器值分配
系統(tǒng)中電機(jī)只需要響應(yīng)應(yīng)用程序傳送給驅(qū)動(dòng)的步進(jìn)量和轉(zhuǎn)向參數(shù),順序地進(jìn)行控制操作,因此它可作為字符設(shè)備來(lái)進(jìn)行驅(qū)動(dòng)[3]。
2.3 步進(jìn)電機(jī)驅(qū)動(dòng)程序編寫(xiě)[4-5]
基于Linux內(nèi)核編寫(xiě)字符設(shè)備驅(qū)動(dòng)程序主要完成如下工作:
#define DEVICE_NAME "stepmotor"
//通過(guò)宏定義設(shè)備名為stepmotor
static int j=0;
//定義全局變量j,保存電機(jī)的相位信息;
根據(jù)上文分析的步進(jìn)電機(jī)脈沖分配信號(hào),定義正轉(zhuǎn)時(shí)對(duì)應(yīng)的結(jié)構(gòu)體為:
Static unsigned
Char pulse_table[]=
{0x20,0x60,0x40,0xc0,0x80,0xa0};
首先通過(guò)初始化函數(shù)static int_init dev_init(void)對(duì)硬件設(shè)備進(jìn)行初始化,向內(nèi)核注冊(cè)設(shè)備號(hào),同時(shí)初始化步進(jìn)電機(jī)。
然后重新編寫(xiě)file_operations結(jié)構(gòu)體成員函數(shù)ioctl,它是步進(jìn)電機(jī)控制的實(shí)現(xiàn)者,Struct file_operations dev_fops.ioctl=s3c2440_stepmotor_ioctl,依據(jù)策略與機(jī)制盡可能相分離原則編寫(xiě)_ioctl函數(shù)體,使步進(jìn)電機(jī)可以完成最基礎(chǔ)的正向單步轉(zhuǎn)動(dòng)和反向單步轉(zhuǎn)動(dòng)即可,其余的控制任務(wù)交給應(yīng)用層的應(yīng)用程序完成。
利用應(yīng)用程序傳遞s3c2440_stepmotor_ioctl的參數(shù)arg來(lái)判斷步進(jìn)電機(jī)的轉(zhuǎn)動(dòng)方向,0是正向轉(zhuǎn)動(dòng),1是暫停,2是反向轉(zhuǎn)動(dòng),3是相位初始化;cmd在初始化模式時(shí)傳遞相位參數(shù)j;以下為_(kāi)ioctl的程序片段:
static int s3c2440_stepmotor_ioctl(
struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){
switch(arg){
case 0://正轉(zhuǎn);
++j;
if(j==6)j=0;
writel(pulse_table[j],S3C2410_GPBDAT);
break;
case 1://暫停;
break;
case 2://反轉(zhuǎn);
--j;
if(j<0) j+=6;
writel(pulse_table[j],S3C2410_GPBDAT);
break;
case 3://初始化;
j=cmd;
if(j>=0&&j<=5)
writel(pulse_table[j],S3C2410_GPBDAT);
break;
default:
return -EINVAL;
}};
最后通過(guò)清除函數(shù)static void _exit dev_exit(void)對(duì)設(shè)備文件進(jìn)行卸載,向內(nèi)核空間注銷(xiāo)設(shè)備號(hào),使內(nèi)核恢復(fù)到?jīng)]有安裝過(guò)這個(gè)設(shè)備的狀態(tài)。
編寫(xiě)Makefile文件,在pc機(jī)上運(yùn)行make命令編譯stepmotor_driver.c文件獲得電機(jī)驅(qū)動(dòng)模塊stepmotor_driver.ko.
在Linux系統(tǒng)中,有很多可供選擇的GUI庫(kù),其中Qt是比較流行的一個(gè)。Qt采用C++語(yǔ)言開(kāi)發(fā),包含了豐富的C++類(lèi),包括窗口界面設(shè)計(jì)的接口、I/O控制接口、繪圖接口、多媒體接口、數(shù)據(jù)庫(kù)操作接口、網(wǎng)絡(luò)通訊接口、XML接口、模塊測(cè)試接口等豐富的開(kāi)發(fā)接口[6]。軟件開(kāi)發(fā)人員通過(guò)使用這些接口,可以方便、高效地完成應(yīng)用設(shè)計(jì)與程序開(kāi)發(fā)。由于采用C++語(yǔ)言,Qt具有較高的執(zhí)行效率。此外不同平臺(tái)間的Qt開(kāi)發(fā)接口是相同的,因此,可以有效的降低Qt應(yīng)用程序跨平臺(tái)開(kāi)發(fā)的移植成本[7]。
3.1 系統(tǒng)流程分析
在系統(tǒng)上電后,首先進(jìn)行數(shù)據(jù)和界面的初始化,然后對(duì)傳感器檢測(cè)到的位置數(shù)據(jù)作處理和顯示步進(jìn)電機(jī)主控制界面,最后是控制程序的結(jié)束。整個(gè)系統(tǒng)程序的總流程圖如圖3所示。
圖3 系統(tǒng)總流程圖
在初始化過(guò)程中Qt控制程序打開(kāi)數(shù)據(jù)文件/opt/data,利用fread()讀取上次電機(jī)停轉(zhuǎn)時(shí)的相位,控制程序通過(guò)ioctl()初始化電機(jī)相位,在控制操作完成后,控制程序?qū)?dāng)前的電機(jī)相位通過(guò)fwrite()寫(xiě)入數(shù)據(jù)文件data中,作為下次初始化的數(shù)據(jù)??刂七^(guò)程中的數(shù)據(jù)流如圖4所示。
圖4 系統(tǒng)數(shù)據(jù)流程圖
如圖5所示為主控制界面流程圖。在步進(jìn)電機(jī)控制主界面中,首先可以對(duì)步進(jìn)電機(jī)的轉(zhuǎn)速進(jìn)行設(shè)置,然后選擇轉(zhuǎn)動(dòng)方向和轉(zhuǎn)動(dòng)模式,在單步模式下可以通過(guò)點(diǎn)擊觸摸屏上對(duì)應(yīng)按鈕達(dá)到單步運(yùn)行的目的;在連續(xù)工作模式下需要對(duì)運(yùn)行步數(shù)進(jìn)行設(shè)置,然后點(diǎn)擊開(kāi)始實(shí)現(xiàn)連續(xù)轉(zhuǎn)動(dòng),在連續(xù)轉(zhuǎn)動(dòng)過(guò)程中可以點(diǎn)擊暫停中止當(dāng)前連續(xù)轉(zhuǎn)動(dòng)任務(wù)。對(duì)步數(shù)進(jìn)行設(shè)置時(shí),點(diǎn)擊對(duì)應(yīng)的LineEdit部件彈出虛擬數(shù)字鍵盤(pán),通過(guò)虛擬數(shù)字鍵盤(pán)完成步數(shù)的設(shè)置。
圖5 控制界面操作流程圖
圖6 單個(gè)步進(jìn)電機(jī)控制界面
4.2 步進(jìn)電機(jī)控制界面程序的實(shí)現(xiàn)
如圖6示,當(dāng)前模式行的LineEdit部件設(shè)置為只讀,用來(lái)顯示當(dāng)前的控制方向和模式,用LCD數(shù)字部件實(shí)時(shí)顯示位置傳感器反饋的位置信息,重定義一個(gè)LineEdit部件作為預(yù)置步數(shù)輸入口,模式選擇和方向選擇通過(guò)兩個(gè)滑槽部件來(lái)實(shí)現(xiàn)。
重定義預(yù)置步數(shù)行對(duì)應(yīng)的LineEdit,為其添加Clicked事件,實(shí)現(xiàn)該LineEdit部件被點(diǎn)擊時(shí)彈出虛擬數(shù)字鍵盤(pán)。具體操作如下:
定義一個(gè)繼承自QLineEdit的類(lèi):mylineedit,
class mylineedit :public QLineEdit
{……}
由于Clicked()事件是由鼠標(biāo)左鍵單擊下LineEdit觸發(fā)的,因此可以重寫(xiě)Qt中原有的mousePressEvent事件,在檢測(cè)到鼠標(biāo)單擊后觸發(fā)自定義的Clicked信號(hào)。
Void mylineedit::mousePressEvent
(QMouseEvent *event){
if(event->button()==Qt::LeftButton) { emit clicked();}
QLineEdit::mousePressEvent(event);}
這樣就可以實(shí)現(xiàn)在觸摸屏上點(diǎn)擊LineEdit就會(huì)發(fā)送一個(gè)clicked的信號(hào)。在圖形界面設(shè)計(jì)中將需要添加clicked事件的LineEdit提升窗口部件為mylineedit.利用信號(hào)與槽機(jī)制使LineEdit部件被點(diǎn)擊時(shí)彈出虛擬數(shù)字鍵盤(pán),從而完成數(shù)值輸入。
通過(guò)單步和連續(xù)模式的配合使用,可以方便的控制步進(jìn)電機(jī)的轉(zhuǎn)動(dòng),達(dá)到精確控制調(diào)整架的目的。
向搭建的系統(tǒng)中移植qt embedded-linux 4.5.2的Lib和tslib-1.4;修改/etc/profile設(shè)置環(huán)境變量,修改/etc/init.d/rcS,實(shí)現(xiàn)系統(tǒng)上電后,內(nèi)核自動(dòng)加載步進(jìn)電機(jī)驅(qū)動(dòng)模塊,啟動(dòng)步進(jìn)電機(jī)控制界面程序,在系統(tǒng)完成啟動(dòng)后可以通過(guò)觸摸屏直接控制步進(jìn)電機(jī)在連續(xù)或單步模式下的正、反轉(zhuǎn),并實(shí)時(shí)的顯示當(dāng)前步進(jìn)電機(jī)的工作狀態(tài)和位置信息。
系統(tǒng)采用ARM9+Linux架構(gòu)設(shè)計(jì),系統(tǒng)功耗低,相比于同類(lèi)型的PLC控制系統(tǒng)具有很高的性?xún)r(jià)比;利用Qt可以快捷的開(kāi)發(fā)圖形控制界面,減少開(kāi)發(fā)時(shí)間。
使用數(shù)據(jù)文件記錄電機(jī)每次停轉(zhuǎn)的相位作為下次啟動(dòng)的相位初始化相位,可以解決系統(tǒng)重啟后電機(jī)會(huì)正向或反向轉(zhuǎn)動(dòng)幾步的問(wèn)題,實(shí)現(xiàn)電機(jī)工作的連續(xù)性。
此外,針對(duì)該項(xiàng)目中需要控制多個(gè)步進(jìn)電機(jī)的情況,創(chuàng)建多個(gè)線程對(duì)各個(gè)步進(jìn)電機(jī)進(jìn)行控制將會(huì)是一種高效的方法[8],可以同時(shí)實(shí)現(xiàn)對(duì)多個(gè)步進(jìn)電機(jī)的控制。
[1] 王學(xué)龍.嵌入式Linux系統(tǒng)設(shè)計(jì)與應(yīng)用.北京:清華大學(xué)出版社,2001.
[2] CORBET J,RUBINI A,KROAB-HARTMAN G.Linux設(shè)備驅(qū)動(dòng)程序.3版.北京:中國(guó)電力出版社,2006.
[3] 黃勤兵,周桂耀,王京京,等.基于嵌入式ARMLinux步進(jìn)電機(jī)驅(qū)動(dòng)程序的設(shè)計(jì).電子技術(shù),2010(7):39-41.
[4] 曹?chē)?guó)輝,曾志鵬.深入理解嵌入式Linux設(shè)備驅(qū)動(dòng)程序.北京:電子工業(yè)出版社,2012.
[5] 曾宏安.從實(shí)踐中學(xué)嵌入式LinuxC編程.北京:電子工業(yè)出版社,2012.
[6] 譚大鵬,李培玉,潘曉弘.基于Qt/E的嵌入式工業(yè)監(jiān)測(cè)輕型圖形用戶(hù)界面構(gòu)件庫(kù)開(kāi)發(fā).計(jì)算機(jī)集成制造系統(tǒng),2009,15(2):399-405.
[7] 陳曦,呂湘曄,劉艷.基于嵌入式Linux新型模塊化工業(yè)控制器設(shè)計(jì).儀表技術(shù)與傳感器,2010(11):27-29.
[8] 陳杰春,丁振良,袁峰.基于多線程的精密離心機(jī)測(cè)試系統(tǒng)設(shè)計(jì).儀表技術(shù)與傳感器,2006(6):29-31.
作者簡(jiǎn)介:楊碩(1989—),碩士,主要從事嵌入式系統(tǒng)開(kāi)發(fā)及應(yīng)用。 E-mail:yangshuo@shu.edu.cn
Linux-based Stepper Motor Control System
YANG Shuo,SHEN Zhen-Jun
(School of Mechanical Engineering and Automation,Shanghai University,Shanghai 200072)
Aiming at improving the existing control system based on the Single Chip Microcomputer , an embedded system design scheme based on ARM processor and Linux2.6.32 kernel was proposed and the driver module was developed according to the working principle of stepper motor. Qt/Embedded4.8.5 was adopted to design human-computer interaction interface, and the semi-automatic control of the system was fulfilled through touch-screen. The system can be separated from the host computer completely, and can record and save the data. It has good mobility and stability to meet the demand of digitalization and visualization for stepping motor .
stepping motor;Linux;Device Drivers;Qt
陳曦(1963—),教授,博士。主要研究領(lǐng)域?yàn)榭刂评碚撆c工程,智能檢測(cè)和智能儀表方向的研究以及嵌入式控制系統(tǒng)的開(kāi)發(fā)。 E-mail:240373982@qq.com
2013-12-15 收修改稿日期:2014-11-07
TP271
A
1002-1841(2015)01-0077-04