stm32單片機控制28BYJ48步進電機原理及代碼


 命名方式(以28BYJ48步進電機為例)

28BYJ48步進電機的編號

28-----步進電機的有效最大外徑是28毫米

B-----表示步進電機

Y-----表示永磁式

J-----表示減速型

48-----表示四相八拍

工作原理

1、五線四相步進電機,不同相位得電會讓步進電機的轉子轉動一個角度,按一定規律給不同的相位通電,就可以讓步進電機連續轉動,下表就是通電的順序。

表里面的順,逆時針的方向只是代表相位給電時序,

注:總共五條線,一個是VCC,剩下四條分別接上ABCD相

分別對應與ULN2003/ULN2003A驅動芯片的5V以及4個輸入口對應連接

2、每走一個位置,都要給一定的延時,不然還沒等轉子到位,下一個脈沖就進來了,肯定會引起錯誤,導致電機堵轉或者異常震動。

3、通過改變延時的時間,就可以控制電機的轉速,不能太慢,也不要太快,不斷調試到合理范圍就行。

4、單片機IO口和電機四條相線連接時,一定不能錯誤,要按照順序相連接。

5、調換得電的順序,就可以控制電機的轉向。

注意在51單片機中,為IO口置0相當於是高電平,而置1的時候相當於是低電平,和上面的圖片一致(GND)

二、關鍵實驗程序

在編寫注釋的時候用的是ANSI編碼器,在這里部分注釋可能會出現亂碼,復制到編譯器中就會正常顯示(也注意一般用UTF-8編碼器進行編寫,ANSI編碼器對中文不友好,一般一個漢字用的2個字符儲存,所以在轉存的時候就會出現亂碼)

頭文件

#ifndef __BSP_ULN2003_H__
#define __BSP_ULN2003_H__

#include <stm32f10x.h>
#include "bsp_SysTick.h"

#define STEPPER_ANGLE		0.703125   //  360/(4096/4)=360/512=0.703125

enum dir{Pos, Neg};   //Pos = 0, Neg = 1  //enumΪ¶¨ÒåΪö¾Ù

#define IN1_HIGH	GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET)
#define IN1_LOW		GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET)

#define IN2_HIGH	GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET)
#define IN2_LOW		GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET)

#define IN3_HIGH	GPIO_WriteBit(GPIOA, GPIO_Pin_6, Bit_SET)
#define IN3_LOW		GPIO_WriteBit(GPIOA, GPIO_Pin_6, Bit_RESET)

#define IN4_HIGH	GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET)
#define IN4_LOW		GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_RESET)

void ULN2003_Configuration(void);
void stepper(unsigned int dir, unsigned int speed);
void angle_control(unsigned int dir, double angle, unsigned int speed);

#endif

調用函數

/*
	Á¬Ïß±í£º
	STM32								ULN2003Çý¶¯
	PA4      	<-------> 	IN1
	PA5			<-------> 	IN2
	PA6			<-------> 	IN3
	PA7			<-------> 	IN4
	
	5V 28BYJ-48²½½øµç»ú£¬ÄÚ²¿´øÓмõËÙ×°Öà ¼õËٱȣº1/64   ²½¾à½Ç£º5.625¡ã/64£¨64¸öÂö³åת¶¯5.625¡ã£©

ÕýÏòת¶¯£º
	ËÄÏà°ËÅÄ¿ØÖÆË³Ðò£º(A-AB-B-BC-C-CD-D-DA)
				1		2		3		4		5		6		7		8
	A			-		-		+		+		+		+		+		-
	B			+		-		-		-		+		+		+		+
	C			+		+		+		-		-		-		+		+
	D			+		+		+		+		+		-		-		-
·´Ïòת¶¯£º(DA-D-CD-C-BC-B-AB-A)
*/

#include "bsp_uln2003.h"

void ULN2003_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_WriteBit(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, Bit_RESET);
}

