一、前言
本項目基于STC89C52單片機,通過控制28BYJ-48步進電機實現(xiàn)按角度正反轉旋轉的功能。28BYJ-48步進電機是一種常用的電機,精準定位和高扭矩輸出,適用于許多小型的自動化系統(tǒng)和機械裝置。
在這個項目中,使用STC89C52單片機作為控制器,這是一款強大而常用的8位單片機芯片,具有豐富的外設和強大的計算能力。通過編寫適當?shù)某绦?,可以通過單片機的IO口來控制步進電機的運動。
28BYJ-48步進電機是一種低成本、低功耗的步進電機,擁有精確的定位能力和較高的轉矩輸出。將使用單片機與步進電機之間的接口信號來驅動電機旋轉,并通過控制電流脈沖的頻率和順序來控制電機前進或后退以及旋轉的角度。
本項目的目標是實現(xiàn)根據(jù)用戶輸入的角度值,控制28BYJ-48步進電機按指定角度進行正反轉旋轉。通過靈活調(diào)整步進電機的控制信號,可以實現(xiàn)不同角度范圍內(nèi)的精確旋轉。
在接下來的內(nèi)容將介紹所需的硬件和軟件資源,包括STC89C52單片機的基本特性、28BYJ-48步進電機的工作原理,以及編寫控制程序的關鍵步驟。
二、設計流程
【1】硬件準備:
- 51單片機開發(fā)板:選擇STC89C52單片機開發(fā)板。
- 28BYJ-48步進電機:一個28BYJ-48步進電機+ULN2003驅動板。
- 驅動電路:使用ULN2003芯片來驅動步進電機。
- 連接線和電源:準備連接線和電源供電。
【2】連接電路:
- 將51單片機與驅動電路和步進電機連接起來。
【3】編寫程序:
- 使用keil集成開發(fā)環(huán)境(IDE)編寫51單片機的控制程序。
- 初始化引腳和端口設置,配置控制步進電機所需的引腳。
- 編寫函數(shù)來控制步進電機的正反轉旋轉。
- 編寫函數(shù)來控制步進電機按照指定的角度進行旋轉。
【4】控制步進電機旋轉:
- 在主程序中,調(diào)用適當?shù)暮瘮?shù)來控制步進電機的旋轉。
- 使用按鍵輸入設備來觸發(fā)步進電機的旋轉。
- 控制旋轉的角度、速度和方向。
【5】調(diào)試和測試:
- 通過編譯程序,并將生成的可執(zhí)行文件下載到51單片機開發(fā)板中。
三、代碼實現(xiàn)
3.1 電機正反轉控制
下面是通過STC89C52單片機控制28BYJ-48步進電機實現(xiàn)正轉和反轉的實現(xiàn)代碼:
#include <reg52.h>
#include <intrins.h>
#define motorPort P1 // 步進電機的控制引腳連接到P1口
#define clockwise 0 // 順時針方向
#define counterclockwise 1 // 逆時針方向
// 函數(shù)聲明
void delay(unsigned int time);
void motorRotate(unsigned char direction, unsigned int steps);
void main()
{
while (1)
{
// 正轉,執(zhí)行一定的步數(shù) (這里為512步,可根據(jù)需要修改)
motorRotate(clockwise, 512);
delay(1000); // 延時1秒
// 反轉,執(zhí)行一定的步數(shù)
motorRotate(counterclockwise, 256);
delay(1000); // 延時1秒
}
}
// 延時函數(shù)
void delay(unsigned int time)
{
unsigned int i, j;
for (i = time; i > 0; i--)
{
for (j = 110; j > 0; j--); // 指令周期延時
}
}
// 控制步進電機旋轉
void motorRotate(unsigned char direction, unsigned int steps)
{
unsigned int i;
unsigned char motorSequence[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09}; // 步進電機的控制序列
for (i = 0; i < steps; i++)
{
if (direction == clockwise)
{
motorPort = motorSequence[i % 8];
}
else if (direction == counterclockwise)
{
motorPort = motorSequence[7 - (i % 8)];
}
delay(2); // 每步之間的延時,可根據(jù)需要調(diào)整
}
motorPort = 0x00; // 停止電機
}
代碼里使用 STC89C52 單片機的 P1 口連接到28BYJ-48步進電機的控制引腳。在 main
函數(shù)中,通過循環(huán)實現(xiàn)了正轉和反轉的功能。motorRotate
函數(shù)用于控制步進電機的旋轉方向和步數(shù),其中 clockwise
和 counterclockwise
分別代表順時針和逆時針方向。
3.2 角度旋轉
下面代碼使用STC89C52單片機控制28BYJ-48步進電機按指定的角度進行正轉和反轉,封裝子函數(shù)進行調(diào)用。
#include <reg52.h>
// 定義28BYJ-48步進電機的相序
unsigned char stepSequence[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};
// 定義步進電機當前位置和角度
unsigned char currentPosition = 0;
unsigned int currentAngle = 0;
// 延時函數(shù)
void delay(unsigned int time) {
unsigned int i, j;
for (i = 0; i < time; i++) {
for (j = 0; j < 120; j++);
}
}
// 步進電機正轉函數(shù)
void stepForward(unsigned int angle) {
unsigned int steps = angle / 5; // 每步轉動角度為5度
unsigned int i;
for (i = 0; i < steps; i++) {
currentPosition++;
if (currentPosition >= 8) {
currentPosition = 0;
}
P1 = stepSequence[currentPosition];
delay(10); // 控制步進電機轉速,可調(diào)整延時時間
}
currentAngle += angle;
}
// 步進電機反轉函數(shù)
void stepBackward(unsigned int angle) {
unsigned int steps = angle / 5; // 每步轉動角度為5度
unsigned int i;
for (i = 0; i < steps; i++) {
if (currentPosition == 0) {
currentPosition = 8;
}
currentPosition--;
P1 = stepSequence[currentPosition];
delay(10); // 控制步進電機轉速,可調(diào)整延時時間
}
currentAngle -= angle;
}
// 主函數(shù)
void main() {
while (1) {
// 正轉180度
stepForward(180);
delay(1000); // 停頓1秒鐘
// 反轉90度
stepBackward(90);
delay(1000); // 停頓1秒鐘
}
}
代碼使用STC89C52單片機的P1口作為輸出口,通過控制P1口輸出的電平來控制步進電機的旋轉。步進電機的相序存儲在stepSequence
數(shù)組中,每個元素對應一個相位。stepForward
函數(shù)用于實現(xiàn)步進電機的正轉,stepBackward
函數(shù)用于實現(xiàn)步進電機的反轉。delay
函數(shù)用于控制步進電機的轉速,可以根據(jù)需要調(diào)整延時時間。
在主函數(shù)中,演示了步進電機的正轉180度和反轉90度的操作。
3.3 按鍵控制電機
有2個按鍵,接在P2口3上面的,按下是低電平。下面代碼加入2個按鍵,實現(xiàn)了2個按鍵的功能。
#include <reg52.h>
#define motorPort P1 // 步進電機的控制引腳連接到P1口
#define clockwise 0 // 順時針方向
#define counterclockwise 1 // 逆時針方向
sbit startBtn = P2^0; // 啟動按鈕連接到P2.0口
sbit stopBtn = P2^1; // 停止按鈕連接到P2.1口
sbit cwBtn = P2^2; // 順時針按鈕連接到P2.2口
sbit ccwBtn = P2^3; // 逆時針按鈕連接到P2.3口
unsigned char motorSequence[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09}; // 步進電機的控制序列
bit motorRunning = 0; // 步進電機是否正在運行
unsigned int targetAngle = 0; // 目標轉動角度,初始為0
bit clockwiseDirection = 1; // 電機默認啟動方向為順時針
// 函數(shù)聲明
void delay(unsigned int time);
void motorRotate(unsigned char direction, unsigned int steps);
void main()
{
while (1)
{
if (startBtn == 0) // 如果按下了啟動按鈕
{
while (startBtn == 0); // 等待按鈕釋放
if (!motorRunning)
{
motorRunning = 1;
motorRotate(clockwiseDirection, targetAngle); // 啟動電機
}
}
if (stopBtn == 0) // 如果按下了停止按鈕
{
while (stopBtn == 0); // 等待按鈕釋放
if (motorRunning)
{
motorRunning = 0;
motorPort = 0x00; // 停止電機
}
}
if (cwBtn == 0) // 如果按下了順時針按鈕
{
while (cwBtn == 0); // 等待按鈕釋放
clockwiseDirection = 1; // 設置電機啟動方向為順時針
}
if (ccwBtn == 0) // 如果按下了逆時針按鈕
{
while (ccwBtn == 0); // 等待按鈕釋放
clockwiseDirection = 0; // 設置電機啟動方向為逆時針
}
}
}
// 延時函數(shù)
void delay(unsigned int time)
{
unsigned int i, j;
for (i = time; i > 0; i--)
{
for (j = 110; j > 0; j--); // 指令周期延時
}
}
// 控制步進電機旋轉
void motorRotate(unsigned char direction, unsigned int steps)
{
unsigned int i;
for (i = 0; i < steps; i++)
{
if (!motorRunning)
break;
if (direction == clockwise)
{
motorPort = motorSequence[i % 8];
}
else if (direction == counterclockwise)
{
motorPort = motorSequence[7 - (i % 8)];
}
delay(2); // 每步之間的延時,可根據(jù)需要調(diào)整
}
motorPort = 0x00; // 停止電機
}
在以上代碼中,增加了 cwBtn
和 ccwBtn
兩個按鍵引腳,并定義為 P2^2
和 P2^3
。按下順時針按鈕時,將 clockwiseDirection
設置為 1,表示啟動方向為順時針;按下逆時針按鈕時,將 clockwiseDirection
設置為 0,表示啟動方向為逆時針。