STM32ドライバ ステッピングモータドライバ(HALライブラリ)

この記事では、ドライバーのソース コードとよくある質問について説明します。これは HAL ライブラリであることに注意してください。
正逆回転、ブレーキをサポートしており、コードはすべてマクロとして定義されているため、プロジェクトへのその後の追加が容易になり、
モーターが回転するたびに前のステップに進みます。

導入

ステッピングモーターは、特定のステップ角を徐々に回転させることによって動作が達成される特殊なタイプのモーターです。ステッピングモーターの動作は離散的なステップ方式で行われ、各ステップが一定の角度で回転するため、正確な位置制御が可能です。ステッピング モーターは、固定数のステップ角、ローター、巻線、および駆動回路で構成されます。一般に、ステッピング モーターには、単相ステッピング モーターと二相ステッピング モーターの 2 つの主なタイプがあります。各タイプは異なるバリエーションに分類できますが、基本的な動作原理は同じです。ステッピングモーターの動作原理は、電磁気と磁気の相互作用に基づいています。これは、回転コンポーネント (ローターと呼ばれることが多い) とステーターで構成されます。ステーターの巻線は入力電流に基づいて磁場を生成し、ローターには永久磁石が付いています。電流が固定子巻線を通過すると、磁界が回転子の永久磁石と相互作用し、回転子が回転します。ステッピング モーターの回転はステップ角度で測定され、ステップ角度はモーターの設計と構造によって異なります。適切な電流パルスを順番に印加することにより、正確な回転運動を達成することができ、同時にモーターの速度と位置を制御することができます。ステッピング モーターは、多くのアプリケーション、特にプリンター、CNC 工作機械、ロボット、精密機器など、正確な位置制御や特定の角度への回転を必要とするアプリケーションで広く使用されています。
この記事では、最も一般的で最も単純な 28BYJ-48 (5 線 4 端子モーター) を使用します。
ここに画像の説明を挿入します

原理

ステッピング モーターの動作原理は電磁気と磁気の相互作用に基づいており、ステーターとローター、および電流によってローターの回転を制御する駆動回路が含まれています。
ステータと巻線: ステッピング モーターのステータには通常、複数の巻線が含まれています。これらの巻線は電源に接続されており、巻線を流れる電流によってステータ上に磁界が発生することがあります。これらの巻線の配置と数は、ステッピング モーターの種類と特性に影響します。
ローターと永久磁石: ステッピング モーターのローターには通常、安定した磁場を生成する永久磁石が付いています。この磁場はステーターで生成される磁場と相互作用し、ローターを回転させます。
ステップ角とステップ動作: ステッピング モーターの回転は、固定のステップ角単位で実行されます。ステップ角とは、モーターがパルスを受けるごとに回転する角度であり、モーターの機械設計と電気的特性によって決まります。モーターにパルス信号を徐々に加えることで、段階的な回転運動を実現します。ステップ角が小さいほどモーターの回転精度が高くなります。
駆動回路とパルス制御: ステッピングモーターの回転を制御するには、適切な電流パルスを生成する駆動回路が必要です。駆動回路は入力された制御信号に基づいて一連のパルスを生成し、これらのパルスがステッピング モーターのさまざまな巻線を順番に流れることで、磁界と回転が生成されます。周波数とパルス数を制御することで、モーターの回転速度と角度を制御できます。
フルステップ モードとハーフステップ モード: ステッピング モーターはフルステップ モードまたはハーフステップ モードで動作できます。フルステップ モードでは、各ステップ角度が完全なステップ角度を回転します。ハーフステップ モードでは、各ステップ角度が半分のステップ角度を回転するため、より細かい制御とよりスムーズな動きが可能になります。

ハーフステップモード

ここに画像の説明を挿入します

フルステップモード

ここに画像の説明を挿入します
マイコンのIOポートの出力電流が小さすぎてモーターを駆動できないため、別のドライバーボードを追加する必要がありますが、シンプルで安価なULN2003を使用するだけです。

実験コード

ステップモーター.h

/**
 ****************************************************************************************************
 * @file        step_motor.h
 * @author      Mr.wang
 * @version     V1.0
 * @date        2023-08-1
 * @brief       步进电机驱动代码
 ****************************************************************************************************
 */

#ifndef _STEP_MOTOR_H
#define _STEP_MOTOR_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/

//在这里配置引脚 A-D
#define MOTOR_GPIO_PORT                 GPIOB
#define MOTOR_GPIO_PIN_A                GPIO_PIN_3
#define MOTOR_GPIO_PIN_B                GPIO_PIN_4
#define MOTOR_GPIO_PIN_C                GPIO_PIN_5
#define MOTOR_GPIO_PIN_D                GPIO_PIN_6
#define MOTOR_GPIO_CLK_ENABLE()         do{
      
       __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   


#define GPIO_A_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_A, GPIO_PIN_SET);
#define GPIO_A_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_A, GPIO_PIN_RESET);
#define GPIO_B_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_B, GPIO_PIN_SET);
#define GPIO_B_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_B, GPIO_PIN_RESET);
#define GPIO_C_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_C, GPIO_PIN_SET);
#define GPIO_C_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_C, GPIO_PIN_RESET);
#define GPIO_D_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_D, GPIO_PIN_SET);
#define GPIO_D_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_D, GPIO_PIN_RESET);


/******************************************************************************************/
/* 外部接口函数*/
void step_motor_init(void);
void Move_StopNow(void);
void stepMotor_8(uint8_t dir);
void Move_Step_8(uint8_t dir, uint16_t Step);

#endif

ステップモーター.c

/**
 ****************************************************************************************************
 * @file        step_motor.c
 * @author      Mr.wang
 * @version     V1.0
 * @date        2023-08-1
 * @brief       步进电机驱动代码
 ****************************************************************************************************
 */

#include "./BSP/LED/step_motor.h"
#include "./SYSTEM/delay/delay.h"


uint8_t motorSequence_8[] = {
    
    0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};   // 步进电机八拍序列
uint16_t currentStep_8 = 0; // 目前处于哪一拍
uint8_t stepx = 0;
uint8_t step = 0;

/**
 * @brief       步进电机初始化
 * @param       无
 * @retval      无
 */
void step_motor_init(void)
{
    
    
    GPIO_InitTypeDef GPIO_InitStruct;
    MOTOR_GPIO_CLK_ENABLE();

    GPIO_InitStruct.Pin = MOTOR_GPIO_PIN_A | MOTOR_GPIO_PIN_B | MOTOR_GPIO_PIN_C | MOTOR_GPIO_PIN_D; //  选择引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速输出
    HAL_GPIO_Init(MOTOR_GPIO_PORT, &GPIO_InitStruct);
}



/**
 * @brief       刹车
 * @param       无
 * @retval      无
 */
void Move_StopNow(void)
{
    
    
    uint8_t stop = 0x0F;
    if (stop & 0x01)
    {
    
    
        GPIO_A_ON();
    }
    else
    {
    
    
        GPIO_A_OFF();
    }
    if (stop & 0x02)
    {
    
    
        GPIO_B_ON();
    }
    else
    {
    
    
        GPIO_B_OFF();
    }
    if (stop & 0x04)
    {
    
    
        GPIO_C_ON();
    }
    else
    {
    
    
        GPIO_C_OFF();
    }
    if (stop & 0x08)
    {
    
    
        GPIO_D_ON();
    }
    else
    {
    
    
        GPIO_D_OFF();
    }
}
/**
 * @brief       步进电机转动 连续转动没有抖动
 * @param       dir 方向 1是正向 0是反向
 * @retval      无
 */
void stepMotor_8(uint8_t dir)
{
    
    
		if (dir == 1)
				stepx = (stepx + 1) % 8;
    else if (dir == 0)
        stepx = (stepx + 7) % 8;
    step = motorSequence_8[stepx];
    if (step & 0x01)
    {
    
    	
				GPIO_A_ON();
    }
    else
    {
    
    
        GPIO_A_OFF();
    }
    if (step & 0x02)
    {
    
    
        GPIO_B_ON();
    }
    else
    {
    
    
        GPIO_B_OFF();
    }
    if (step & 0x04)
    {
    
    
        GPIO_C_ON();
    }
    else
    {
    
    
        GPIO_C_OFF();
    }
    if (step & 0x08)
    {
    
    
        GPIO_D_ON();
    }
    else
    {
    
    
				GPIO_D_OFF();
    }
}
/**
 * @brief       步进电机转动 连续转动没有抖动
 * @param       dir 方向  方向 1是正向 0是反向
 * @param       Step 步数
 * @retval      里面用到了delay_ms阻塞函数
 */
void Move_Step_8(uint8_t dir, uint16_t Step)
{
    
    
    uint16_t Count = Step; // 步数
    while (Count--)
    {
    
    
        stepMotor_8(dir);
        delay_ms(1);
    }
}

main.c テスト

int main(void)
{
    
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    step_motor_init();                          /* 初始化步进电机 */
    while(1)
    {
    
    
				Move_Step_8(1, 2500); //步进电机正转2500步
        delay_ms(500);
				Move_Step_8(0, 2500); //步进电机反转2500步
        delay_ms(500);
    }
}

ここに画像の説明を挿入します

問題の結論

1. 問題が発生した場合は、ピン定義、ピンクロック定義、グループ定義を確認してください。

//在这里配置引脚 A-D
#define MOTOR_GPIO_PORT                 GPIOB
#define MOTOR_GPIO_PIN_A                GPIO_PIN_3
#define MOTOR_GPIO_PIN_B                GPIO_PIN_4
#define MOTOR_GPIO_PIN_C                GPIO_PIN_5
#define MOTOR_GPIO_PIN_D                GPIO_PIN_6
#define MOTOR_GPIO_CLK_ENABLE()         do{
      
       __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) 

2. モーターがジッターする場合は、遅延を変更して増加または減少させます。

void Move_Step_8(uint8_t dir, uint16_t Step)
{
    
    
    uint16_t Count = Step; // 步数
    while (Count--)
    {
    
    
        stepMotor_8(dir);
        delay_ms(1);    <--------更改这里
    }
}
``

おすすめ

転載: blog.csdn.net/Systemmax20/article/details/132251981