使用 ULN2003 驅動 28BYJ-48 步進電機。
要用一個步進電機測試東西,不過需求來的比較突然手邊也沒有像是A4988或TMC2209這種硬件驅動,于是就用別人的ULN2003驅動和28BYJ-48步進電機來做如何驅動步進電機。
基本概念
步進電機:將輸入的脈沖信號轉變成角位移,即給一個脈沖信號,步進電機就轉動一個角度。
可以通過控制脈沖頻率,來控制電機轉動的速度和加速度。
從這個電機的名字入手28BYJ-48: 28表示電機直徑28mm,B代表步進電機,Y代表永磁式步進電機PM,J代表減速型電機帶減速箱,48表示四相八拍。

轉子:最中間標注為0~5的六個齒。顧名思義,它是要轉動的。轉子的每個齒上都帶有永久的磁性,是一塊永磁體,這就是永磁式。
定子:外圈的8個齒。它是保持不動的,跟電機的外殼固定在一起。每個齒上都纏上了一個線圈繞組,正對著的2個齒上的繞組又是串聯在一起的,也就是說正對著的2個繞組總是會同時導通或關斷的,如此就形成了4相,即圖中標注的ABCD,相對的2個齒是1相。四項五線多吃來那條線是電源線。
拍數:完成一個磁場周期性變化所需脈沖數。一拍就是一個脈沖信號。
以四相電機為例,四相四拍為 AB-BC-CD-DA(-AB…), 四相八拍為 A-AB-B-BC-C-CD-D-DA(-A…)
步距角(步進角):每接收到一個脈沖信號步進電機轉動的角度。
步距角 = 360° / (定子齒數 * 運行拍數)
以八拍運行為例,電機主軸的步距角度為: 360/(8*8)=5.625。再除以減速比64,得到輸出軸的步距角5.625/64=0.087890625。八拍運行俗稱半步,對應四拍運行則為整步。
查到步距角參數,也可以反推需要360/5.625=64個脈沖信號轉子才會轉動1圈,(因為帶減速箱結構所以需要再乘上減速比)64*64=4096個脈沖信號電機主軸才會轉1圈。
齒輪減速比:這款為1:64。即內部轉子轉動64圈,外部輸出主軸才轉動1圈。于是就是需要64×64=4096個拍數才會讓輸出軸轉過1圈。
空載啟動頻率:這款步進電機是550P.P.S。即每秒最多給出550個步進脈沖數才可以正常啟動,需要單個節(jié)拍持續(xù)時間(或節(jié)拍的刷新時間)至少為1/550=1.8ms
當脈沖頻率高于啟動頻率,電機不能正常啟動,可能發(fā)生丟步或堵轉。在有負載的情況下,啟動頻率應更低。
如果要使電機達到高速轉動,脈沖頻率應該有加速過程,即啟動頻率較低,然后按一定加速度升到所希望的高頻(電機轉速從低速升到高速)
保持轉矩:步進電機通電但沒有轉動時,定子鎖住轉子的力矩。通常步進電機在低速時的力矩接近保持轉矩。
細分(角度細分):一般由硬件驅動器完成。如果主軸轉1圈需要200個脈沖,那么2細分就是轉1圈需要400個脈沖。細分是通過影響電機的步距角來影響轉角和轉速。
了解完了基本信息和原理之后
可以得出轉動一個角度的公式
轉動角度所需輸出步數 = (角度 * 減速比) * (定子齒數 * 運行拍數) / 360°
轉速的公式
轉速(轉/秒) = 脈沖頻率(HZ) / (360 / 步距角 * 細分倍數)
例如設置PWM波的頻率為1kHz(1秒1000個脈沖),42步進電機的步距角是1.8°,在沒有細分的情況下,轉速為1000/(360/1.8*1)=5rad/s,即5*60=300rpm
八拍模式是這類4相步進電機的最佳工作模式。八拍相較于四拍除了能使轉動精度增加一倍,也能增加電機的整體扭力輸出。
除了單四拍和八拍的工作模式外,還有雙四拍(雙繞組通電四節(jié)拍)。雙四拍步進角度同單四拍是一樣的,但由于它是兩個繞組同時導通,所以扭矩會比單四拍模式大。
28BYJ-48的減速比精度問題
然而實際數一下每個齒輪的齒數,然后將各級減速比相乘,算出的真實的減速比應該為 (32/9)(22/11)(26/9)(31/10)≈63.683950617
并非1:64整。
按真實減速比計算,需要64x63.68...≈4075.7拍主軸才會完整轉過一圈。要是按1:64錯誤地計算那么每轉過100.5圈就會使主軸差出來半圈。
后來查了下在實際應用中, 28BYJ-48最初的設計目的是用來控制空調的扇葉的,轉動的角度也小于180度,也就不需要很高的精度。
代碼
/********************************** DEFINE **********************************/
#define MOTOR_PORT
GPIOA
#define MOTOR_IN1
GPIO_PIN_4
#define MOTOR_IN2
GPIO_PIN_5
#define MOTOR_IN3
GPIO_PIN_6
#define MOTOR_IN4
GPIO_PIN_7
#define IN1_HIGH
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN1, GPIO_PIN_SET);
#define IN1_LOW
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN1, GPIO_PIN_RESET);
#define IN2_HIGH
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN2, GPIO_PIN_SET);
#define IN2_LOW
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN2, GPIO_PIN_RESET);
#define IN3_HIGH
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN3, GPIO_PIN_SET);
#define IN3_LOW
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN3, GPIO_PIN_RESET);
#define IN4_HIGH
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN4, GPIO_PIN_SET);
#define IN4_LOW
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_IN4, GPIO_PIN_RESET);
/******************************** FUNCTION ********************************/
/*
* @function: 八拍驅動
* @notion: 28BYJ-48步進電機delay最小為2ms
*/
static void Phase8_Single(uint8_t
step, uint8_t delay)
{
switch (step) {
case 0:
IN1_LOW;IN2_HIGH; IN3_HIGH; IN4_HIGH;
break;
case 1:
IN1_LOW; IN2_LOW; IN3_HIGH; IN4_HIGH;
break;
case 2:
IN1_HIGH; IN2_LOW; IN3_HIGH; IN4_HIGH;
break;
case 3:
IN1_HIGH; IN2_LOW; IN3_LOW; IN4_HIGH;
break;
case 4:
IN1_HIGH; IN2_HIGH; IN3_LOW; IN4_HIGH;
break;
case 5:
IN1_HIGH; IN2_HIGH; IN3_LOW; IN4_LOW;
break;
case 6:
IN1_HIGH; IN2_HIGH; IN3_HIGH; IN4_LOW;
break;
case 7:
IN1_LOW; IN2_HIGH; IN3_HIGH; IN4_LOW;
break;
default :
break;
}
HAL_Delay(delay);
}
/*
* @function: 轉動指定角度
* @param:
dir: 0為正轉 1為反轉
* @notion: 28BYJ-48步進電機delay最小為2ms
*/
void SteppingMotor_TurnAngle(float
angle, uint8_t delay)
{
// 轉動角度所需輸出步數 = (角度 * 減速比) * (定子齒數 * 運行拍數) / 360°
//
float tmp = angle * 4096.0f / 360.0f;
// 減速比1:64
float tmp = fabsf(angle) * 283712.0f / 4455.0f * 8.0f / 45.0f;
// 減速比1:63.684
uint16_t steps = (uint16_t)tmp;
if (angle > 0) {
for (uint16_t i = steps; i > 0; i -- ) {
Phase8_Single(i % 8, delay);
}
} else {
for (uint16_t i = steps; i > 0; i -- ) {
Phase8_Single(abs(i % 8 - 7), delay);
}
}
}
_Single(i % 8, delay);
}
} else {
for (uint16_t i = steps; i > 0; i – ) {
Phase8_Single(abs(i % 8 - 7), delay);
}
}
}
24BYJ48步進電機可在線咨詢索樣!