کنترل و راه‌اندازی استپر موتور توسط میکروکنترلر STM32F103C8

الکترونیک و رباتیک -> انواع موتور و درایور صنعتی 2968 2 کاربر آکادمی پارتینه

استپر موتور چیست؟
استپر موتور یک موتور DC است که در گام هایی گسسته حرکت می‌کند. استپرها به دلیل توانایی چرخش شافت خود در یک موقعیت دقیق و ایجاد گشتاور بالا جزو محبوب ترین موتورهای DC در صنعت به شمار می‌روند. امکان کنترل سرعت گام‌ها و موقعیت بدون نیاز به اعمال مکانیزم کنترلی حلقه بسته نیز از دیگر مشخصات مهم استپرها است.

اگرچه میزان مصرف توان و انرژی استپرها درمقایسه با سایر موتورهای DC بیشتر بوده و راه‌اندازی آن  نسبتا سخت‌تر است، اما با یادگیری عمیق و درست مکانیزم کارکرد آنها، برای همیشه می‌توان از قابلیت‌ بهره این موتورها بهره برد. از استپرها می‌توان در سیستم‌هایی که نیاز به دقت بالا دارند مانند بازوهای روباتیکی ، پرینترهای سه‌بعدی ، اسکنرها ، فلاپی و دی وی دی درایو ها و ماشین‌های cnc استفاده کرد. برخلاف موتورهای DC جاروبک‌دار که تا مادامی که به ترمینال‌های آنها ولتاژ اعمال شود به حرکت پیوسته ادامه می‌دهند، استپرها جزو موتورهای DC براشلس محسوب می‌شوند. بدین معنا که با اعمال پالس به ترمینال‌های آن ( عموما پالس های موج مربعی ) موقعیت شفت یا محور موتور به میزان مشخص و از پیش تعیین شده ای دوران می‌کند. آنها دارای سیم‌پیچ و آهنربای دائمی هستند که شافت را می چرخانند.

در این آموزش نحوه‌ی راه‌اندازی یک استپر موتور نما 17 دو فاز 1.8 درجه با درایور A4988 توسط میکروکنترلر Stm32f103c8t6  مورد بررسی قرار می‌گیرد.

مواد اولیه :
# عنوان تعداد لینک
0 برد مینی آرم STM32F051C8T6 1 لینک خرید
1 استپر موتور نما 17 1 لینک خرید
2 درایور A4988 1 لینک خرید
3 منبع تغذیه 1 لینک خرید

مرحله 1 : اتصالات و دیاگرام مداری

مروری بر مشخصات درایور استپر موتور A4988

استپر موتورها در حالت عادی حداکثر نیاز به 1 آمپر جریان دارند. بنابراین استفاده از منبعی که این میزان انرژی را تعمین کند ضروری است. یک تکنیک قدیمی برای طراحی درایور استفاده از مدار H-Bridge با استفاده از ترانزیستور یا ماسفت است که می تواند مقدار کافی انرژی را برای استپر تأمین کرده و آن را به راحتی هدایت کند.

 به دلیل وقت‌گیر بودن طراحی وساخت مدار H-Bridge توصیه می‌شود از درایورهای ارزان قیمت و مونتاژ شده‌ی H-Bridge  که در بازار موجود است، مانند A4988 و ... استفاده شود. این درایور می‌تواند از 1 آمپر تا 2 آمپر جریان با ولتاژ 8 تا 35 ولت را تامین کند. در تصویر بالا درایور و مدار معادل آن نشان داده شده است. تغذیه‌ی بخش دیجیتال 3 تا 5 ولت ( پین‌های VDD و  (Gnd و ولتاژ ورودی درایور 8 تا 35 ولت  (پین‌هایVMOT و     (GND است. هر زمان که یک پالس از جانب پین STEP درایور به پردازنده ارسال شود، یک گام طی می‌شود. پین DIR نیز جهت حرکت استپر را کنترل می‌کند. پین‌های MS2 ، MS1 و MS3  تعداد میکرواستپ‌ها را مشخص می‌کند.

دیاگرام مداری  

برای تغذیه این درایور از یک باتری 9 ولت استفاده شده است. یک خازن 100 میکرو فاراد به منظور جلوگیری از ایجاد اسپایک AC در ورودی تغذیه قرارداده شده است. این استپر موتور نما 17 چهار سیمه بوده که با شناسایی درست، قطب‌های آن به پین‌های A1A2B1B2 درایور متصل می‌شوند. برای تغذیه‌ی بخش دیجیتال درایور از خروجی 3.3 ولت STM32 استفاده می‌شود. در این پروژه استپر در حالت گام کامل راه اندازی شده است. بنابراین نیازی به اتصال Ms2 ، Ms1 و Ms3 نیست. چون به صورت پیش فرض LOW هستند. در گام آخر پین Step درایور به پین 4 پورت A و پین  Direction به پین 3 پورت A  متصل می‌شود. 

مرحله 2 : کدنویسی و تنظیمات نرم‌افزاری

کد پروژه در کامپایلر Keil تنظیم شده است. برای تنظیمات اولیه نوسان‌ساز و رجیسترها از واسط گرافیکی  Stm32cubemx استفاده شده است. دو پین از پورت A میکروکنترلر به عنوان خروجی جهت کنترل پین‌های Step و Direction درایور نیز در گرفته شده‌اند.

در حلقه اصلی برنامه پین Direction به منظور چرخش موتور در جهت ساعتگرد High می‌شود. سپس به منظور چرخش یک دور کامل 360 درجه در حلقه for 200 گام طی می‌شود. 

HAL_GPIO_WritePin(GPIOA, DIR_Pin, GPIO_PIN_SET);//Clock wise rotation

سپس جهت چرخش عوض شده و مجددا موتور 200 گام به عقب و به نقطه‌ی اولیه برمی‌گردد.

#include "main.h"
#include "stm32f1xx_hal.h"
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* Infinite loop */
  while (1)
  {

		HAL_GPIO_WritePin(GPIOA, DIR_Pin, GPIO_PIN_SET);//Clock wise rotation
		
		for(int i=1;i<=200;i++){  //Moving stepper motor forward
			HAL_GPIO_WritePin(GPIOA, STEP_Pin, GPIO_PIN_SET);
			HAL_Delay(50);
			HAL_GPIO_WritePin(GPIOA, STEP_Pin, GPIO_PIN_RESET);
			HAL_Delay(50);
		}
		
	HAL_GPIO_WritePin(GPIOA, DIR_Pin, GPIO_PIN_RESET);//Anti clock wise rotation
		
		for(int j=1;j<=200;j++){  //Moving stepper motor forward
			HAL_GPIO_WritePin(GPIOA, STEP_Pin, GPIO_PIN_SET);
			HAL_Delay(50);
			HAL_GPIO_WritePin(GPIOA, STEP_Pin, GPIO_PIN_RESET);
			HAL_Delay(50);
		}	
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, DIR_Pin|STEP_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : DIR_Pin STEP_Pin */
  GPIO_InitStruct.Pin = DIR_Pin|STEP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void _Error_Handler(char *file, int line)
{
  while(1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
#endif /* USE_FULL_ASSERT */