在工業控制中,許多場合都可以看到電機的身影。特別是步進電機,以其精度高,運行可靠等優勢,廣泛地應用于數字控制系統中。像這一類步進電機的控制,通常都是使用的脈沖信號來實現的。當步進電機接收到一個脈沖信號,會轉動一個固定的角度,所以可以通過控制脈沖的個數來控制轉動的角度,從而實現精確定位的目的;同時可以通過控制脈沖頻率來控制電機轉動的速度,從而實現控制速度的目的。
英創嵌入式工控板提供了兩種控制步進電機的方法給用戶,第一種方法是使用GPIO發出脈沖來實現控制電機的目的,根據需要轉動的角度和速度,通過調用GPIO的API函數來發出相應個數和頻率的脈沖就能夠達到這一目的。但是如果控制電機的實時性要求比較高,需要達到10ms以內的精度,那么第一種方法可能就不能滿足要求了,因為控制GPIO是通過了操作系統來執行的,這樣程序就涉及到了系統調度等因素,在實時性方面肯定就不能滿足太高的需求。于是英創公司推出了另外一種實時性較高的方法,即使用PWM脈沖來控制電機。
英創工控主板EM928x系列上共有4路PWM輸出,其最高輸出頻率可達12MHz,但如果希望保證一定精 度的占空比(1%的精度),則輸出最高頻率只能到240KHz。而EM335x系列上也有4路PWM輸出,其最高輸出頻率可達50MHz,但如果希望保證一定精度的占空比(1% 的精度),則輸出最高頻率只能到1MHz。從頻率和占空比上看,應該是完全滿足控制速度的要求,但是如果要實現精確定位的功能,還需要控制脈沖的個數,所以英創公司修改了PWM脈沖驅動,在原來的基礎上增加了對PWM波個數控制和計數的功能,使應用程序能控制發出的脈沖個數,從而精確步進電機的動作。
本文以下部分將介紹這一新增加的功能以及在應用程序中的調用方法。
實現這一功能是通過利用CPU內部的計數器來記錄PWM脈沖的個數,當達到預定的值,就產生中斷將PWM脈沖停止,這樣就能夠對PWM脈沖的計數并且產生指定個數的脈沖,這一部分的功能英創公司已經在驅動中完成,用戶只需要在應用程序中通過接口調用,就可以啟用、停止計數功能,并且實時查詢脈沖數。支持這一功能的PWM波有兩路:PWM1和PWM2,能產生的最小波形數為2。對PWM的操作可歸為2種基本操,在原有的普通使能和停止功能基礎上加入了計數功能的操作,所對應的命令參數,定義如下:
#define EM9280_COUNT_START 12//啟動帶計數功能的PWM脈沖輸出
#define EM9280_COUNT_STOP 13//強制停止帶計數功能的PWM脈沖輸出
接下來來看頭文件中定義的PWM 的數據結構,包括頻率、占空比以及極性等參數:
struct pwm_config_info
{
unsigned int cmd;//= 0, 1, 2, ....
unsigned int freq;/* in Hz */
unsigned int duty;/* in % */
unsigned int polarity;
unsigned int count;
};
cmd表示指令:就是上面說的兩種操作。
freq表示輸出的脈沖頻率,單位為 Hz。Freq 的取值范圍 和板卡的最高支持頻率有關。
duty表示輸出脈沖的占空比,單位為%。
Duty的取值范圍:1 – 99。
Polarity表示輸出脈沖的極性,選擇 0 或者 1。
count是新加入的參數,表示需要生成的PWM波的個數。
進行PWM操作時,首先打開相應的設備節點文件,然后再調用 write( )函數進行 pwm 的設置、啟動計數等操作,以下為啟動計數功能的相關應用代碼:
int PWM_COUNT_Start(int fd, int freq, int duty, unsigned int count)
{
int rc;
struct pwm_config_info conf;
conf.cmd = EM9280_COUNT_START;
conf.freq = freq;
conf.duty = duty;
conf.polarity = POLARITY;
conf.count = count;
rc = write(fd, &conf, sizeof(struct pwm_config_info));
return rc;
}
這樣就只需要調用PWM_COUNT_Start()這個函數,并將參數帶入即可,我們就以產生5個占空比為1KHZ的波形為例:
int npwm = 1;
int fd;
char device[32];
unsigned int freq = 1000;
unsigned int duty = 50;
unsigned int count = 5;
sprintf( device, '/dev/em9280_pwm%d', npwm );
fd = open(device, O_RDWR);
if ( fd < 0)
{
printf('can not open /dev/em9280_pwm%d device file!\n', npwm);
return -1;
}
printf( 'Open %s\n', device );
PWM_COUNT_Start( fd, freq, duty, count );
在脈沖輸出的過程中,可以調用read函數讀取已經輸出的脈沖數,如果到達某一個值的時候需要停止輸出,就調用write( )函數進行pwm的停止,詳細的代碼如下:
int PWM_COUNT_Stop(int fd )
{
int rc;
struct pwm_config_info conf;
memset( &conf, 0, sizeof(struct pwm_config_info));
conf.cmd = EM9280_COUNT_STOP;
rc = write(fd, &conf, sizeof(struct pwm_config_info));
return rc;
}
//讀取已發送脈沖數
read(fd, &buf, sizeof(buf));
if( buf>=5 )//當輸出脈沖數到達某個值則停止
PWM_COUNT_Stop( fd );
生成5個占空比為1KHz的波形的程序運行的結果如下圖:
通過對PWM脈沖計數功能的實現,就可以對電機進行精確的控制了,詳細的代碼請參考光盤中的例程。
-
嵌入式主板
+關注
關注
7文章
6100瀏覽量
36273
發布評論請先 登錄
評論