Шаговый двигатель – это специальный тип электродвигателя, который осуществляет вращение небольшими шагами. Можно регулировать скорость и направление его вращения, а также число шагов, на которое должен "повернуться" двигатель. Существует два основных типа шаговых двигателей: униполярные и биполярные. Униполярные проще в управлении и использовании, а также дешевле. В данной статье мы рассмотрим подключение шагового двигателя 28BYJ-48 к микроконтроллеру PIC16F877A.
Шаговый двигатель 28BYJ-48 является униполярным, он прост в использовании и сравнительно недорог. Работает он от 5V постоянного тока (5V DC). Для управления им мы будем использовать микросхему драйвера шаговых двигателей ULN2003, которая представляет собой массив пар Дарлингтона (Darlington pair array). Она выдерживает ток нагрузки до 500mA. Использование данной микросхемы в нашем проекте обусловлено тем, что выдерживаемый контактами микроконтроллера PIC ток недостаточен для управления шаговым двигателем.
Также на нашем сайте мы рассматривали подключение шагового двигателя к другим микроконтроллерам (платам):
Необходимые компоненты
- Микроконтроллер PIC16F877A (купить на AliExpress).
- Шаговый двигатель 28BYJ-48 (купить на AliExpress).
- Драйвер шаговых двигателей ULN2003 (купить на AliExpress).
- Программатор PICkit 3 (купить на AliExpress).
- Кварцевый генератор 20 МГц (купить на AliExpress).
- Конденсаторы 33 пФ (2 шт.) (купить на AliExpress).
- Резистор 4,7 кОм (купить на AliExpress).
- Напряжение питания 5V с током не менее 500mA.
- Макетная плата.
- Соединительные провода.
Шаговый двигатель 28BYJ-48
Внешний вид шагового двигателя 28BYJ-48 и его характеристики представлены на следующих рисунке.
Некоторые наиболее важные технические характеристики этого шагового двигателя приведены на следующем рисунке.
Распиновка шагового двигателя 28BYJ-48 приведена на следующем рисунке.
Как вы видите из представленного рисунка внутри двигателя находятся две катушки с отводами от их центральных частей. Красный провод является общим для обоих катушек и подключается к напряжению питания (VCC 5V).
Остальные 4 провода (розовый, красный, желтый и синий) используются для управления вращением шагового двигателя. Существует 3 режима управления вращением данного двигателя: режим полного шага, режим полушага и режим волнового управления.
Режим полного шага (Full Drive)
Если на оба статора двигателя одновременно подается питание, то двигатель делает один полный с полным крутящим моментом. Последовательность управления для данного режима представлена в следующей таблице.
Шаг | Синий | Розовый | Желтый | Оранжевый |
1 | 1 | 1 | 0 | 0 |
2 | 0 | 1 | 1 | 0 |
3 | 0 | 0 | 1 | 1 |
4 | 1 | 0 | 0 | 1 |
Режим полушага (Half-Drive)
Его также называют режимом восьмитактной коммутации. В этом случае двигатель поочередно делает шаг и находится в режиме удержания, то есть работает по алгоритму: шаг – остановка – шаг – остановка и т.д. Вэтом случае также, как и в предыдущем, шаг делается только тогда, когда ток протекает через две обмотки двигателя. При остановке ток протекает только через одну фазу, которая в этот момент становится обмоткой удержания и фиксирует положение ротора. Достоинством данного режима по сравнению с режимом полного шага является более высокое угловое разрешение, а недостатком – меньший крутящий момент. Последовательность управления для данного режима представлена в следующей таблице.
Шаг | Синий | Розовый | Желтый | Оранжевый |
1 | 1 | 0 | 0 | 0 |
2 | 1 | 1 | 0 | 0 |
3 | 0 | 1 | 0 | 0 |
4 | 0 | 1 | 1 | 0 |
5 | 0 | 0 | 1 | 1 |
6 | 0 | 0 | 0 | 1 |
7 | 1 | 0 | 0 | 1 |
8 | 1 | 0 | 0 | 0 |
Режим волнового управления (Wave Drive)
В этом режиме питание подается на один статор. Для совершения шага нужно также 4 действия, как и в режиме полного шага. В данном режиме двигатель потребляет меньше энергии, но соответственным образом уменьшается и его крутящий момент.
Шаг | Синий | Розовый | Желтый | Оранжевый |
1 | 1 | 0 | 0 | 0 |
2 | 0 | 1 | 0 | 0 |
3 | 0 | 0 | 1 | 0 |
4 | 0 | 0 | 0 | 1 |
Драйвер шагового двигателя ULN2003
Внешний вид драйвера шагового двигателя ULN2003 приведен на следующем рисунке.
На этом рисунке контакты, обозначенные надписью желтого цвета, используются для подключения двигателей, а контакты, обозначенные розовым цветом – для подключения микроконтроллера. Также необходимо установить правильное положение джампера, обозначенного красным цветом чтобы он подключал диод, обеспечивающий защиту двигателя.
В нашем проекте мы будем вращать двигатель в режиме полного шага сначала по часовой стрелке, а потом против часовой стрелки. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
Схема проекта
Схема подключения шагового двигателя 28BYJ-48 к микроконтроллеру PIC представлена на следующем рисунке.
Соединения между драйвером ULN2003A и микроконтроллером PIC16F877A следующие:
A.IN1 => Pin33
B.IN2 => Pin34
C.IN3 => Pin35
D.IN4 => Pin36
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Объяснение программы для микроконтроллера PIC
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе мы должны настроить биты конфигурации микроконтроллера и подключить заголовочные файлы необходимых библиотек. После этого мы можем переходить к функции void main.
1 2 3 4 5 |
#define _XTAL_FREQ 200000000 //Crystal Frequency, used in delay #define speed 1 // Speed Range 10 to 1 10 = lowest , 1 = highest #define steps 250 // how much step it will take #define clockwise 0 // clockwise direction macro #define anti_clockwise 1 // anti clockwise direction macro |
В коде программы мы будем использовать три функции (которые соответствуют режимам полного шага, полушага и режиму волнового управления) для вращения двигателя по часовой и против часовой стрелки:
- void full_drive (char direction).
- void half_drive (char direction).
- void wave_drive (char direction).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void main(void) { system_init(); while(1){ /* Drive the motor in full drive mode clockwise */ for(int i=0;i<steps;i++) { full_drive(clockwise); } ms_delay(1000); /* Drive the motor in wave drive mode anti-clockwise */ for(int i=0;i<steps;i++) { wave_drive(anti_clockwise); //full_drive(anti_clockwise); } ms_delay(1000); } } |
Исходный код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
/* * File: main.c * Author: Sourav Gupta * By:- circuitdigest.com * Created on May 10, 2018, 1:26 PM * This program will drive a servo motor. */ // PIC16F877A Configuration Bit Settings // 'C' source line config statements // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include <xc.h> #include <stdio.h> /* Hardware related definition */ #define _XTAL_FREQ 200000000 //Crystal Frequency, used in delay #define speed 1 // скорость вращения в диапазоне от 10 до 1; 10 = самая низкая , 1 = самая высокая #define steps 250 // число шагов для полного оборота в шаговом двигателе #define clockwise 0 // clockwise direction macro (макрос для вращения по часовой стрелке) #define anti_clockwise 1 // anti clockwise direction macro (макрос для вращения против часовой стрелки) /* *Application related function and definition */ void system_init (void); // функция для инициализации портов микроконтроллера void full_drive (char direction); // функция для вращения двигателя в режиме полного шага void half_drive (char direction); // функция для вращения двигателя в режиме полушага void wave_drive (char direction); // функция для вращения двигателя в режиме волнового управления void ms_delay(unsigned int val); /* * main function starts here */ void main(void) { system_init(); while(1){ /* вращаем двигатель в режиме полного шага по часовой стрелке */ for(int i=0;i<steps;i++) { full_drive(clockwise); } ms_delay(1000); /* вращаем двигатель в режиме волнового управления против часовой стрелки */ for(int i=0;i<steps;i++) { wave_drive(anti_clockwise); //full_drive(anti_clockwise); } ms_delay(1000); } } /*System Initialising function to set the pin direction Input or Output*/ void system_init (void){ TRISB = 0x00; // контакты PORT B на вывод данных PORTB = 0x0F; } /*This will drive the motor in full drive mode depending on the direction*/ void full_drive (char direction){ if (direction == anti_clockwise){ PORTB = 0b00000011; ms_delay(speed); PORTB = 0b00000110; ms_delay(speed); PORTB = 0b00001100; ms_delay(speed); PORTB = 0b00001001; ms_delay(speed); PORTB = 0b00000011; ms_delay(speed); } if (direction == clockwise){ PORTB = 0b00001001; ms_delay(speed); PORTB = 0b00001100; ms_delay(speed); PORTB = 0b00000110; ms_delay(speed); PORTB = 0b00000011; ms_delay(speed); PORTB = 0b00001001; ms_delay(speed); } } /* This method will drive the motor in half-drive mode using direction input */ void half_drive (char direction){ if (direction == anti_clockwise){ PORTB = 0b00000001; ms_delay(speed); PORTB = 0b00000011; ms_delay(speed); PORTB = 0b00000010; ms_delay(speed); PORTB = 0b00000110; ms_delay(speed); PORTB = 0b00000100; ms_delay(speed); PORTB = 0b00001100; ms_delay(speed); PORTB = 0b00001000; ms_delay(speed); PORTB = 0b00001001; ms_delay(speed); } if (direction == clockwise){ PORTB = 0b00001001; ms_delay(speed); PORTB = 0b00001000; ms_delay(speed); PORTB = 0b00001100; ms_delay(speed); PORTB = 0b00000100; ms_delay(speed); PORTB = 0b00000110; ms_delay(speed); PORTB = 0b00000010; ms_delay(speed); PORTB = 0b00000011; ms_delay(speed); PORTB = 0b00000001; ms_delay(speed); } } /* This function will drive the the motor in wave drive mode with direction input*/ void wave_drive (char direction){ if (direction == anti_clockwise){ PORTB = 0b00000001; ms_delay(speed); PORTB = 0b00000010; ms_delay(speed); PORTB = 0b00000100; ms_delay(speed); PORTB = 0b00001000; ms_delay(speed); } if (direction == clockwise){ PORTB = 0b00001000; ms_delay(speed); PORTB = 0b00000100; ms_delay(speed); PORTB = 0b00000010; ms_delay(speed); PORTB = 0b00000001; ms_delay(speed); } } /*функция для создания необходимого значения задержки*/ void ms_delay(unsigned int val) { unsigned int i,j; for(i=0;i<val;i++) for(j=0;j<1650;j++); } |