purebasic.info

PureBasic forum
Текущее время: Сб июн 23, 2018 10:26 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Битовые операции
СообщениеДобавлено: Чт ноя 30, 2017 8:38 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Ср май 18, 2016 11:52 pm
Сообщений: 34
Откуда: Нижегородская обл.
Благодарил (а): 16 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Создавая программу и параллельно изучая PureBasic, о да, наконец-то нашел вдохновение изучить этот отличный язык программирования, принимайте меня в секту поклонения PureBasic`у :mrgreen:
Собственно пару дней назад освоил окно, некоторые гаджеты, RS232 и по мелочи, получилось создать такое: https://www.youtube.com/watch?v=c4SLCK8BvOA

Столкнулся с отсутствием возможности выдрать байты из многобайтовых переменных, а так-же подгонять строку под нужный формат.
К примеру на Бэйсике в BascomAvr это выглядит так:
Код:
1
2
3
4
5
Dim D As Word (2 байта 0-65536)
Dim B as Byte   (1 байт 0-255)
D=300
B=Low(D) - Берём младший байт
B=High(D) - Берём старший байт


А строку можно подогнать через Format:
Код:
1
2
3
4
5
Dim Vxod As String * 6
Dim Vyxod As String * 8
Vxod = "38.869"
Vyxod = Format(Vxod, "+000.00")
'Vyxod = "+038.86"



Если кто сталкивался, может подскажите как сделать следующее:
К примеру X.d = 34.15
Нужно выдрать цифру до запятой и после запятой, после запятой перевести в цифру от 0-1000 и отослать двумя байтами по UART + 1 байт до запятой.
То-есть:
B.a=INT(X.d)
WriteSerialing(0,B,1)
D.c=(X-INT(X))*1000
B= как-то выдрать младший байт
WriteSerialing(0,B,1)
B= как-то выдрать старший байт
WriteSerialing(0,B,1)

Конечно можно было бы отправить сразу два байта, но у меня обмен данными постоянный и ошибки не допустимы, каждый отправленный байт прибавляется к 1 байтовой переменной и после посылается последним и всё это при получении сравнивается, это никак не подойдёт: WriteSerialing(0,В,2)

Говоря проще, переменную Word надо разбить на две переменные Byte.
Может есть вариант как в Bascom - объявление переменных в адрес переменных:
Код:
1
2
3
Dim D As Word
Dim LowD As Byte AT D Overley
Dim HighD As Byte AT D+1 Overley


Таким образом я знаю адреса верхнего и нижнего байта двухбайтовой переменной.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Чт ноя 30, 2017 9:29 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1625
Откуда: Алматы
Благодарил (а): 14 раз.
Поблагодарили: 44 раз.
Пункты репутации: 5
так Петр ж сделал :) искать над было лучше! хотя я сам не помню что искать... скопировал из проекта :)

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;{ битовые операции
Macro SetBit(Var, Bit) ; Установка бита.
  Var | (Bit)
EndMacro
Macro ClearBit(Var, Bit) ; Обнуление бита.
  Var & (~(Bit))
EndMacro
Macro TestBit(Var, Bit)
  Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num) ; Позиция бита по его номеру.
  (1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
  ((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}



есть еще Bin() в справке.

в итоге чтоб примерно понимать добавить к коду:
Код:
1
2
3
4
5
6
a.w = 267
Debug Bin(a)
 
Debug Bin(GetBits(a, 0, 3))
Debug Bin(GetBits(a, 4, 7))
Debug Bin(GetBits(a, 8, 11))



Последний раз редактировалось SereZa Чт ноя 30, 2017 9:33 pm, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Чт ноя 30, 2017 9:32 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11194
Благодарил (а): 4 раз.
Поблагодарили: 417 раз.
Ev3658 писал(а):
Столкнулся с отсутствием возможности выдрать байты из многобайтовых переменных
Выдрать можно путем сдвигов и побитового И.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Procedure Low(Var)
  ProcedureReturn Var & 255 ; Обнуление всех байт кроме нулевого.
EndProcedure
 
Procedure High(Var)
  ProcedureReturn Var>>8 & 255 ; Сдвиг вправо на 8 бит и обнуление всех байт кроме нулевого.
EndProcedure
 
D=300
 
B=Low(D) ;- Берём младший байт
Debug B
 
B=High(D);- Берём старший байт
Debug B



Ev3658 писал(а):
Нужно выдрать цифру до запятой и после запятой
Вариант 1, через преобразование в строку
Код:
1
2
3
4
X.d = 34.15
s.s = StrD(x, 2)
Debug Val(StringField(s, 1, "."))
Debug Val(StringField(s, 2, "."))

Вариант 2, без преобразования в строку
Код:
1
2
3
4
5
X.d = 34.15
y = Int(x)
z = (x-y)*100
Debug y
Debug z



Ev3658 писал(а):
Может есть вариант как в Bascom - объявление переменных в адрес переменных:
Можно узнать адрес переменной и прочитать любой из ее байтов.
Код:
1
2
3
D.u=300
Debug PeekA(@D)
Debug PeekA(@D+1)


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Чт ноя 30, 2017 10:29 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Ср май 18, 2016 11:52 pm
Сообщений: 34
Откуда: Нижегородская обл.
Благодарил (а): 16 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
УРА! Спасибо!!!!! А ведь вторые сутки ищу, везде как-то через STRING делают, но почему-то меня жаба давит ресурсы ЦП тратить на кучу бесполезных тактов.... Блин, это всё микроконтроллеры виноваты )))))
Только сейчас прозрел :roll:
@ - это же даёт начальный адрес переменной!!!!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 12:19 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Ev3658 писал(а):
Создавая программу и параллельно изучая PureBasic, о да, наконец-то нашел вдохновение изучить этот отличный язык программирования, принимайте меня в секту поклонения PureBasic`у :mrgreen:
Собственно пару дней назад освоил окно, некоторые гаджеты, RS232 и по мелочи, получилось создать такое: https://www.youtube.com/watch?v=c4SLCK8BvOA

Столкнулся с отсутствием возможности выдрать байты из многобайтовых переменных, а так-же подгонять строку под нужный формат.
К примеру на Бэйсике в BascomAvr это выглядит так:
Код:
1
2
3
4
5
Dim D As Word (2 байта 0-65536)
Dim B as Byte   (1 байт 0-255)
D=300
B=Low(D) - Берём младший байт
B=High(D) - Берём старший байт


А строку можно подогнать через Format:
Код:
1
2
3
4
5
Dim Vxod As String * 6
Dim Vyxod As String * 8
Vxod = "38.869"
Vyxod = Format(Vxod, "+000.00")
'Vyxod = "+038.86"



Если кто сталкивался, может подскажите как сделать следующее:
К примеру X.d = 34.15
Нужно выдрать цифру до запятой и после запятой, после запятой перевести в цифру от 0-1000 и отослать двумя байтами по UART + 1 байт до запятой.
То-есть:
B.a=INT(X.d)
WriteSerialing(0,B,1)
D.c=(X-INT(X))*1000
B= как-то выдрать младший байт
WriteSerialing(0,B,1)
B= как-то выдрать старший байт
WriteSerialing(0,B,1)

Конечно можно было бы отправить сразу два байта, но у меня обмен данными постоянный и ошибки не допустимы, каждый отправленный байт прибавляется к 1 байтовой переменной и после посылается последним и всё это при получении сравнивается, это никак не подойдёт: WriteSerialing(0,В,2)

Говоря проще, переменную Word надо разбить на две переменные Byte.
Может есть вариант как в Bascom - объявление переменных в адрес переменных:
Код:
1
2
3
Dim D As Word
Dim LowD As Byte AT D Overley
Dim HighD As Byte AT D+1 Overley


Таким образом я знаю адреса верхнего и нижнего байта двухбайтовой переменной.


А что 2 байта без знака минуса ?
Я бы сказал регистр процессора работает с каждым из своих сорегистров со знаком минуса :D
Код:
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
 
 
;{Виртуальный регистр eax x86
Structure axx
al.b
ah.b
EndStructure
Structure ax
  StructureUnion
  axx.axx
  ax.w
 EndStructureUnion    
EndStructure  
Structure eax
  StructureUnion
  ax.ax
  eax.i
  EndStructureUnion
EndStructure
 
 
Macro _eax
__eax\eax
EndMacro
Macro _ax
__eax\ax\ax
EndMacro
Macro _ah
__eax\ax\axx\ah
EndMacro
Macro _al
__eax\ax\axx\al
EndMacro
;}
 
Global __eax.eax
 
_ax=$ffff
 
 
Debug _eax
Debug _ax
Debug _ah
Debug _al
 
 
_ax = -32768
 
Debug _eax
Debug _ax
Debug _ah
Debug _al
 
 
_eax = 65535
 
Debug _eax
Debug _ax
Debug _ah
Debug _al
 
 
;;;;;;;;;;;;;;;;;;;
Debug PeekA(@_ah)
Debug PeekA(@_al)
;или изменить в  структуре типы и смотреть от 0-255 без   PeekA(@_al)
;Structure axx
;al.a
;ah.a
;EndStructure
 
 ;;;;;;;;;;;;;;;;;;;;;;
 
 
 
 
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 12:41 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Ev3658 писал(а):
УРА! Спасибо!!!!! А ведь вторые сутки ищу, везде как-то через STRING делают, но почему-то меня жаба давит ресурсы ЦП тратить на кучу бесполезных тактов.... Блин, это всё микроконтроллеры виноваты )))))
Только сейчас прозрел :roll:
@ - это же даёт начальный адрес переменной!!!!


Так данные же с контроллера вроде бы идут строкой? :roll:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 12:45 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11194
Благодарил (а): 4 раз.
Поблагодарили: 417 раз.
Сергейчик писал(а):
А что 2 байта без знака минуса ?
Ev3658 писал(а):
2 байта 0-65536

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 1:37 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Пётр писал(а):
Сергейчик писал(а):
А что 2 байта без знака минуса ?
Ev3658 писал(а):
2 байта 0-65536

Ну значит можно так :roll:
Код:
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
 
Procedure.s BinMemory(*s,y=1);адрес памяти,количество сканируемых бит и вывод строкой в Юникоде
  ;If y>0
  Protected string.s=RSet(string,y,"1");создать буфер с количеством выводящих байт
  !mov dword esi,[p.p_s]
  !mov dword edi,[p.v_string]
  !mov eax,[p.v_y];Количиство просматриваемых бит
  ;;;;;;;;;;;;;
  !jmp ff
  !tt:
 !cmp eax,0
  !jz xx
  !add edi,2
  !ff:
 !sub dword eax,1
  !BT dword[esi],eax
  !JC tt;Переход, если бит равен 1
  !mov word[edi],30h
  !jmp tt
  !xx:
 ProcedureReturn string
  ;EndIf
EndProcedure
 
Structure axx
al.a
ah.a
EndStructure
Structure ax
  StructureUnion
  axx.axx
  ax.u
 EndStructureUnion    
EndStructure
 
 
Macro _ax
__ax\ax
EndMacro
Macro _ah
__ax\axx\ah
EndMacro
Macro _al
__ax\axx\al
EndMacro
 
Global __ax.ax
Global slovo.u
_ax= 25334
 
Debug "ax"
Debug _ax
Debug BinMemory(@_ax,16)
Debug "ah "+Str(_ah)+"     "+"al "+Str(_al)
Debug "7654321076543210"
Debug BinMemory(@_ah,8)+BinMemory(@_al,8)
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 10:15 am 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Ср май 18, 2016 11:52 pm
Сообщений: 34
Откуда: Нижегородская обл.
Благодарил (а): 16 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Сергейчик писал(а):
....
Код:
1
2
3
4
5
6
7
 
.....
  !mov dword esi,[p.p_s]
  !mov dword edi,[p.v_string]
  !mov eax,[p.v_y];Количиство просматриваемых бит
 ....
 


Assembler :? , не, я не готов к такому экзорцизму :D

Двухбайтные переменные далеко не одинаковы, к примеру "Character" .c и "Unicode" .u выдают разное значение при Debug:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
 
Global vrd.d =0 ;временная переменная для рассчёта
Global vra.a=0;временная переменная для рассчёта
Global vru.u=0;временная переменная для расчёта
 
vrd=34.789
vrd=(vrd-Round(vrd,#PB_Round_Down))*1000
vrc=vrd
vru=vrd
 
Debug vrd
Debug vrc
Debug vru



789.00000000000148
21
789


Я в замешательстве )))

Да и куда теряются биты?
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Global vrd.d =0 ;временная переменная для рассчёта
Global vra.a=0;временная переменная для рассчёта
Global vru.u=0;временная переменная для расчёта
 