//ËÙ¶È¿ØÖÆ:
/*
dir: ˳£¬ÄæÊ±ÕëÐýת·½Ïò
speed£º×ªËÙ£¬·¶Î§[1,100]
*/
void stepper(unsigned int dir, unsigned int speed)
{
	if(dir == Pos)
	{
		//step1:
		IN1_HIGH;
		IN2_LOW;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);
		
		//step2:	
		IN1_HIGH;
		IN2_HIGH;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);

		//step3:		
		IN1_LOW;
		IN2_HIGH;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);

		//step4:
		IN1_LOW;
		IN2_HIGH;
		IN3_HIGH;
		IN4_LOW;
		Delay_us(speed);

		//step5:
		IN1_LOW;
		IN2_LOW;
		IN3_HIGH;
		IN4_LOW;
		Delay_us(speed);

		//step6:
		IN1_LOW;
		IN2_LOW;
		IN3_HIGH;
		IN4_HIGH;
		Delay_us(speed);

		//step7:
		IN1_LOW;
		IN2_LOW;
		IN3_LOW;
		IN4_HIGH;
		Delay_us(speed);

		//step8:
		IN1_HIGH;
		IN2_LOW;
		IN3_LOW;
		IN4_HIGH;
		Delay_us(speed);
	}
	else
	{
		//step1:
		IN1_HIGH;
		IN2_LOW;
		IN3_LOW;
		IN4_HIGH;
		Delay_us(speed);

		//step2:		
		IN1_LOW;
		IN2_LOW;
		IN3_LOW;
		IN4_HIGH;
		Delay_us(speed);

		//step3:		
		IN1_LOW;
		IN2_LOW;
		IN3_HIGH;
		IN4_HIGH;
		Delay_us(speed);

		//step4:
		IN1_LOW;
		IN2_LOW;
		IN3_HIGH;
		IN4_LOW;
		Delay_us(speed);

		//step5:
		IN1_LOW;
		IN2_HIGH;
		IN3_HIGH;
		IN4_LOW;
		Delay_us(speed);

		//step6:
		IN1_LOW;
		IN2_HIGH;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);

		//step7:
		IN1_HIGH;
		IN2_HIGH;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);

		//step8:
		IN1_HIGH;
		IN2_LOW;
		IN3_LOW;
		IN4_LOW;
		Delay_us(speed);
	}
}

//½Ç¶È¿ØÖÆ£º
/*
dir: ˳£¬ÄæÊ±ÕëÐýת·½Ïò
angle£º½Ç¶È£¬·¶Î§[0,360]
speed£º×ªËÙ£¬·¶Î§[1,100]
*/

void angle_control(unsigned int dir, double angle, unsigned int speed)
{
	int i;
	
	for(i = 0; i < angle / STEPPER_ANGLE; i++) //µ÷ÓÃ(angle / STEPPER_ANGLE)¸ö°ËÅÄ
		stepper(dir, speed);
}
//µ÷ÓÃÕâ¸öº¯Êý¿ØÖƽǶÈÓнÏСµÄÎó²î»ò˵ÊÇȱÏÝ£ºÒ»ÊÇ˵stepper(dir, speed);ÊÇÒÔ°ËÅÄΪ×îС·Ö¶ÈÖµ
//Æä´ÎÊÇ£¬forº¯ÊýÖÐ×îС²½¾àΪ1£¬ºÜÏÔÈ»angle / STEPPER_ANGLE ×î¶àÓÐÒ»¸ö°ËÅĵÄÎó²î£¬
//¼´5.624/64*8=0.703¶È£¬Ò²²»ÊǺܴ󣬿ÉÒÔºöÂÔ²»¼Æ

1、步進電機的減速比為1/64,即轉子轉動64圈,外面的轉軸才會轉動1圈

2、步進電機的步距角為5.624/64 (步進電機的定子繞組每次改變一次通電狀態,步進電機外面的轉軸轉過的角度稱步距角;即步進電機的最小旋轉角度)

3、所以360/(5.624/64)≈ 4096 (步進電機外面的轉軸轉過一圈所需要改變定子繞組的通電狀態次數)

這里補充介紹一個概念:步進角

步進電機的定子繞組每次改變一次通電狀態,轉子轉過的角度稱步進角。

(可以認為是電機內部的轉子的最小旋轉角度)

步進角 = (360)/m * Z * C

m-----定子相數

Z-----轉子磁極對數

C-----通電方式

{ C = 1 ,單相輪流通電,雙相輪流通電方式

  C = 2 , 雙相輪流通電方式

1,相數:是指產生不同對極N,S磁場的激磁線圈對數

2,拍數:完成一個周期性變化所需脈沖數,以四相電機為例,有單相四拍的運行方式:(A-B-C-D),有雙相四拍的運行方式:(AB-BC-CD-DA),有四相八拍的運行方式:(A-AB-B-BC-C-CD-D-DA)

這里的源碼用的是雙相輪流通電方式,在源碼中可以看到四個相位MA,MB,MC,MD使能為高電平狀態的相位數為相鄰2個或1個(A-AB-B-BC-C-CD-D-DA)

步進電機的相關參數:


注意事項:由於電機的制造誤差,安裝誤差,單片機的誤差還有軟件延時函數誤差,這些誤差累加起來之后,就會導致電機的轉速、轉動角度出現一定的誤差。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM