Главная » Микроконтроллеры
Призовой фонд
на июль 2017 г.
1. Осциллограф DSO138
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 200 руб.
От пользователей

МК-управление микрошаговым драйвером LB1847 из старого принтера

Данная статья родилась в помыслах изготовить себе трёх-координатный микростанок с ЧПУ для выполнения некоторых минимальных задач по сверлению, фрезерованию и вырезке печатных плат.
В течение некоторого времени мне очень часто на запчасти отдают старые матричные и струйные принтеры по причинам того, что хозяева решили купить себе новый и более совершенный принтер или МФУ, ибо старенький свой принтер уже морально устарел или его ремонт будет стоить соизмеримо с приобретением нового принтера, а старый попросту выкинули.
После разборки и выброса ненужных пластмассовых деталей и внутренней механики, я себе оставлял только печатные платы, шаговые двигатели с пасиками и стальные направляющие, по которым когда-то бегала печатающая головка. Давным-давно я посматривал в них на интересную микросхему, которая питает тамошние шаговые двигатели.
Просто запросив в поиске даташит на данную микросхему, я увидел в ней не просто драйвер с четырьмя парами ключей, а полноценный микрошаговый ШИМ контроллер.

Итак, микросхема LB1847 (даташит PDF) - это драйвер для шаговых двигателей с широтно-импульсным управлением током обмоток биполярного двигателя.
Особенностью данной микросхемы является возможность установки тока на обмотки двигателя в 15 шагов в любой полуфазе.
С возможностью установки медленного затухания тока, быстрого спада тока или смешанного режима, тем самым повышая частотные характеристики, которыми можно добиться высокоточного управления и получить наименьшие вибрации двигателя.

Не буду заниматься комментированием оригинального даташита, вы просто можете запросить его в поиске, найти во вложении к статье и самостоятельно изучить характеристики. Я же двинусь далее.

Схема подключения довольно простая. 

lb1847.jpg

 В считанные минуты была нарисована печатка и при помощи ЛУТа сделана плата, обвязку из резисторов, конденсаторов и диодов Шоттки, тоже снял со старой платы:

plat.jpg

Далее это все было подключено к одной из моих самодельных тестовых плат с микроконтроллером Atmega32. Конечно, можно использовать любую доступную вам, но нужно учитывать, что должно хватать выводов для подключения, так как на управление используется аж 12 линий.

В моём случае изначально тестировался максимально возможный режим работы драйвера в режиме Phase 4W1-2, но потом посчитал что это уже чересчур и настолько уже сверх-точность мне не нужна, потому и перевел на режим Phase 2W1-2, тем самым просмотрев данную таблицу выявил закономерность по первым входам каждого плеча драйвера - на них постоянно присутствует логическая "1" в нужном для меня режиме.

PWM_port_medium.jpg

Ну и пусть, просто подключим их на питание микросхемы и забудем про них.

Так мы сократили количество используемых выводов до 10. При дальнейшем исследовании этой таблицы явно заметно, что вывод ENABLE получая логическую "1" (просто обесточивает канал, давая возможность другому каналу притянуть к себе магнитный ротор на максимальном токе), и при этом не имеет значения в какой фазе этот канал находится.

Сразу заметно, что та самая единица появляется тогда как на входах 2-3-4 каждого канала присутствует логический "0". Тут просто вспомним о справочнике микросхем логики и найдем нужный для нас логический элемент. Нам понадобится два элемента 3ИЛИ-НЕ, выбираем микросхему, импортная 7427, отечественная К155ЛЕ4 или подобные.

Принципиальная схема:

Схема

Обвязку полного подключения LB1847 не изображал, так как она ничем не отличается от той, что в даташите. На Vref временно поставил проволочный подстроечный резистор.

Как видно, теперь мы используем только 8 выводов для управления, чего вполне достаточно для использования одного полного порта микроконтроллера.

Теперь приступим к программированию нашего микроконтроллера. Для этого нам потребуется предварительно рассчитать значение выхода целого порта микроконтроллера для каждого микрошага.

Тут я просто использовал программу Excell, где создал таблицу и встроенными формулами рассчитал значение PORTB для режима Phase 2W1-2 (учтите, что пример в даташите указан только для одной фазы, необходимо продублировать его для второй с изменением направления тока через обмотки).

excell.jpg

Сразу забегу вперед. Я изначально вдоволь наигрался как заданием статических величин по значениям перемещения вала, так и с вводом значения перемещения через порт RS232, но потом всё же захотелось вручную лицезреть сие детище и подключил энкодер, дабы насладиться механическим управлением с визуальным вращением вала шагового двигателя.

mc210_sch2.png

Программировал на CodeVisionAVR.

Микроконтроллер Atmega32, Кварц 16МГц, PORTB весь на выход, PC0 и PC1 на вход с подтяжкой к шине питания, настраиваем таймер на обработку прерывания каждые 10 микросекунд.
 
Сначала объявим переменные
unsigned int timerCNC=0;                // Счетчик-Таймер ожидания готовности к смене шага
unsigned long int CNC1required=25000;   // Начальное требуемое значение шага
char flagCNC1;                          // Флаг разрешения обработки шага
#define CNC1steps 32                    // Количество шагов для 1/32 шага в обоих полюсах двух фаз 
unsigned long int CNC1point=25000;      // Начальная/текущая точка положения шага
unsigned char CNC1counter=0;            // Счетчик смещения. В дальнейшем приведем к значению маски в 32 варианта смещения
unsigned long EncState;                 // Состояние энкодера.
unsigned char step[CNC1steps] =         // Массив значений для шагания
{ 
0b01110000, //0
0b01110010, //1
0b00110100, //2
0b01010110, //3
0b00011000, //4
0b01101010, //5
0b00101100, //6
0b01001110, //7
0b00001110, //8
0b11001110, //9
0b10101100, //10
0b11101010, //11
0b10011000, //12
0b11010110, //13
0b10110100, //14
0b11110010, //15
0b11110000, //16
0b11110011, //17
0b10110101, //18
0b11010111, //19
0b10011001, //20
0b11101011, //21
0b10101101, //22
0b11001111, //23
0b00001111, //24
0b01001111, //25
0b00101101, //26
0b01101011, //27
0b00011001, //28
0b01010111, //29
0b00110101, //30
0b01110011};//31

 

Функция опроса энкодера

void EncoderScan (void){

unsigned char New;

New = PINC & 0x03;    // Берем текущее значение 

// И сравниваем со старым

switch(EncState)
    {
    case 2:
        {
            if(New == 3){
            CNC1required++;
            };

            if(New == 0){
            CNC1required--;
            }; 
        break;
        }

    case 0:
        {
            if(New == 2){
            CNC1required++;
            };

            if(New == 1){
            CNC1required--;
            };
        break;
        }
    case 1:
        {
            if(New == 0){
            CNC1required++;
            };

            if(New == 3){
            CNC1required--;
            };
        break;
        }
    case 3:
        {
            if(New == 1){
            CNC1required++;
            };
                
            if(New == 2){
            CNC1required--;
            };
        break;
        }
    }
 
EncState = New;        // Записываем новое значение предыдущего состояния
}

Функция опроса энкодера не имеет никаких особенностей, банально читает значения с выводов и по их изменению добавляет или отнимает значение счетчика, тем самым диктуя главной программе направление на вращения. Единственное что опрос у меня сейчас проходит на частоте 100кГц, и мне было лень добавлять отдельный счетчик (три строчки программы), чтобы отсчитывать только полные щелчки оборота энкодера, да это и совсем не нужно на данной стадии тестовых испытаний. 

 

Обработчик прерывания таймера

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xEC;
// Place your code here

EncoderScan(); // Производим опрос энкодера

//Счетчик временной задержки между шагами
//Чтоб не пропустить шаг на высокой скорости
timerCNC++;
if(timerCNC == 100) {       //Если значение достигло 
flagCNC1=1;                 //разрешаем шагнуть
timerCNC=0;                 //перезапускаем счетчик  
}

Обработчики шагов

// Обработчик прибавления шагов
// задается значение S на количество шагов перемещения вверх
void STEP_UP (unsigned char s)
    {
    if (flagCNC1){                  //Проверяем флаг разрешения смещения

    unsigned char q;

    CNC1counter +=s;                //Записываем новое значение смещения
    q = CNC1counter & 0b00011111;   //Получаем номер значения из CNC1steps по маске
    PORTB = step[q];                //Производим запись в порт нужный байт шага                
    CNC1point+=s;                   //Добавляем новое значения текущего положения двигателя 

    flagCNC1=0;                     //Очищаем флаг, смещение завершено, шаг выполнен.
    }
}

Аналогичная функция на обработку обратного счета для движения оси шагового двигателя в обратную сторону.

// Обработчик вычитания шагов
// задается значение S на количество шагов перемещения вниз
void STEP_DOWN (unsigned char s)
    {
    if (flagCNC1){
    unsigned char q;
    CNC1counter -=s;
    q = CNC1counter & 0b00011111;
    PORTB = step[q];
    CNC1point-=s;

    flagCNC1 = 0;
    }

В данную функцию я ввел очень полезную величину, можно задать шаг работы двигателя от 1 до 8. Это я и хочу использовать в дальнейшем, чтобы можно было программно управлять скоростью перемещения.

Например: для холостого перемещения на пару тысяч шагов можно составить простой алгоритм, который может плавно начать с одного микрошага за такт разрешения таймера, и каждые 10 тактов поднимать на единицу пока не достигнет "8", так будет программно реализован четверть шаг (счетчик тоже будет добавлять или отнимать по 8 шагов), а далее за 100 шагов до окончания пути начать уменьшать значение перешагивания каждые 10 тактов и двигатель плавно остановится на нужном ему значении. Такая реализация программно обеспечит высокую скорость перемещения при максимальной точности перемещения вала двигателя даже под нагрузкой (старт-разгон-работа-торможение-остановка). Можно, конечно, поднять значение и до 16, в таком случае двигатель выйдет на режим полушага.

Главный цикл программы

void main(void)
{
//
// Код инициализации микроконтроллера
//

PORTB = step[0];  // После включения записываем в порт нулевое значение шага

while (1)
    {
    // Обработка циклического перемещения пока CNC1required не станет равным CNC1point

          while (CNC1required>CNC1point)  
          {
            STEP_UP(1); 
          }
          while (CNC1required < CNC1point)  
          {
            STEP_DOWN(1);
          }
    }
}

Для проверок использовался один из биполярных шаговых двигателей с тех самых разобранных принтеров.

P5113956.jpg

Он имеет шаг 7,5 градусов, что соответствует 48 шагам на полный оборот, при 32 микрошагах это выходит точность 1536 микрошагов на полный оборот вала двигателя. Если бы нам не было жалко использовать еще 2 вывода микроконтроллера, то легко можно получить 1/64 шага. А присмотревшись в конструктив этой микросхемы, думаю несложно и поболее 128 шагов сделать, только придется много расчетов произвести на усредненные значения, правда будет серьёзная нелинейность вращения, но и то что мы получили вполне достаточно, незачем нам вращение менее 0,1 градуса.

Энкодер, что я нашел у себя, имеет 24 щелчка на полный оборот, в каждом щелчке 4 импульса изменения состояния, то есть 96 импульсов на полный оборот.

Без использования энкодера программно запускал его на довольно быстрое вращение и действительно чувствовалась сила на валу при том, что я его питаю 12V вместо 24V родного питания принтера.

Вот посмотрите что из этого вышло.

При необходимости можно сохранять в энерго-независимой памяти текущие значения шага, и использовать его при отключениях устройства, только заранее привести значение к нулевому, ибо после отключения-включения устройства полушаг может провернуть вал как в одну, так и в другую сторону. Или просто использовать калибровку (например, на оптопаре или концевике) при включении устройства.

Данная статья была предварительным тестом работы микросхемы LB1847, все собрано практически на коленке, только для уточнения всех нюансов её работы. Далее планируется использовать более продвинутый микроконтроллер (скорее всего STM32) и организация одновременного управления тремя (и более) двигателями.

При необходимости можно еще дополнительно вывести на МК выводы DECAY, MD и программно управлять режимом спада тока при различных условиях.

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
Cхема №1
МикросхемаLB18471 Поиск в FivelВ блокнот
SBDx4 Диод4 Поиск в FivelВ блокнот
Конденсатор470 пФ2 Поиск в FivelВ блокнот
Конденсатор10 мкФ1 Поиск в FivelВ блокнот
Конденсатор47 мкФ1 Поиск в FivelВ блокнот
Резистор
0.51 Ом
2 Поиск в FivelВ блокнот
Резистор
15 кОм
2 Поиск в FivelВ блокнот
Lx2 Катушка индуктивности2 Обмотки шагового двигателяПоиск в FivelВ блокнот
Батарея питания1.5 В1 Поиск в FivelВ блокнот
Батарея питания5 В1 Поиск в FivelВ блокнот
Батарея питания42 В1 Поиск в FivelВ блокнот
Схема №2
МикросхемаLB18471 Поиск в FivelВ блокнот
Микросхема74271 К155ЛЕ4Поиск в FivelВ блокнот
Электролитический конденсатор10 мкФ1 Поиск в FivelВ блокнот
Переменный резистор5 кОм1 Поиск в FivelВ блокнот
Блок питания+5 В +12 В1 Поиск в FivelВ блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: Изменена: 14.05.2013 0 0
Я собрал 0 Участие в конкурсе 2
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 3.8 Проголосовало: 2 чел.

Комментарии (13) | Я собрал (0) | Подписаться

0
Руслан #
Могли бы Вы расписаться подробный алгоритм работы программы. Я с кодом не дружку и работаю через Flowcode. Поэтому придется собирать код с нуля.
Ответить
0

[Автор]
Wolf79 #
В статье и так подробно все описано, код с комментариями, единственно по опросу энкодера (если он Вам нужен), подобрать соответствующую опцию в Flowcode.
Ответить
0
Винни #
На Enable удобнее подавать сигнал ШИМ...
Ответить
0

[Автор]
Wolf79 #
Зачем на него ШИМ подавать? Это логический вход, который просто отключает канал, давая другому на максимальном токе притянуть шаг, то есть нейтральное положение между шагами переключения фазы.
Ответить
0
Винни #
Извините - невнимательно прочитал статью и не посмотрел даташит. М/с показалась похожей на L298 - у неё на enable можно постоянно подать лог 1 или ШИМ. ШИМ актуален при управлении обычными электродвигателями
Ответить
0
Иван #
Не очень понял как в Excell рассчитать массив для Phase 4W1-2.
Ответить
0

[Автор]
Wolf79 #
Excel использовался только для удобства группировки битов, по типу ="0b"&A1&C1&E1&G1&B1&D1&F1&H1.
Для этого нужно заполнить все значения по микрошагам
Потом полученное значение писать в порт в результирующем формате 0b11110000 или привести его в НЕХ или десятичную.
Ответить
0
Иван #
Не могу найти микросхему логики, не могли бы написать функцию, чтобы обойтись без логики?
Ответить
0

[Автор]
Wolf79 #
Видимо Вы не внимательно прочитали.
В статье описана функция микросхемы логики
Элемент 3ИЛИ-НЕ = "1" на выходе появляется когда на всех входах присутствует логический "0", в любых других случаях на выходе элемента постоянный "0". Если есть пара свободных ног микросхемы, то можно их даже на другом порту реализовать, только программу придется немного дописать для проверки состояний выхода рабочего порта и сравнения по маске (так я делал на первых включениях, потом уже микросхему приделал чтоб разгрузить МК от не нужных функций).
Ответить
0
Иван #
Добавил в прерывания.
Вроде в протеусе порты заблыкали нормально, проверю в железе отпишусь
if(PORTC==0x70)
PORTA = b00000100;
if(PORTC==0x0e)
PORTA = b00001000;
if(PORTC==0xf0)
PORTA = b00000100;
if(PORTC==0x0f)
PORTA = b00001000;
Ответить
0
Иван #
У вас тоже слышно как работает ШИМ драйвера или это у меня не качественный двигатель?
Ответить
0

[Автор]
Wolf79 #
У меня слышно ШИМ только если ухо к двигателю прислонить (меняется тон при шагании), если на микросхеме слышите, то наверняка где-то с напряжениями не учли что-то, либо в массиве шагов допустили ошибку. Возможно программное прерывание (что вы реализовали для выводов ENABLE ) не корректное - если на смене фазы он не держит четкую "1" - тогда точно будет слышно работу ШИМ на драйвере. Проверьте осциллографом выводы ENABLE на переходах фаз обмоток
Ответить
0
Dj_smart #
Вопрос такого плана. Нет исходника под степ-дир? В нынешних условиях и при наших пенсиях... Короче раритеты в цене
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
ELM327 OBD II — адаптер с поддержкой CAN Регулятор мощности 2 кВт
вверх