vrd=34.789
vrd=(vrd-Round(vrd,#PB_Round_Down))*1000
vru=vrd
vra=PeekA(@vru)
vru=vrd
 
Debug vrd
Debug vru
Debug vra
vra=PeekA(@vru+1)
Debug vra



789.00000000000148
789
21
3


3*255+21=786
Или байт=256?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 10:34 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Ev3658 писал(а):
Сергейчик писал(а):
....
Код:
1
2
3
4
5
6
7
 
.....
  !mov dword esi,[p.p_s]
  !mov dword edi,[p.v_string]
  !mov eax,[p.v_y];Количиство просматриваемых бит
 ....
 


Assembler :? , не, я не готов к такому экзорцизму :D

Двухбайтные переменные далеко не одинаковы, к примеру "Character" .c и "Unicode" .u выдают разное значение при Debug:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
 
Global vrd.d =0 ;временная переменная для рассчёта
Global vra.a=0;временная переменная для рассчёта
Global vru.u=0;временная переменная для расчёта
 
vrd=34.789
vrd=(vrd-Round(vrd,#PB_Round_Down))*1000
vrc=vrd
vru=vrd
 
Debug vrd
Debug vrc
Debug vru



789.00000000000148
21
789


Я в замешательстве )))

Да и куда теряются биты?
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Global vrd.d =0 ;временная переменная для рассчёта
Global vra.a=0;временная переменная для рассчёта
Global vru.u=0;временная переменная для расчёта
 
vrd=34.789
vrd=(vrd-Round(vrd,#PB_Round_Down))*1000
vru=vrd
vra=PeekA(@vru)
vru=vrd
 
Debug vrd
Debug vru
Debug vra
vra=PeekA(@vru+1)
Debug vra



789.00000000000148
789
21
3


3*255+21=786
Или байт=256?

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


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 11:42 am 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Ср май 18, 2016 11:52 pm
Сообщений: 34
Откуда: Нижегородская обл.
Благодарил (а): 16 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Сергейчик писал(а):
...Сначала спрашивал про целочисленные типы данных теперь же пытаешься из внутреннего форма с плавающей точкой...

На самом деле постеснялся написать полноту всей задачи, но теперь с таким кол-вом текста в теме расскажу вам головоломку :roll:
Есть устройство, задача которого управлять двумя моторами одновременно и симметрично.
Так-же это устройство следит за энкодерами двигателя и по требованию отсылает данные.
Для перемещения данные отправляются по байтам в следующем порядке:
;1.Команда бай (126) - перемещение
;2.Направление и режим такта (Бит0-направление X, Бит1-направление Z.... в разработке)
;3.Скорость такта HByte
;4.Скорость такта LByte
;5.Сантиметры X
;6.Миллиметры X Hbyte
;7.Миллиметры X Lbyte
;8.Период X Hbyte
;9.Период X Lbyte
;10.Сантиметры Z
;11.Миллиметры Z Hbyte
;12.Миллиметры Z Lbyte
;13.Период Z Hbyte
;14.Период Z Lbyte
;15.Пров.байт - каждый байт в B.a=B+отправляемый байт (контрольная сумма)

Вся суть в том, что нужно передать сантиметры (0-255), микроны (0-1000) и период (0-65536). (1микрон = 0,001мм) из данных ±X=0000.000 ±Z=0000.000 SPEED=0000
Период это типа редукция, к примеру надо переместится на 10 см по первому двигателю и на 1 см по второму, так вот, период это пропуск тактом в микронах, пока движется 10см, другой двигается по микронам с пропуском тактов(период) первого двигателя.
Скорость такта - это внутренний генератор в устройстве, который задаёт импульсы для равномерного перемещения.

Программа для станков пишется в G-cod`е, от туда можно выдрать координаты формата ±0000.000мм., из этой координаты надо выбрать сантиметры и микроны, после найти делитель разности, учесть остаток после деления и после озадачить контроллер.

Исходник контроллера
Код:
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
$regfile = "xm256a3def.dat"
$crystal = 33177600
$hwstack = 200
$swstack = 128
$framesize = 235
 
$lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
 
 
Config Osc = Enabled , Extosc = Enabled , Pllosc = Enabled , _
Range = 2mhz_9mhz , Startup = Xtal_1kclk , Pllsource = Extclock , Pllmul = 9 , Plldiv2 = Disabled , 32khzosc = Disabled       &#39;, 32khzpowermode = Normal
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1
Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled
 
&#39;===================== Порты первого частотника
Error1 Alias Pind.5                                         &#39;Вход ошибки
Config Error1 = Input
Config Xpin = Portd.5 , Outpull = Pullup
 
Pozicia1 Alias Pind.4                                       &#39;Вход сигнала выхода на позицию
Config Pozicia1 = Input
Config Xpin = Portd.4 , Outpull = Pullup
 
On1 Alias Portd.7                                           &#39;Включить часттник
Config On1 = Output
 
Reset1 Alias Portd.6                                        &#39;Сброс ошибки в частотнике
Config Reset1 = Output
 
Rev1 Alias Porte.0                                          &#39;Направление вращения
Config Rev1 = Output
 
Puls1 Alias Porte.1                                         &#39;Выход импульсов перемещения
Config Puls1 = Output
 
&#39;Входы квадратурной дешифрации
Config Pina.0 = Input                                       &#39;A
Config Pina.1 = Input                                       &#39;B
Config Pina.2 = Input                                       &#39;Z
Config Xpin = Pina.0 , Sense = Rising                       &#39;Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.1 , Sense = Rising                       &#39;Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.2 , Sense = Both                         &#39;Контроль входа на обнаружение падающего фронта
&#39;===================== Порты второго частотника
Error2 Alias Pinb.1
Config Error1 = Input
Config Xpin = Portb.1 , Outpull = Pullup
 
Pozicia2 Alias Pinb.0
Config Pozicia2 = Input
Config Xpin = Portb.0 , Outpull = Pullup
 
On2 Alias Portb.3                                           &#39;Включить часттник
Config On2 = Output
 
Reset2 Alias Portb.2                                        &#39;Сброс ошибки в частотнике
Config Reset2 = Output
 
Rev2 Alias Portd.0                                          &#39;Направление вращения
Config Rev2 = Output
 
Puls2 Alias Portd.1                                         &#39;Выход импульсов перемещения
Config Puls2 = Output
 
&#39;Входы квадратурной дешифрации
Config Porta.3 = Input                                      &#39;A
Config Porta.4 = Input                                      &#39;B
Config Porta.5 = Input                                      &#39;Z
Config Xpin = Porta.3 , Sense = Rising                      &#39;Контроль входа на обнаружение падающего фронта
Config Xpin = Porta.4 , Sense = Rising                      &#39;Контроль входа на обнаружение падающего фронта
Config Xpin = Porta.5 , Sense = Both                        &#39;Контроль входа на обнаружение падающего фронта
&#39;===================== Энкодер шпинделя
&#39;Входы квадратурной дешифрации
Config Portc.5 = Input                                      &#39;A
Config Portc.6 = Input                                      &#39;B
Config Portc.7 = Input                                      &#39;Z
 
&#39;===================== Настройка UART
Config Com7 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Config Portf.2 = Input                                      &#39;RX
Config Portf.3 = Output                                     &#39;TX
Open "COM7:" For Binary As #1
On Usartf0_rxc Serialinput
Enable Usartf0_rxc
Dim B As Byte
 
Dim Command(30) As Byte                                     &#39;буфер принятых комманд
Dim Tm As Byte                                              &#39;счётчик принятых данных в команду
Dim Endtm As Byte                                           &#39;конец принятия команд
 
 
 
 
Dim Takt1 As Byte
Dim Takt2 As Byte
 
 
 
Dim En1 As Byte
Dim En2 As Byte
 
 
&#39;===================== Каналы событий
&#39;квадратурной дешифрации
Config Event_system = Dummy , Mux0 = Porta.0 , Qd0 = Enabled , Digflt0 = 2
Config Event_system = Dummy , Mux2 = Porta.3 , Qd2 = Enabled , Digflt2 = 2
Config Event_system = Dummy , Mux4 = Portc.5 , Qd4 = Enabled , Digflt4 = 2
 
&#39;Тактовое событие
Config Event_system = Dummy , Mux1 = Tcf0_ovf               &#39;Общий такт перемещения
Config Event_system = Dummy , Mux3 = Tce0_ccb               &#39;Счёт импульсов перемещения 1
Config Event_system = Dummy , Mux5 = Tcd0_ccb               &#39;Счёт импульсов перемещения 2
&#39;===================== Таймеры квадратурной дешифрации
 
Tcc1_per = 9999
Tcc0_per = 9999
Config Tcc1 = Normal , Prescale = E0 , Event_source = E0 , Event_action = Qdec , Event_delay = Enabled       &#39;Квадратура двигателя 1
Config Tcc0 = Normal , Prescale = E2 , Event_source = E2 , Event_action = Qdec , Event_delay = Enabled       &#39;Квадратура двигателя 2
Config Tcf1 = Normal , Prescale = E2 , Event_source = E2 , Event_action = Qdec , Event_delay = Enabled
 
On Tcc1_ovf Enc1:
Enable Tcc1_ovf
 
On Tcc0_ovf Enc2:
Enable Tcc0_ovf
 
 
&#39;===================== Таймер счёта импульсов
Config Tce1 = Normal , Prescale = E3 , Event_source = E3
Config Tcd1 = Normal , Prescale = E5 , Event_source = E5
Tce1_per = 9999                                             &#39;ограничение счёта импульсов X
Tcd1_per = 9999                                             &#39;ограничение счёта импульсов Z
 
 
&#39;===================== Таймеры импульсов
Config Tce0 = Pwm , Prescale = E1 , Event_source = E1 , Compareb = Enabled
Config Tcd0 = Pwm , Prescale = E1 , Event_source = E1 , Compareb = Enabled
Tce0_ccb = 1
Tcd0_ccb = 1
 
Tce0_per = 1
Tcd0_per = 1
 
On Tce1_cca Pz1
Enable Tce1_cca
On Tcd1_cca Pz2
Enable Tcd1_cca
 
On Tce1_ovf Pl1
Enable Tce1_ovf
On Tcd1_ovf Pl2
Enable Tcd1_ovf
 
Tce0_ctrld = 0
Config Tcf0 = Normal , Prescale = Off , Event_delay = Enabled
Tcf0_per = 10
 
Dim X As Word
Dim Z As Word
 
Dim X1 As Byte At X Overlay
Dim X2 As Byte At X + 1 Overlay
 
Dim Z1 As Byte At Z Overlay
Dim Z2 As Byte At Z + 1 Overlay
 
Dim Speed As Word
Dim Speed1 As Byte At Speed Overlay
Dim Speed2 As Byte At Speed + 1 Overlay
Dim Bitch As Byte                                           &#39;бит чётности
Dim Rabota As Byte                                          &#39;режим исполнения комманды
 
Dim Per1 As Word
Dim Per11 As Byte At Per1 Overlay
Dim Per12 As Byte At Per1 + 1 Overlay
 
Dim Per2 As Word
Dim Per21 As Byte At Per2 Overlay
Dim Per22 As Byte At Per2 + 1 Overlay
 
Dim Xsm As Byte
Dim Zsm As Byte
Dim Pzx As Byte
Dim Pzz As Byte
 
Dim Stoptm As Byte
Dim Cmdrab As Byte
Dim Priem As Bit
 
Cmdrab = 1
 
Goto Prog:
 
 
 
 
 
 
Prog:
 
Set On1
Set On2
Set Rev1
Enable Interrupts
 
Do
If Rabota = 0 And Priem = 1 Then
   If Command(1) = 126 Then
      Command(1) = 0
      Speed1 = Command(4)
      Speed2 = Command(3)
      Xsm = Command(5)
      X1 = Command(7)
      X2 = Command(6)
      Tce1_cca = X
 
 
      Zsm = Command(10)
      Z1 = Command(12)
      Z2 = Command(11)
      Tcd1_cca = Z
      Per21 = Command(14)
      Per22 = Command(13)
 
      If Per1 > 1 Then
         Tce0_per = Per1
         Else
             Tce0_per = 2
      End If
 
      If Per2 > 1 Then
         Tcd0_per = Per2
         Else
             Tcd0_per = 2
      End If
 
      Rev1 = Command(2).0
      Rev2 = Command(2).1
      Pzx = 0
      Pzz = 0
      Priem = 0
      Tm = 0
      Print #1 , "SPEED:" ; Speed ; " Xсм:" ; Xsm ; " Zсм:" ; Zsm
      Stoptm = 0
      If X > 0 And Xsm > 0 Then
         Tce1_cnt = 0
         Config Tce0 = Pwm , Prescale = E1 , Event_source = E1 , Compareb = Enabled
         Else
         Stoptm = 1
      End If
      If Z > 0 And Zsm > 0 Then
         Tcd1_cnt = 0
         Config Tcd0 = Pwm , Prescale = E1 , Event_source = E1 , Compareb = Enabled
         Else
         Stoptm = 1
      End If
      Config Tcf0 = Normal , Prescale = 2 , Event_delay = Enabled
      Tcf0_per = Speed
      Rabota = 1
 
      Printbin #1 , 251
   End If
End If
 
 
 
Loop
 
 
Serialinput:
 
B = Usartf0_data
If Tm = 0 Then
   Select Case B
   Case 126:
     Endtm = 16
      Tm = 1
      Bitch = 0
   Case 125:
            If Priem = 0 Then
             Endtm = 20
             Bitch = 0
             Tm = 16
             End If
   Case 100:
               Printbin #1 , En1
                Bitch = En1
                B = Low(tcc1_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                B = High(tcc1_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                Bitch = Bitch + En2
                Printbin #1 , En2
                B = Low(tcc0_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                B = High(tcc0_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                Printbin #1 , Bitch
   Case Else:
        Tm = 0
        Endtm = 0
        Bitch = 0
   End Select
 
 
End If
 
If Tm > 0 Then
      Command(tm) = B
      Bitch = Bitch + B
      Incr Tm
        If Tm = Endtm Then                                  &#39;Если конец приёма, выполняем действия
            If Command(1) = 126 Then Priem = 1
            If Command(16) = 125 Then                       &#39;смена скорости
               Command(16) = 0
               Speed2 = Command(17)
               Speed1 = Command(18)
 
               Bitch = Bitch - Command(19)
               If Bitch = Command(19) Then
                  &#39;Print #1 , "OK " ; Speed
                   If Speed > 0 Then
                  Tcf0_per = Speed
                  Printbin #1 , 250
 
                  Else
                  &#39;================================= Действие если не дозавершил
                           Tcf0_ctrla = 0
                           Tce0_ctrla = 0
                           Tcd0_ctrla = 0
                           Rabota = 0
                           Stoptm = 0
               End If
                  Else
                    Printbin #1 , 255
               End If
               Bitch = 0
               Tm = 0
 
             End If
        End If
End If
 
Return
 
 
Pl1:
Incr Pzx
Return
Pl2:
Incr Pzz
Return
Pz1:
 
If Pzx => Xsm And Rabota = 1 Then
   If Stoptm = 1 Then
      Gosub Stoped:
     Else
      &#39;Print #1 , "X STOP"
      Tce0_ctrla = 0
      Stoptm = 1
   End If
End If
 
Return
 
Pz2:
 
If Pzz => Zsm And Rabota = 1 Then
     If Stoptm = 1 Then
      Gosub Stoped:
     Else
      Tcd0_ctrla = 0
      Stoptm = 1
     End If
End If
 
Return
 
Stoped:
        Tcf0_ctrla = 0
         Tce0_ctrla = 0
         Tcd0_ctrla = 0
         Rabota = 0
         Stoptm = 0
         Printbin #1 , 250
Return
 
Enc1:
If Tcc1_ctrlfset.0 = 0 Then
   Incr En1
   Else
    Decr En1
End If
 
Return
 
Enc2:
If Tcc0_ctrlfset.0 = 0 Then
   Incr En2
   Else
    Decr En2
End If
 
Return



Код начальной программы PB
Код:
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
Enumeration
  #okno
  #text0
  #textx
  #textz
  #textx1
  #textz1
  #textst
  #textgs
  #textgs1
  #textgf
  #textgf1  
  #list1
  #bar
  #kn1
  #kn2
EndEnumeration
EnableExplicit
 
Global file.s=""
#com="COM9"
Global comid.a=2
 
#ind_x=455
#ind_y=35
 
Global event
Global gadget
Global menu
Global tmkmd.a ;Принятый байт по Uart
Global stroka.s=""
Global Gn.a=0 ;номер кадра
Global Gg.a=0 ;Номер команды
Global Gm.a=0 ;Номер технологического кода
Global gs.c=0 ;Скорость шпинделя
Global Gx.d=0 ;Координа X из G-кода
Global Gz.d=0 ;Координа Z из G-кода
Global gp.a=0 ;Параметр команды
Global Gd.l=0 ;Параметр коррекции выбранного инструмента
Global gf.c   ;Скорость рабочей подачи
Global F.c    ;Скорость свободной подачи
Global x.d=0  ;Фактическая координата X
Global z.d=0  ;Фактическая координата Z
Global l.a=0 ;Используется для LEN
Global s.s="";Используется для MID и т.п.
Global numbr.s="";для набора цифр из строки
Global p.l=0 ;Используется в циклах FOR
Global o.l=0;Используется в циклах FOR
Global b.a=0;Байтовая переменная для разных одноразовых нужд
Global debugs.s=""
Global kadr.c=0 ;Номер обрабатываемого кадра
Global pusk.a=0 ;1=Пуск 2=отправка команды 3=ожидания начала исполнения 4=ожидание конца исполнения
Global Dim rx.a(200)
Global byterx.a=0 ;Проверочный байт в Usart
Global kmd.a=0 ;отправленная команда на Uart
Global indx.d =0 ;координаты для сравнения изменений при отражении
Global indz.d=0 ;координаты для сравнения изменений при отражении
Global vrd.d =0 ;временная переменная для рассчёта
Global vra.a=0;временная переменная для рассчёта
Global vrc.c=0;временная переменная для расчёта
If OpenWindow(#okno,0,0,800,600,"SCHAUBLINER 128", #PB_Window_ScreenCentered|#PB_Window_BorderLess);|#PB_Window_Maximize  )
  SetWindowColor(#okno,RGB(52, 52, 52))
  AddWindowTimer(#okno,1,20)
  ;CreateToolBar(#bar, WindowID(0) )  
  ; Добавляем две кнопки, дублирующие пункты "Открыть" и "Сохранить" меню  
  ;ToolBarStandardButton(0,#PB_ToolBarIcon_Open)  
  ;ToolBarStandardButton(1,#PB_ToolBarIcon_Save)  
  ; Добавляем всплывающие подсказки к кнопкам  
  ;ToolBarToolTip(#bar, 0, "Открыть программу")  
  ;ToolBarToolTip(#bar, 1, "Сохранить изменения")  
 
  CreateMenu(0,WindowID(0))  
  ; Создаём новый заголовок меню  
  MenuTitle("Программа")  
  ; Создаём пункты меню
  MenuItem(1,"Моделирование")
  MenuBar()  
  MenuItem(2,"Открыть программу")  
  MenuItem(3,"Сохранить изменения")  
  MenuBar()  
  MenuItem(4,"Создать программу")  
  ; Разделитель между меню  
  MenuBar()  
  MenuItem(5,"Выход")  
  MenuTitle("Параметры")  
  ; Создаём пункты меню
  MenuItem(6,"Нулевые точки")  
  MenuItem(7,"Инструмент")
  MenuBar()  
  MenuItem(8,"Машинные параметры")  
 
  ; Создаём новый заголовок меню  
  MenuTitle("Справка")  
  MenuItem(9,"О программе")  
 
 
  TextGadget(#Text0, 270, 500, 490, 30, "",#PB_Text_Border) ;вывод выбранной строки G-code
  TextGadget(#Textst, 270, 300, 490, 30, "N:0 G:0 M:0 X:0 Z:0 F:0 T:0",#PB_Text_Border) ;вывод строки статуса
  ListViewGadget(#List1, 10, 30, 250, 480)
  ButtonGadget(#kn1,10,520,250,30,"ПУСК")
 
  ;============ Отображение индикации
  TextGadget(#Textx1, #ind_x, #ind_y, 60, 40, "X:",#PB_Text_Right )
  TextGadget(#Textz1, #ind_x, #ind_y+45, 60, 40, "Z:",#PB_Text_Right )
 
  TextGadget(#Textx, #ind_x+75, #ind_y, 250, 40, "000.000мм")
  TextGadget(#Textz, #ind_x+75, #ind_y+45, 250, 40, "000.000мм" )
 
  TextGadget(#Textgs1, #ind_x, #ind_y+105, 60, 40, "S:" )
  TextGadget(#Textgs, #ind_x+40, #ind_y+105, 250, 40, "0об/мин.")
 
  TextGadget(#Textgf1, #ind_x, #ind_y+140, 60, 40, "F:")
  TextGadget(#Textgf, #ind_x+40, #ind_y+140, 250, 40, "0мм/мин.")
 
 
  If LoadFont(0, "Arial", 32, #PB_Font_Bold)                                                   ;Загрузка шрифта индикации осей
    SetGadgetFont(#textx, FontID(0))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textz, FontID(0))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textx1, FontID(0))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textz1, FontID(0))   ; Set the loaded Arial 16 font as new standard
   
   
    ;SetGadgetColor(#textx1, #PB_Gadget_FrontColor ,$00FF00)
    SetGadgetColor(#textx1, #PB_Gadget_BackColor ,$0087FF)
    ;SetGadgetColor(#textz1, #PB_Gadget_FrontColor ,$00FF00)
    SetGadgetColor(#textz1, #PB_Gadget_BackColor ,$0087FF)
   
    SetGadgetColor(#textx, #PB_Gadget_FrontColor ,$00FFFF)
    SetGadgetColor(#textx, #PB_Gadget_BackColor ,RGB(55, 55, 55))
    SetGadgetColor(#textz, #PB_Gadget_FrontColor ,$00FFFF)
    SetGadgetColor(#textz, #PB_Gadget_BackColor ,RGB(55, 55, 55))
  EndIf
 
  If LoadFont(1, "Arial", 24, #PB_Font_Bold)
    SetGadgetFont(#textgs1, FontID(1))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textgf1, FontID(1))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textgs, FontID(1))   ; Set the loaded Arial 16 font as new standard
    SetGadgetFont(#textgf, FontID(1))   ; Set the loaded Arial 16 font as new standard
   
   
    SetGadgetColor(#textgs1, #PB_Gadget_FrontColor ,RGB(255, 255, 255))
    SetGadgetColor(#textgs1, #PB_Gadget_BackColor ,$202020)
   
    SetGadgetColor(#textgs, #PB_Gadget_FrontColor ,RGB(255, 255, 255))
    SetGadgetColor(#textgs, #PB_Gadget_BackColor ,$202020)
   
    SetGadgetColor(#textgf1, #PB_Gadget_FrontColor ,RGB(255, 162, 4))
    SetGadgetColor(#textgf1, #PB_Gadget_BackColor ,$202020)
   
    SetGadgetColor(#textgf, #PB_Gadget_FrontColor ,RGB(255, 162, 4))
    SetGadgetColor(#textgf, #PB_Gadget_BackColor ,$202020)
  EndIf
 
 
  If LoadFont(2, "Arial", 15)                                                                  ;Загрузка  шрифта вывода строки
    SetGadgetFont(#text0, FontID(2))   ; Set the loaded Arial 16 font as new standard
  EndIf
 
  StartDrawing(WindowOutput(#okno))
  Box(445, 135, 345, 110, $202020)
  Box(445, 30, 345, 110, $202020)
  Box(525, 35, 260, 100, RGB(55, 55, 55))
  Box(450, 35, 75, 100, $0087FF)
 
  StopDrawing()
 
  SetGadgetState(#list1, 0) ;выбор первого пункта списка
  SetGadgetText(#text0, "Строка:"+ GetGadgetItemText(#list1,0))  
 
  If OpenSerialPort(2,#com,115200, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
  Else
    Debug "NO COM"
  EndIf
 
 
  Repeat
    Event=WaitWindowEvent() ; Узнаём текущее событие в программе  
    Gadget=EventGadget()
    Menu=EventMenu()
   
    If Event = #PB_Event_Timer And EventTimer() = 1 And kmd=0
      kmd=100
      tmkmd=0
      byterx=0
      While AvailableSerialPortInput(comID) > 0
        ReadSerialPortData(comID,@b,1)
        Debug Str(b)
      Wend
      WriteSerialPortData(comID,@kmd,1)
     
     
     
    EndIf
    If kmd=100 And AvailableSerialPortInput(2)>0
      While AvailableSerialPortInput(comID) > 0
        ReadSerialPortData(comID,@b,1)
        tmkmd+1
        rx(tmkmd)=b
       
       
        If tmkmd=7
          ;Debug Str(byterx)+"="+Str(b)
          ;Debug "OK UART"
          x=PeekW(@rx(2))
          x=x+rx(1)*10000
          x=x/1000
          z=PeekW(@rx(5))
          z=z+rx(4)*10000
          z=z/1000
          If indx<>x Or indz<>z
            SetGadgetText(#textx,StrD(x)+"мм.")
            SetGadgetText(#textz,StrD(z)+"мм.")
          EndIf
          indx=x
          indz=z
          kmd=0
          If byterx<>b
            Debug "ERROR COM"
            kmd=0
           
           
          EndIf
        Else
          byterx=byterx+b
        EndIf
      Wend
    EndIf
   
   
   
   
    ;If gadget=#list1 And EventType()=#PB_EventType_LeftClick                       ; Действия выбора клика на список
    ; EndIf
   
    If event=#PB_Event_Menu                                                         ;Выбор меню
      If menu=2                                                                     ;Открываем окно выбора файла
        File=OpenFileRequester("Открыть файл", "", "*.txt|*.txt|All Files|*.*", 0)
       
        If File<>""
          ClearGadgetItems(#list1)
          If ReadFile(1,file)
            Repeat
             
              AddGadgetItem (#list1, -1, ReadString(1))
            Until Eof(1)=1
            CloseFile(1)
            SetGadgetState(#list1, 0) ;выбор первого пункта списка
          EndIf
        EndIf
      EndIf
      If menu=5
        CloseSerialPort(2)
        Break
      EndIf
    EndIf
   
   
   
   
    If gadget=#kn1 And EventType()=#PB_EventType_LeftClick  
      If pusk=0 And CountGadgetItems(#list1)>0
        kadr=0
        pusk=1
        SetGadgetText(#kn1,"СТОП")
      Else
        SetGadgetText(#kn1,"ПУСК")
        kadr=0
        SetGadgetState(#list1, kadr)
      EndIf
     
     
    EndIf
   
   
   
    ;====================================================== ПУСК УП Программы
    If pusk=1
      ;stroka=GetGadgetItemText(#list1,GetGadgetState(#list1))
      stroka=GetGadgetItemText(#list1,kadr)
      Gosub gcode:
     SetGadgetText(#textgf,Str(gf)+"мм/мин.")
      SetGadgetText(#textgs,Str(gs)+"об/мин.")
      SetGadgetText(#text0, "Строка:"+ debugs)
      ;TextGadget(#Textst, 270, 300, 490, 30, Str(x1)+" "+Str(y1)+" "+Str(x2)+" "+Str(y2))
      ;TextGadget(#Textst, 270, 300, 490, 30, "N:"+Str(gn)+" G:"+Str(gg) +" M:"+Str(gm)+" X:"+StrD(gx)+" Z:"+StrD(gz)+" S:"+Str(gs)+" F:"+Str(gf)+" T:"+Str(gt),#PB_Text_Border) ;вывод строки статуса
     
      ;Line(270,100,100,100,RGB(255,0,0))
      x=gx
      z=gz
      If kadr=CountGadgetItems(#list1)
        pusk=0
        kadr=0
        SetGadgetText(#kn1,"ПУСК")
        SetGadgetState(#list1, kadr)
      Else
        kadr+1
        SetGadgetState(#list1, kadr) ;выбор первого пункта списка
        pusk=2
       
      EndIf
     
    EndIf
   
    If pusk=2 And kmd=0                             ; Отправка параметров к исполнению
      While AvailableSerialPortInput(comID) > 0
        ReadSerialPortData(comID,@b,1)
        Debug Str(b)
      Wend
      pusk=1
      If gx<>0 Or gz<>0
        ;Протокол:
        ;1.Команда 126
        ;2.Направление и режим такта (Бит0-направление X, Бит1-направление Z.... в разработке)
        ;3.Скорость такта HByte
        ;4.Скорость такта LByte
        ;5.Сантиметры X
        ;6.Миллиметры X Hbyte
        ;7.Миллиметры X Lbyte
        ;8.Период X Hbyte
        ;9.Период X Lbyte
        ;10.Сантиметры Z
        ;11.Миллиметры Z Hbyte
        ;12.Миллиметры Z Lbyte
        ;13.Период Z Hbyte
        ;14.Период Z Lbyte
        ;15.Пров.байт
        ;
        ;
        kmd=126
        WriteSerialPortData(comID,@kmd,1) ;1 Команда 126
        If gx<0 And gz<0
          kmd=3
        ElseIf gx<0 And gz>0
          kmd=1
        ElseIf gx>0 And gz<0
          kmd=2
        ElseIf gx>0 And gz>0
          kmd=0
        EndIf
       
        WriteSerialPortData(comID,@kmd,1);2 Направление и режим такта (Бит0-направление X, Бит1-направление Z.... в разработке)
       
        gf=gf+8
        WriteSerialPortData(comID,@gf,2);3 Скорость такта HByte
        ;kmd=126
        ;WriteSerialPortData(comID,@kmd,1);4 Скорость такта LByte
       
        If gx<0
          gx=0-gx
        EndIf
        If gz<0
          gz=0-gx
        EndIf
        If gx>10
          kmd=gx/10
        Else
          kmd=0
        EndIf
        WriteSerialPortData(comID,@kmd,1);5 Сантиметры X
       
        WriteSerialPortData(comID,@kmd,1);6 Миллиметры X Hbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);7 Миллиметры X Lbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);8 Период X Hbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);9 Период X Lbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);10 Сантиметры Z
        kmd=126
        WriteSerialPortData(comID,@kmd,1);11 Миллиметры Z Hbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);12 Миллиметры X Lbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);13 Период Z Hbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);14 Период Z Lbyte
        kmd=126
        WriteSerialPortData(comID,@kmd,1);15 Пров.байт
      Else
       
       
      EndIf
     
    EndIf
   
    If pusk=3 And kmd=0                              ;Ожидание ответа начала исполнения
     
      If AvailableSerialPortInput(comid)>0
        ReadSerialPortData(comID,@b,1)
        If b=251
          pusk=4
        EndIf
       
      EndIf
    EndIf
   
    If pusk=4 And kmd=0                              ;Ожидание ответа заверщения исполнения
     
      If AvailableSerialPortInput(comid)>0
        ReadSerialPortData(comID,@b,1)
        If b=250
          pusk=1
        EndIf
       
      EndIf
    EndIf
   
  Until Event = #PB_Event_CloseWindow
 
EndIf
End
 
 
gcode:
l=Len(stroka)
debugs=""
For p=1 To l
  s=Mid(stroka,p,1)
  b=Asc(s)
  If b>64
    debugs=debugs+s
    numbr=""
   
    If s="M" Or s="m"                 ;Находим значение M
      Gosub gfor:
     debugs=debugs+numbr
      gm=Val(numbr)
     
    ElseIf s="G" Or s="g"             ;Находим значение G
      Gosub gfor:
     Gg=Val(numbr)
      debugs=debugs+numbr
     
    ElseIf s="N" Or s="n"             ;Находим значение N
      Gosub gfor:
     Gn=Val(numbr)
      debugs=debugs+numbr
     
    ElseIf s="P" Or s="p"             ;Находим значение P
      Gosub gfor:
     Gp=Val(numbr)  
      debugs=debugs+numbr
     
    ElseIf s="X" Or s="x"             ;Находим значение X
      Gosub gfor:
     
      Gx=ValD(numbr)
     
      debugs=debugs+numbr
     
    ElseIf s="Z" Or s="z"            ;Находим значение Z
      Gosub gfor:
     Gz=ValD(numbr)
      debugs=debugs+numbr
     
    ElseIf s="S" Or s="s"             ;Находим значение S
      Gosub gfor:
     
      Gs=Val(numbr)
      debugs=debugs+numbr
     
    ElseIf s="F" Or s="f"             ;Находим значение F
      Gosub gfor:
     
      Gf=Val(numbr)
      debugs=debugs+numbr
     
    ElseIf s="D" Or s="d"            ;Находим значение D
      Gosub gfor:
     
      Gz=Val(numbr)
      debugs=debugs+numbr
    EndIf
  EndIf
Next p
 
Return
gfor:
p=p+1
For o=p To l
  b=Asc(Mid(stroka,o,1))
  If b=44 ;Исправляем запятую на точку
    b=46
  EndIf
 
  If b>43 And b<58
    numbr=numbr+Chr(b)
  ElseIf b>58 Or b<32
    Break
  EndIf
Next o
Return
 


Тестовый G-cod
Код:
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
%MPF5   
N0005 G92 S4000
N0010 G94 X-35 S1000 M8 M3 D1
N0015 Z-1.8
N0020 G1 X-31.4 Z0 F80
N0025 X-5
N0030 G Z30
N0035 G40 X0 M3 D2
N0040 G Z1
N0045 G1 Z-3.3 F35
N0050 G4 X0.2
N0055 G1 Z0 F200
N0060 G Z30
N0065 G40 X-18.3 M3 D3
N0070 Z2
N0071 G1 Z-0.831 F60
N0072 X-21.362 Z-3.6
N0073 X-10
N0075 G Z1
N0076 G1 X-19.584 F300
N0077 G1 Z0 F60
N0080 G3 X-18.684 Z-0.45 I0 K-0.45
N0085 G3 X-18.804 Z-0.675 I-0.45 K0
N0090 G1 X-22.178 Z-3.6
N0095 X-10 F60
N0100 G Z100 M9
N0105 G40 X-35 D1 M5
N0110 M11
N0115 M2



Ну как-то так вот )))


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 12:53 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11194
Благодарил (а): 4 раз.
Поблагодарили: 417 раз.
Ev3658 писал(а):
Двухбайтные переменные далеко не одинаковы, к примеру "Character" .c и "Unicode" .u выдают разное значение при Debug:
Переменная типа Character двухвайтовая только если программа компилируется с поддержкой юникода. Иначе она однобайтовая. Она предназначена для работы с символами.
Необходимо использовать тип Word если переменная должна быть со знаком, или Unicode для беззнаковых переменных.

Ev3658 писал(а):
Или байт=256?
Ну да. :)
В байтовой переменной хранятся числа от 0 до 255, а вместимость 256.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 1:35 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11194
Благодарил (а): 4 раз.
Поблагодарили: 417 раз.
Ev3658 писал(а):
Для перемещения данные отправляются по байтам в следующем порядке:
Чтобы было проще и меньше путаницы, отправляемый пакет можно оформить в виде структуры.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Structure SendDevice
  Cmd.a        ;1.Команда бай (126) - перемещение
  Direction.a  ;2.Направление и режим такта (Бит0-направление X, Бит1-направление Z.... в разработке)
  Steps.u      ;3.Скорость такта HByte
               ;4.Скорость такта LByte
  X_cm.a       ;5.Сантиметры X
  X_mm.u       ;6.Миллиметры X Hbyte
               ;7.Миллиметры X Lbyte
  X_Period.u   ;8.Период X Hbyte
               ;9.Период X Lbyte
  Z_cm.a       ;10.Сантиметры Z
  Z_mm.u       ;11.Миллиметры Z Hbyte
               ;12.Миллиметры Z Lbyte
  Z_Period.u   ;13.Период Z Hbyte
               ;14.Период Z Lbyte
  Summ.a       ;15.Пров.байт - каждый байт в B.a=B+отправляемый байт (контрольная сумма)
EndStructure


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 9:17 pm 
Не в сети
ассистент

Зарегистрирован: Ср мар 30, 2016 9:45 pm
Сообщений: 15
Благодарил (а): 0 раз.
Поблагодарили: 3 раз.
;1.Команда бай (126) - перемещение
;2.Направление и режим такта (Бит0-направление X, Бит1-направление Z.... в разработке)
А у мотора всего два возможных состояния ? может их всетаки три?

;3.Скорость такта HByte
;4.Скорость такта LByte
;5.Сантиметры X
Все расстояния задаются и измеряются в миллиметрах
;6.Миллиметры X Hbyte
;7.Миллиметры X Lbyte
;8.Период X Hbyte
;9.Период X Lbyte
;10.Сантиметры Z
;11.Миллиметры Z Hbyte
;12.Миллиметры Z Lbyte
;13.Период Z Hbyte
;14.Период Z Lbyte
;15.Пров.байт - каждый байт в B.a=B+отправляемый байт (контрольная сумма)

Вся суть в том, что нужно передать сантиметры (0-255), микроны (0-1000) и период (0-65536). (1микрон = 0,001мм) из данных ±X=0000.000 ±Z=0000.000 SPEED=0000

Может быть лучше сразу считать в дискретных единицах энкодора ?

Период это типа редукция, к примеру надо переместится на 10 см по первому двигателю и на 1 см по второму, так вот, период это пропуск тактом в микронах, пока движется 10см, другой двигается по микронам с пропуском тактов(период) первого двигателя.
Скорость такта - это внутренний генератор в устройстве, который задаёт импульсы для равномерного перемещения.

Я бы рекомендовал Вам ознакомиться с промышленными системами управления ЧПУ, например Siemens Sinumerik 840 и примерами расчета хотя-бы линейной интерполяции. Там все далеко не так просто как кажется.

По поводу передачи данных в контроллер и обратно, шлите их как есть, они все равно идут через буфер UART на компе, только со стороны контроллера их и принимать и посылать нужно именно в той-же последовательности и размерности т.е передаешь с компа байт, будь любезен и на контроллере принимать именно байт и не слово или строку ;)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Битовые операции
СообщениеДобавлено: Пт дек 01, 2017 9:45 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Ср май 18, 2016 11:52 pm
Сообщений: 34
Откуда: Нижегородская обл.
Благодарил (а): 16 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Polkovnik писал(а):
.... ознакомиться с промышленными системами управления ЧПУ, например Siemens Sinumerik 840 и примерами расчета хотя-бы линейной интерполяции. Там все далеко не так просто как кажется.

По поводу передачи данных в контроллер и обратно, шлите их как есть, они все равно идут через буфер UART на компе, только со стороны контроллера их и принимать и посылать нужно именно в той-же последовательности и размерности т.е передаешь с компа байт, будь любезен и на контроллере принимать именно байт и не слово или строку ;)


Пока всё предусмотрел, с ЧПУ знаком.
Отдельно от позиции перемещения регулируется сама скорость, так-же если скорость равна нулю, то всё останавливается и отсылается недоделанный остаток. Ну ещё несколько режимом для импульсного перемещения и линейного.
Этот STEP/DIR облегчает ситуацию, но надёжней конечно сделать полностью аппаратное слежение за осями.
По сути дела делаю ЧПУ, которое управляет моторами по Step/DIR но отображает фактическую индикацию положения, а не программную.
После отсылки команды, она в контроллере принимается, раскладывается по регистрам таймеров и т.п., а дальше контроллер сообщает о начале выполнения и тем самым уже готов принять следующие данные пока выполняются предыдущие.
В контроллере серии Xmega очень хорошие аппаратные штуки, единственный минус - не смог аппаратно сделать 32 битный квадратурный счёт, только 16 + программное расширение.
Ещё подумаю как, хотелось бы отказаться от Uart в сторону USB HID устройства.
P:S: Меня одолели всякие люди призывающие к Си ибо он и все на нём и всё такое.... :evil: , сил уже нет отбиваться.


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB