Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Управление шаговыми двигателями


Управление шаговыми двигателями

Сообщений 1 страница 30 из 31

1

Уважаемые форумчане.

Есть проблема - необходимо сделать управление парой шаговых двигателей на ATMega16
Само управление - это вызов соответствующих подпрограмм через Gosub в зависимости от сигналов на портах
Проблема в следующем. Не получается одновременного перемещения двигателей. Сначала отрабатывает один, затем -- другой, затем снова первый и т.д.

Можно ли как-то обеспечить их параллельную работу?

Спасибо!

Код:
'************  управляющая программа
Do
If Pinb.0 = 1 Then Gosub Azimuth_right
If Pinb.1 = 1 Then Gosub Azimuth_left
If Pinb.2 = 1 Then Gosub Tilt_up
If Pinb.2 = 1 Then Gosub Tilt_down
Loop
End

'************ подпрограммы перемещения
Azimuth_right:

Portd = &B00000001 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00000011 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00000010 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00000110 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00000100 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00001100 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00001000 : Incr Azimuth : Waitms Azimuth_speed
Portd = &B00001001 : Incr Azimuth : Waitms Azimuth_speed

Return


'************* Азимут - Вращение влево
Azimuth_left:

Portd = &B00001001 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00001000 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00001100 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00000100 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00000110 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00000010 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00000011 : Decr Azimuth : Waitms Azimuth_speed
Portd = &B00000001 : Decr Azimuth : Waitms Azimuth_speed

Return


'************* Угол места - Вращение вверх
Tilt_up:

Portc = &B00000001 : Incr Tilt : Waitms Tilt_speed
Portc = &B00000011 : Incr Tilt : Waitms Tilt_speed
Portc = &B00000010 : Incr Tilt : Waitms Tilt_speed
Portc = &B00000110 : Incr Tilt : Waitms Tilt_speed
Portc = &B00000100 : Incr Tilt : Waitms Tilt_speed
Portc = &B00001100 : Incr Tilt : Waitms Tilt_speed
Portc = &B00001000 : Incr Tilt : Waitms Tilt_speed
Portc = &B00001001 : Incr Tilt : Waitms Tilt_speed

Return


'************* Угол места - Вращение вниз
Tilt_down:

Portc = &B00001001 : Decr Tilt : Waitms Tilt_speed
Portc = &B00001000 : Decr Tilt : Waitms Tilt_speed
Portc = &B00001100 : Decr Tilt : Waitms Tilt_speed
Portc = &B00000100 : Decr Tilt : Waitms Tilt_speed
Portc = &B00000110 : Decr Tilt : Waitms Tilt_speed
Portc = &B00000010 : Decr Tilt : Waitms Tilt_speed
Portc = &B00000011 : Decr Tilt : Waitms Tilt_speed
Portc = &B00000001 : Decr Tilt : Waitms Tilt_speed
Return

0

2

Всё просто. Один двигатель не может сразу вращаться в разные стороны. Поэтому могут быть такие комбинации:

а. 1 и 2 выключены         (0000)

б. 1 влево 2 выключен    (0100)
в. 1 вправо 2 выключен  (1000)
г. 1 выключен 2 влево    (0001)
д. 1 выключен2 вправо   (0010)
е. 1 вправо 2 влево        (1001)
ж. 1 влево 2 вправо       (0110)
з. 1 влево 2 влево         (0101)
и. 1 вправо 2 вправо       (1001)

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

Код:
'************  управляющая программа
Do
If Portb = 4 Then Gosub Azimuth_right
If Portb = 8 Then Gosub Azimuth_left
...
If Portb = 9 Then Gosub Azimuth_left+Tilt_down


Loop
End

Azimuth_left+Tilt_down:
Portd = &B00001001 : Decr Azimuth : Portc = &B00000001 : Incr Tilt :Waitms speed
Portd = &B00001000 : Decr Azimuth : Portc = &B00000011 : Incr Tilt : Waitms speed
...
Return

Единственное НО! скорость перемещения для этого кода одинакова. Если нужна разная, цепляйте обработку каждого шага двигателя на прерывания по таймеру. А временем срабатывания таймеров регулируйте скорость шаговиков.

Уж не ЧПУ ли вы разрабатываете?

0

3

radan написал(а):

скорость перемещения для этого кода одинакова

К сожалению, скорость будет разной - поэтому и обратился. :)
Скорость задается в переменной speed (точнее, в результате будет 2 переменных - каждая для определенного двигателя)
Основная проблема  -  не могу понять, как повесить это на прерывания. RTFM не предлагать - не помогает :)

radan написал(а):

Уж не ЧПУ ли вы разрабатываете?

Нет, до ЧПУ мне далеко - это поворотная платформа с пропорциональным управлением для видеокамеры.

Отредактировано validol (2009-12-21 01:35:55)

0

4

Поставь 2 555ИР11 и будет счастье...

0

5

Nakoiher
не очень понимаю Вашу идею - как это поможет?

0

6

А это не идея, в старом принтере D-100 на ИР11 очень просто реализовано непосредственно переключение обмоток двигателя, на неё подаются только сигналы направления и тактовый для шагов, то есть Вы усложняете конструкцию на 10 рублей и получаете простор для программирования алгоритма перемещения.
Если интересно, пишите на мыло - пришлю схемку.

0

7

Nakoiher

Спасибо, идея интересная, письмо отпишу - на будущее пригодится)

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

Помогите дураку :)

0

8

validol
а можете показать Вашу схему? я не смог понять по коду программы ...

может и я чем смогу помочь :)

0

9

Александр Д.
схема примитивная - несколько концевиков-ограничителей, 2 шаговых движка, ULN2003 и ATMEga16 (поменяю на 8, вероятно)
Индикатор пока для вывода в симуляторе протеуса
http://img130.imageshack.us/img130/4924/tempv.jpg

Отредактировано validol (2009-12-28 00:15:23)

0

10

Нынче тоже заинтересован данной темой. Хочу сделать поворотный узел для видеокамеры. Ни кто не делал? Может чего посоветуете, хочу на шаговых двигателях сделать. Думаю это лучший вариант.

0

11

а если перед UNL поставить сдвиговый регистр и управлять шаговиками как при статической индикации. Мой приятель так делал и был доволен одновременным перемещением двух и более двигателей.

0

12

Поясни как ты себе это представляешь?

0

13

Для двух моторов два регистра. Есть значения X, Y положили номер шага для первого в один регистр для второго во второй а потом защелкнули данные и оба мотора совершили какой-то шаг. Как он мне сказал, значения поступают постоянно или 0 или конкретное значение.

0

14

Да, идея интересная. Но зачем регистры? Отводим один порт для двигателей. Старшие четыре бита-один двигатель, младшие- второй. Вводим переменную MOTOR. По таймеру -PortC=Motor. А в программе хоть маску накладывать, хоть с массивом. К примеру

Код:
motor1=&b00110011
motor2=&b00110011
If kn_r= 0 Then Rotate motor1 , Right
If Kn_L = 0 Then Rotate motor1 , left
If kn_u= 0 Then Rotate motor2 , Right
If Kn_d= 0 Then Rotate motor2, left
x=motor1
Shift x , Right , 4
y=motor2
Shift y, left , 4
MOTOR=x and y
PortC=Motor

0

15

Да я вот к чему это все. Хочу сделать видеокамеру которая будет стоять на улице, чтоб управляться и питался по кабелю LAN. Видеосигнал думаю пустить по коаксиальному кабелю. Камера у меня весьма не плохая, бескорпусная правда. Но это не важно, хочу сделать корпус герметичный, это понятно, улица не лучшее место для бескорпусной камеры, да даже в корпусах камеры есть "не очень". Думаю сделать контроль температуры внутри корпуса, хотелось бы чтоб камера по дольше пожила. Вот не знаю, стоит ли новую тему открывать... Или тут все выкладывать.....

0

16

kip написал(а):

Да, идея интересная. Но зачем регистры? Отводим один порт для двигателей. Старшие четыре бита-один двигатель, младшие- второй. Вводим переменную MOTOR. По таймеру -PortC=Motor. А в программе хоть маску накладывать, хоть с массивом.


Да идея интересная. Но с регистрами мы используем всего три ноги МК и любое число Шаговиков (регистров)

0

17

$regfile = "m8515.dat"
'$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
$baud = 9600

Print "test"
'Config Lcd = 20 * 4
'Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5

  Dim S As Byte
  Dim Nastawa As Integer
  Dim Krock As Integer                                      'Single
  Dim Krock1 As Integer
  Dim Wsk As Bit
  Config Porta = &B11111111
  Config Portd = &B11100000
  Config Portb.0 = Output

  Led Alias Portb.0
      Reset Wsk
      Reset Led
  Declare Sub Motor1
  Declare Sub Motor2
         Config Int0 = Falling
         Config Int1 = Falling
           Enable Int0
           Enable Int1

      On Int1 Button                                        'ďđĺđűâŕíčĺ îň ęíîďęč ýíęîäĺđŕ
      On Int0 Encod                                         'ďđĺđűâŕíčĺ îň ďîâîđîňŕ ýíęîäĺđŕ
      On Urxc Getchar

     Enable Urxc
     Enable Interrupts
     Cursor Off

   Do
    If Wsk = 0 Then
    Call Motor1
    Else
    Call Motor2
    End If
   Loop

   '================================
Sub Motor1

    If Krock > 3 Then
    Krock = 0
    Else
    If Krock < 0 Then
   Krock = 3
    End If
    End If
    Porta = Lookup(krock , Numbers)
    Nastawa = Krock

End Sub
  '================================================
Sub Motor2

    If Krock1 > 3 Then
    Krock1 = 0
    Else
    If Krock1 < 0 Then
    Krock1 = 3
    End If
    End If
    Porta = Lookup(krock1 , Numbers1)
   Nastawa = Krock1

  End Sub

'======================================================================================================
  Numbers:

Data &H09                                                   '0
Data &H03                                                   '1
Data &H06                                                   '2
Data &H0C                                                   '3

  Numbers1:

Data &H90                                                   '0
Data &H30                                                   '1
Data &H60                                                   '2
Data &HC0                                                   '3

'=====================================================================================================================

     Encod:                                                 ' ňóň óçíŕĺě â ęŕęîě íŕďđŕâëĺíčč âđŕůŕţň đó÷ęó ýíęîäĺđŕ
'Waitms 1                                                   ' ćäĺě ďîęŕ óňčőíĺň äđĺáĺçă ęîíňŕęňîâ
If Pind.4 = 1 Then                                         ' ĺńëč íŕ íîăĺ ĺäčíčöŕ (čěďóëüń íĺ ďđčřĺë) ňîăäŕ
Incr Nastawa
   Else                                                     ' â îáđŕňíîě ńëó÷ŕĺ
Decr Nastawa
End If
' Stop Timer0
Gifr = 64                                                  ' ńáđŕńűâŕĺě đĺăčńňđ őđŕíĺíč˙ ďđĺđűâŕíč˙ INT0

If Wsk = 0 Then
Krock = Nastawa
Else
Krock1 = Nastawa
End If
Return
  '==================================================
Getchar:

S = Inkey()

Print S ; "  " ; Chr(s)
If S = 115 Then
Wsk = 0
Reset Led
Incr Nastawa
Krock = Nastawa
End If
If S = 97 Then
Wsk = 0
Reset Led
Decr Nastawa
Krock = Nastawa
End If

  If S = 119 Then
Wsk = 1
Set Led
Incr Nastawa
Krock1 = Nastawa
End If
If S = 122 Then
Wsk = 1
Set Led
Decr Nastawa
Krock1 = Nastawa
End If
Return

Button:

Toggle Led
Waitus 10
Toggle Wsk
Return

0

18

komu interesno wyshlu e-mail

0

19

http://s6.uploads.ru/t/O2Fnc.jpg

0

20

Доброго здравия, форумчане!
Приобрел у китайцев униполярный шаговый двигатель 28DYJ-48, популярный у ардуинщиков. И драйвер к нему на ULN2003
http://savepic.net/6409269m.jpg
http://savepic.net/6410293m.jpg

СПЕЦИФИКАЦИЯ

    номинальное напряжение питания: 5 Вольт (постоянный ток)
    количество фаз: 4
    количество шагов: 64
    количество микрошагов: 4096
    шаг: 5.625 Градусов
    номинальная частота: 100 Герц
    номинальное сопротивление обмоток (при 25 Градусах по Цельсию): 50 Ом
    частота холостого хода (по часовой стрелке) : 600 Герц
    частота холостого хода (против часовой стрелки): 1000 Герц
    крутящий момент (по часовой стрелке, при частоте 120 Герц): 34,3 Ньютон-метр
    вращающий момент: 34,3 Ньютон-метров
    момент трения (сопротивление вращению): 600-1200 Граммов-на-сантиметр
    номинальная тяга: 300 Граммов-на-сантиметр
    Класс электробезопасности: А

Хочу управлять им по UART.
По теме нашел только заезженную и избитую:
http://avrproject.ru/publ/upravlenie_sh … t/1-1-0-28
Принципиальная схема:
http://avrproject.ru/publ/upravlenie_sh … t/1-1-0-28http://avrdesign.ucoz.ru/_pu/0/67408193.png

Код:
$regfile = "2313def.dat"
$crystal = 4000000
$baud = 9600


'заводим переменные
Dim S As Byte                             'эта переменная следит за номером шага двигателя
Dim A As Word                             'хранит количество сделанных шагов
Dim N As Word                             'хранит количество полушагов которые необходимо сделать
Dim T As String * 6                       'хранит команду пришедшую по UART
Dim Sign As String * 1                    'хранит направление движения
Dim M As Byte                             'хранит количество знаков в команде пришедшей по UART
Dim Char As String * 5                    'хранит числовое значение необходимых шагов

S = 1                                     'нумерация шагов начинается с единицы


'прерывания будут генерироваться пока на ноге низкий уровень, то есть пока кнопка будет нажата
Config Int0 = Low Level
Config Int1 = Low Level


Config Portb = Output                     'конфигурируем порт на выход
Config Portd.5 = Output                   'конфигурируем ногу для подключения светодиода
Led Alias Portd.5                         'присваиваем имя LED выводу 5 порта D


On Urxc Command                           'даем ссылку на обработчик прерывания по UART
On Int0 Knopka1                           'даем имена обработчикам прерываний от кнопок
On Int1 Knopka2


'разрешаем прерывания
Enable Interrupts
Enable Urxc
Enable Int0
Enable Int1


Print "Enter direction (+,-) and value step"


'****** ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ ******

Do
'проверяем состояние переменной Sign
'в зависимости от ее содержимого выполняем соответствующий код

 If Sign = "+" Then                       'если в ней плюс
  Led = 1                                 'зажигаем светодиод
  Gosub Plus                              'выполняем подпрограмму с меткой plus
  Led = 0                                 'гасим светодиод

 Print "OK!"
 Print ""
 Print "Enter direction (+,-) and value step"

 End If

 If Sign = "-" Then                       'если в ней минус
  Led = 1                                 'зажигаем светодиод
  Gosub Minus                             'выполняем подпрограмму с меткой minus
  Led = 0                                 'гасим светодиод

 Print "OK!"
 Print ""
 Print "Enter direction (+,-) and value step"

 End If

Loop



'****** здесь крутим двигатель в одном направлении ******

Plus:

   Do

Incr S                                    'увеличим номер шага

 If S = 9 Then                            'максимально возможный номер шага = 8
  S = 1
 End If

Select Case S                       'выбираем какие обмотки включать в зависимости от номера шага

Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001

End Select

Waitus 1000                               'задержка между шагами

Incr A                                    'считаем пройденные шаги

  Loop Until A = N                        'если прошагали сколько нужно выходим из цикла

'обнуляем переменные
A = 0
N = 0
Sign = "0"


Return                                    'возвращаемся в главный цикл программы



'****** а здесь крутим двигатель в обратном направлении ******

Minus:

  Do

Decr S

 If S = 0 Then                            'минимально возможный номер шага = 1
  S = 8
 End If

Select Case S

Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001

End Select

Waitus 1000

Incr A

  Loop Until A = N

'обнуляем переменные
A = 0
N = 0
Sign = "0"

Return                                    'возвращаемся в главный цикл программы



'****** обрабатываем команду пришедшую по UART ******

Command:

Input T                                   'пришедшая команда

Sign = Left(t , 1)                'вытащим первый символ, отвечающий за направление движения
M = Len(t)                        'узнаем сколько символов в пришедшей команде
M = M - 1                         'убавляем на 1, так как первый символ хранит только направление
Char = Right(t , M)               'вытаскиваем из команды все символы кроме первого символа
N = Val(char)                     'преобразуем строку в числовую переменную
N = N * 2                         'теперь мы знаем сколько нужно сделать полушагов (N)

Return


'****** обработка нажатия кнопок ******

 Knopka1:                                 '<<< обработчик прерывания первой кнопки

Led = 1                                   'зажигаем светодиод

Incr S                                    'увеличим номер шага

  If S = 9 Then                           'максимально возможный номер шага = 8
   S = 1
  End If

Select Case S                       'выбираем какие обмотки включать в зависимости от номера шага

Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001

End Select

Waitus 1000                               'задержка между шагами

Led = 0                                   'гасим светодиод

Return



 Knopka2:                                 '<<< обработчик прерывания второй кнопки

Led = 1                                   'зажигаем светодиод

Decr S                                    'тут все тоже самое, только в обратном направлении

  If S = 0 Then                           'минимально возможный номер шага = 1
   S = 8
  End If

Select Case S

Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001

End Select

Waitus 1000

Led = 0                                   'гасим светодиод

Return

End

Мне в итоге нужно получить результат как на этом видео:

Хочу сделать спидометр для автосимулятора.

У меня поворот должен осуществляться в зависимости от числа типа Byte от 0 до 255.
Если повернуть в одну сторону проблем не составит ( при увеличении числа ), то чтобы  повернуть в другую ( при уменьшении числа ) не пойму как. Ведь нужно перед числом обратных шагов указать знак " - " для обратного направления. А каким образом?

Отредактировано Avus (2015-02-11 20:54:28)

0

21

ну есть у вас маска шагов
крутите её в цикле, в одну сторону
если нужно обратно, то тоже самое но обратно
в чем проблема?
остальное примитивная математика с событиями
т.к. у вас мотор с редуктором (бешеным передаточным числом), то для начала надо понять, сколько раз вам надо сделать шагов, чтобы произвести нужное движение...

0

22

RDW написал(а):

в чем проблема?


Её нет, когда знаешь что и как делать. А когда занимаешься программированием месяц с небольшим, то все простое для здешних обывателей кажется сложным и запутанным.
Маска - говорите?
Это вот этот фрагмент?
Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001

В цикле крутить?
Do
Case 1 : Portb = &B00000001
Case 2 : Portb = &B00000011
Case 3 : Portb = &B00000010
Case 4 : Portb = &B00000110
Case 5 : Portb = &B00000100
Case 6 : Portb = &B00001100
Case 7 : Portb = &B00001000
Case 8 : Portb = &B00001001
Loop ( Loop Until )

RDW написал(а):

примитивная математика с событиями


Знать бы какие формулы прописывать...

0

23

Avus написал(а):

В цикле крутить?

Да, но в баскоме do/loop используют обычно для зацикливания всего кода (политика такая), тут конечно дело привычки...
Делаете переменную для шага/case (байтовую), которая крутится/ходит от 1 до 8 (впрочем лучше от 0 до 7).
Далее делаете переменную направления вращения, можно использовать битовую (но как я писал ранее на форуме, не вижу смысла вообще использовать битовые, тормозные операции в большинстве задачах, можно тоже байт взять (быстрее работать будет).
В зависимости от направления, значение шага увеличивайте/уменьшаете на 1.

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

0

24

Как начал крутить шаговыми двигателями с помощью микроконтроллеров, сделал такую таблицу соответствия выходов МК и десятичным числом (для полушага):

bit 3

bit 2

bit 1

bit 0

DEC

1

0

0

0

8

1

1

0

0

12

0

1

0

0

4

0

1

1

0

6

0

0

1

0

2

0

0

1

1

3

0

0

0

1

1

1

0

0

1

9

В коде примерно следующее. Допустим, нужно сделать 15 полушагов и двигатель подключен к PORTC.0 - PORTC.3

Dim S(8) As Byte
Dim A As Word
Dim D As Byte

S(1) = 8
S(2) = 12
S(3) = 4
S(4) = 6
S(5) = 2
S(6) = 3
S(7) = 1
S(8) = 9

D = 1
   For A=1 To 15
   PORTC = S(d)
   Incr D
   If D = 9 Then D = 1
Next

Если нужно вращать в другую сторону:

D = 1
   For A=1 To 15
   PORTC = S(d)
   Decr D
   If D = 0 Then D = 8
Next

Если на PORTC(4-7) что-то еще подключено и обрабатывается отдельно, то
PORTC = S(d)
заменяется на:
PORTC.0 = S(d).0
PORTC.1 = S(d).1
PORTC.2 = S(d).2
PORTC.3 = S(d).3

Отредактировано SIvan (2015-02-11 22:00:46)

0

25

Спасибо! Более - менее понятно с управлением и переключением обмоток. Пара моментов:

1.
Если мне нужно не 15 шагов, как в Вашем примере, а зависящие от значения Y, например. Тогда:

For A=1 To Y
Правильно?

2.
PORTC = S(d)
Здесь бинарный вид выходов порта C  равен десятичному числу, которое при конвертации в бинарное даст соответствующее положение логической единицы на определенных выходах порта C. При этом конвертация осуществляется с помощью знака " = "
Правильно?

3.
Это переключение обмоток заставляет двигатель сделать один шаг?
S(1) = 8
S(2) = 12
S(3) = 4
S(4) = 6
S(5) = 2
S(6) = 3
S(7) = 1
S(8) = 9

Отредактировано Avus (2015-02-12 00:11:03)

0

26

Начеркал код и схему подключения:
http://savepic.net/6399082m.jpg

Код:
$regfile = "m328Pdef.dat"                                   ' Используемый контроллер
$crystal = 16000000                                         ' Частота работы контроллера
$framesize = 32                                            ' Размер области используемой для преобразований
$hwstack = 40                                              ' Размер аппаратного стека
$swstack = 16                                             ' Размер программного стека

'---------------------------------------------------------------------------------------------------------------------
Config Portc = Output
Config Portd.2 = Input
Config Portd.3 = Input
Dim S As Byte                                               'номер шага двигателя
Dim A As Word                                             'счетчик сделанных шагов. Двигатель остановится,когда A сравняется с N.
Dim N As Word                                              'промежуточная переменная значения скорости
Dim Speed1 As Byte                                          'реальное значение скорости, принимаемое по UART.

Open "comb.1:9600,8,n,1" For Output As #1                   'конфигурируем программный UART
Open "comb.0:9600,8,n,1" For Input As #2


Config Int0 = Falling                                       'конфигурируем внешнее прерывание по низкому уровню
On Int0 Прерывание                                          'определяем обработчик прерывания
Enable Interrupts
Enable Int0




S = 1                                                       'нумерация шагов начинается с единицы



A = 0                                                       'обнуляем счетчик перед началом работы


Главный_цикл:                                               'здесь принимаем данные скорости по UART
                                                            'в зависимости от значения N определяем в какую сторону крутить мотор

Inputbin #2 , Speed1

N = Speed1

If A < N Then
Goto Крутим_вправо
End If

If A > N Then
Goto Крутим_влево
End If

Goto Главный_цикл



Крутим_вправо:

Do
Incr S

 If S = 9 Then
  S = 1
 End If

Select Case S

Case 1 : Portc = &B00000001
Case 2 : Portc = &B00000011
Case 3 : Portc = &B00000010
Case 4 : Portc = &B00000110
Case 5 : Portc = &B00000100
Case 6 : Portc = &B00001100
Case 7 : Portc = &B00001000
Case 8 : Portc = &B00001001

End Select

Waitus 1000
Incr A


Loop Until A = N                                            'выходим из цикла, если счетчик A достиг значения N
                                                              'двигатель при этом останавливается


Waitms 100

Goto Главный_цикл




Крутим_влево:
Do
Decr S

 If S = 0 Then
  S = 8
 End If

Select Case S

Case 1 : Portc = &B00000001
Case 2 : Portc = &B00000011
Case 3 : Portc = &B00000010
Case 4 : Portc = &B00000110
Case 5 : Portc = &B00000100
Case 6 : Portc = &B00001100
Case 7 : Portc = &B00001000
Case 8 : Portc = &B00001001

End Select

Waitus 1000
Decr A


Loop Until A = N                                            'выходим из цикла, если счетчик A достиг значения N
                                                             'двигатель при этом останавливается
Waitms 100

Goto Главный_цикл


Прерывание:                                                 'Нажатием на кнопку можно изменять вручную промежуточную переменную N
Incr N                                                      'в сторону увеличения
Waitms 20
Eifr = 64
Return

Что скажите?

Отредактировано Avus (2015-02-16 23:23:30)

0

27

1. Верно.
2. Верно, только "=" не делает конвертацию, а выставляет биты соответственно битам двоичного представления десятичного числа из таблицы. Собственно, таблица ради этого и сделана: увидеть десятичный эквивалент двоичному.
3. Нет. Разница между двумя любыми соседними значениями - один полушаг.

И вообще, в приведенном мной примере так и указано: для полушага.

Avus написал(а):

Что скажите?

А что мы скажем? Это вы скажИте, работает у вас или нет? :)

Кстати, для симуляции в протеусе (если в нем же не будет разрабатываться плата), ставить буферы не обязательно. И без них там моторчик будет крутиться.

Отредактировано SIvan (2015-02-15 23:46:37)

0

28

Подредактировал исходник, который выше. Исправил ошибки. Заработало, но UART пока не могу заставить работать корректно. Помимо нужного значения Speed1 лезет всякий мусор, который сбивает направление и количество шагов после поворота на нужный угол в соответствии с значением Speed1.
Пробовал использовать аппаратный UART, но результат стал еще хуже. Не знаю как отфильтровать на прием только нужное мне значение Speed1 и чтобы помимо него ничего больше не принималось. Хочу заметить, что в передатчике используются еще 6 каналов ШИМ, которые видимо могут давать серьезные помехи при передаче. Изучаю "Исследование USART"  от sasha_1973.

0

29

Сильноточка с большим уровнем помех, аки регуляторы вращения двигателей без контрольной суммы обычно даже внутри одного корпуса толком не работает. Пробуйте собирать пакет с КС и передавать его контроллеру. Еще - монтаж. Не должно быть соплей по полметра, цепи связи перепендикудярны силовым и т.д.

0

30

Чтобы не было помех от мотора, нужно цифровую схему питать от DC-DC (это минимум)...

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Управление шаговыми двигателями