Оборудование для производства стеклопластиковой арматуры и композитной кладочной сетки
  Оборудование для производства арматуры и сетки Оборудование для производства стеклопластиковой арматуры Оборудование для производства стеклопластиковой сетки ЧПУ аппарат плазменной резки оборудование автоматизированного раскроя металла Прайс лист цена композитная стеклопластиковая арматура и пластиковая кладочная сетка в Екатеринбурге от производителя на Урале Скачать расчёты, бизнес план по производству Чертежи оборудования для производства стеклопластиковой арматуры сделать своими руками Заработать миллион своими руками Производство своими руками  
  ГЛАВНАЯ ОБОРУДОВАНИЕ
ДЛЯ АРМАТУРЫ
ОБОРУДОВАНИЕ
ДЛЯ СЕТКИ
ЧПУ
ПЛАЗМЕННАЯ РЕЗКА
ГИДРОАБРАЗИВНАЯ
РЕЗКА
Новинка!
АВТОНОМНЫЙ
КОНТРОЛЛЕР
ПРАЙС
АРМАТУРА И СЕТКА
СКАЧАТЬ
РАСЧЁТЫ

(для арматуры)
ЧЕРТЕЖИ
ОБОРУДОВАНИЯ

(для арматуры)
ФОТО И ВИДЕО СОТРУДНИЧЕСТВО КОНТАКТЫ  

 

  Мини стол ЧПУ плазменной резки с автономным контроллером с ТНС.  
  Стол 3000х1500мм ЧПУ плазменной резки с автономным контроллером с ТНС.  
  Автономный контроллер и электроника для стола ЧПУ.  
  Набор для самостоятельной сборки ЧПУ стола плазменной резки.  
  ТНС для Mach3.  
Схема и программа Автономного контроллера для стола ЧПУ плазменной резки на STM32 stm32f103rct6  
  ТНС на стрелочном вольтметре для Mach3  
  Установка и настройка mach3  
  Установка и настройка Pronest  
  Фрезер ЧПУ  

Автономный ЧПУ контроллер с ТНС для плазменной резки.

Схема автономного ЧПУ контроллера на базе STM32 собрать своими руками.

Стоимость готового контроллера 19 500 руб.

ВНИМАНИЕ!!!
Ниже информация для САМОСТОЯТЕЛЬНОЙ сборки контроллера.
для самодельщиков, т.е. людей которые хотят спаять контроллер самостоятельно.

 

Прошивка от 24.11.17 Armatura-ural.bin  для самодельной платы, описанной ниже.
есть скрытое меню настройки станка, при загрузке нужно удержать THC ON,
если при загрузке удержать THC ON и THC OFF будут загружены заводские настройки по умолчанию

Прошивка для заводской платы, купленной у меня. (разница в подключении периферии к микроконтроллеру. LCD, кнопки и выходы подключены к другим выводам МК в отличии от прошивки выше)
MyBootload.bin  MyBootload.hex - автозагрузчик прошивки (для самопрограммирования)
Armatura-ural.bin - рабочая программа (от 3.09.18 поддержка отрицательных координат g-кодов)
Armatura-ural.bin - версия от 02.10.18
при изменении траектории движения менее 30 градусов не тормозит, т.е. можно рисовать мелкими отрезками контроллер их склеивает в одну кривую.
также есть два новых параметра настроек - z_plasma_on - высота включения плазмы/газа, можно сделать отличное от z_start - высоты начала движения, этот параметр введён в основном для аппаратов с контактным поджигом.
и thc_time - время измерения thc, по умолчанию нужно выставить 1000, что соответствует 0,1сек, т.е. 10 измерений ТНС за одну секунду, этот параметр введён для корректировки показаний ТНС программным способом.
ALL.bin или ALL.hex - всё в одном - автозагрузчик, программа и настройки. Лучше загружать его вместо бутлодыря, сначала установите эту прошивку как базовую, а затем обновляете..
Armatura-ural.bin - версия от 24.03.19г  (постпроцессор Armatura-ural.cff)
Чтобы обновить прошивку, нужно этот файл сохранить на СДкарту, вставить в контроллер и нажать "Сброс"
ВНИМАНИЕ!!! перед обновлением сохраните настройки на бумажку, т.к. ранее я слишком много памяти отвёл для этих настроек, сейчас пришлось их подвинуть, и придётся их вводить заново.
Эта версия сделана для слишком-сильно-мощно-помехоизлучающих аппаратов. При больших помехах сам микроконтроллер работает стабильно, а периферия отваливается.
При чтении данных с флэшки она бывает "сбрасывается" и начинает выдавать данные сначала либо просто передаёт данные с ошибкой в цифре. Бывает, что после работы на плазме, вставляешь её в комп и он, падла, предлагает её форматировать. Повторю - это бывает не часто, т.е. не на всех аппаратах, я сталкивался с такими помехами только на аппаратах на 220В.
В данном варианте ПО, при нажатии на СТАРТ вся программа (если она менее 200кб, для сравнения - чтобы вырезать 100 квадратов любых размеров нужно менее 2кб) переписывается на внутреннюю память микроконтроллера, далее флэшку можно убирать, если Gкоды более 200кб то чтение производится как и ранее, с флэшки. Если что-либо есть в памяти, при нажатии на СТАРТ контроллер начинает выполнять эти инструкции, не смотря на наличии флэшки, чтобы очистить внутреннюю память нужно нажать УДАЛИТЬ. При первом нажатии на СТАРТ копируется программа, при втором - запускается.

Armatura-ural.bin - версия от 07.11.2019.
Добавлено
1)  контроль наличия дуги ,при паузе прожига (М3) > 0, ждёт поджига дуги, затем начинает отсчёт паузы, если дуга не зажглась в течение 10 сек, то предлагает либо повторить либо продолжить без контроля плазмы
если при резке пропадает дуга, останавливается, запоминает место остановки (можно перемещать портал, он сам вернётся на это место) и ждёт нажатия СТАРТ
2) выбор варианта чтения Gкодов
 - чтение с флэшки построчно во время реза (быстро, без предварительный "размышлений", каждая строчка - отдельный отрезок со своим разгоном и торможением)
 - чтение с флэшки во время реза с предварительным вычислением точек остановки (если траектория движения у следующего отрезка изменяется менее 30° то переход на следующую строку Gкода происходит без торможения, например, вырезая квадрат с закруглёнными углами, станок пройдёт не снижая скорости до конца траектории, а если вырезать простой квадрат, то в каждом углу будет плавное торможения и плавное ускорение. При сложной художке долго думает перед стартом)
 - чтение с внутренней памяти контроллера (перед стартом контроллер копирует ВЕСЬ Gкод во внутреннюю память, попутно вычисляя точки остановки, ограничение примерно 200кб, если не влезет то переходит к варианту описанному выше.
3) при нажатии РАДИУС сначала указывается центр, при втором нажатии указывается окружность (радиус)

Armatura-ural.bin - версия от 19.11.19г
работает ТОЛЬКО с построцессором Armatura-ural.cff v4.0 для ProNest, и Armatura-ural.scpost для >>>> SheetCam <<<<
рекомендую использовать флэшки class 10 (с ними в разы быстрее думает контроллер перед стартом)
Добавлено:
1) ВСЕ данные в G-коде повторяются ТРИ раза. В этой версии упор сделан на прямое чтение G-кода с флэшки по время работы плазмы поэтому такая перестраховка. Также сохраняется возможность копирования данных на внутреннюю память перед запуском.
Бывают битые кластеры флэшки либо ошибка при чтении данных во время работы т.к. помехи от плазмы влияют и на флэшку , поэтому каждая переменная содержится в одной строке в трёх экземплярах, если одна из трёх версий не совпадает с двумя, она отбрасывается и считается за истину те, которые совпали, и данные одной переменной находятся в разны частях строки, что исключает случайную одинаковую ошибку, ну а если не совпадут все три значения - процессор самоуничтожается, запуская процесс аннигиляции всего портала.
2) Утилита Armatura-ural.bat  (запускаете её в папке, где у вас получился файл Gкода, файл должен называться Untitled.cnc или 1.cnc после выполнения он заменяется файлом program.cnc, который запускаете в контроллере.)
Также как и в версии выше есть три варианта чтения данных - 1)чтение сразу с карты, 2)чтение с карты с анализом траектории перед стартом, 3)с копированием всех точек во внутреннюю память.
Анализ траектории делается для того, чтобы не замедлять скорость на промежуточных точках, где отклонения траектории менее 30°
В первых двух вариантах жалательно, не обязательно, пользоваться этой утилитой, в первом случае она уберёт такие остановки, во втором случае контроллер сразу приступит к работе, без предварительного анализа траектории. В третьем варианте применение утилиты ни на что не влияет.
3) G02 и G03 совершенно другая математика, теперь в Gкоде указывается угол дуги.
4) Более точное позиционирование. Разброс на финише не более 1шага.
5) Возможность отключения ТНС на поворотах на замедлениях траектории.

Armatura-ural.bin - версия от 10.01.20г. (внесены исправления 14.05.20г., обновите.)
Добавлено меню выбора исполняемого файла G-кода. При пером нажатии на СТАРТ читает названия файлов, листать кнопкой Z- по кругу пока не будет нажата второй раз кнопка СТАРТ, не более 15 файлов, названия файлов не более 20 символов латиницей.

Пример G-кода Untitled.cnc от ProNest и пример той же детали от SheetCam Untitled.cnc

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

Предлагаю сотрудничество - нужны люди для изготовления и самое главное для его сопровождения (консультаций).
Объясню - заказать изготовление клонов можно и в Китае, но их нужно подключить и настроить, также нужно настроить компьютер для работы с данным устройством (сохранение чертежей в определённом формате, перевод в G-коды). У каждого станка есть свои особенности, разные хотелки и убеждения их хозяев и т.д.
Кто может и хочет заняться изготовлением, модернизацией, ремонтом станков ЧПУ, роботов сварщиков и т.д. - пишите мне на электронку, интересуют все регионы СНГ и Ваши возможности (самостоятельная сборка контроллера ЧПУ (желательно, но не обязательно), программирование, контроллера (переделка кода под определённый станок и задачу), монтаж и ремонт у заказчика, консультации по телефону и др.)
Порядок работы - заказчик обращается ко мне, я даю контакты ближайшего грамотного специалиста, при необходимости высылаю контроллер (работа на дому - пайка и программирование для желающих), монтаж, пуско-наладка, последующие консультации, оплата.

Сразу оговорюсь - это мой первый проект с STM32 и с данным контроллером столкнулся впервые, т.ч. критика ПО СУЩЕСТВУ приветствуется.
На вопросы "у меня не открывается rutracker.org", "как купить на taobao.com", "дайте ссылку тоже самое но на aliexpress.com" не отвечаю и переписку прекращаю, т.к. если этот вопрос человек не может решить даже с помощью яндекс/google, то в изготовлении контроллера он далеко не продвинется и тратить на него время бессмысленно. (это касается самодельщиков, т.е. людей которые хотят спаять контроллер самостоятельно)

Сейчас я заказываю платы в Китае. Готовые платы из Китая дешевле чем у нас купить текстолит.

Стоимость набора для самостоятельной сборки 12 500 руб.
Стоимость только плат (основная + одна маленькая) 2 500руб.

Ниже я описал способ быстрого (я это делаю примерно за час), самостоятельного изготовления платы в домашних условиях.

Я остановил свой выбор на камне STM32F103RCT6, чтобы упростить себе жизнь я купил вот это https://world.taobao.com/item/539338239052.htm
также надо заказать https://world.taobao.com/item/38499936009.htm

Скачайте программу Sprint-Layout_6_RUS и файл платы и файл платы для печати

Я делаю плату по ЛУТ технологии из одностороннего стеклотекстолита 1мм (1мм важно!!!)

Купить заклёпку пустотелую М1,2х3 можно
1) www.irivet.ru 1руб/шт мин партия 5000шт.
2) http://www.optprommetiz.ru 26,13руб/шт. 200шт. = 5 226 руб за 200шт. срок поставки 8 недель
3) https://world.taobao.com/item/8987113918.htm 30 руб. за 200шт. (срок доставки из Китая 3 недели)

Схема автономного контроллера ЧПУ плазменной резки на микроконтроллере STM32
 STM32F103RCT6 с контролем высоты THC по напряжению дуги плазмы

Эта схема для платы описанной выше

в формате Splan70 скачать схему

Преобразователь напряжение-частота с двойной гальванической развязкой (трансформатор и оптопара)

Схема для заводской платы (купленной у меня) как вот эта
(схема обновлена 16.06.18, если просматривали её ранее, то нажмите F5)

в формате Splan70 скачать схему

 

После долгого выбора компилятора (перебрал все доступные Keil, IAR, CooCox), я остановился на mikroBasic (можно mikroC или mikroPascal) от MikroElektronika, т.к в школе я изучал Basic и его основы помню до сих пор.
Для начинающих программистов это самый простой и понятный компилятор схож с Ардуино.
качаем здесь http://rutracker.org/forum/viewtopic.php?t=5203160
также надо скачать и установить библиотеку FAT32 https://libstock.mikroe.com/projects/view/108/fat32-library (иначе читать флэшку можно будет только в системе FAT16)
Package Manager для установки библиотек http://www.mikroe.com/supporting-software/

Для начала загружаем Bootloader в контроллер пользуясь программой "Flash Loader Demo" и переходником UART например https://detail.tmall.com/item.htm?id=528794539661 или самодельным
Bootloader - это программа для самопрограммирования контроллера, при включении она открывает флэшку и если там есть файл "Armatura-ural.bin", то переписывает его в область программ и стирает с флэшки. Очень удобная вещь как для себя, так и для удалённой поддержки клиентов.
Процесс первой загрузки хорошо описан здесь http://easystm32.ru/useful-things/42-bootloader-stm32, затем все последующие перепрограммирования будет делать "бутлодырь".

Т.к. у нас начальную область памяти занимает bootloader, то нам надо настроить чтобы начало программы было после него.
Находим файл STM32F103RC.mlk у меня он C:\Users\Public\Documents\Mikroelektronika\mikroBasic PRO for ARM\Defs
и меняем ROM - MIN_ADDR - 0x00008000

Качайте исходники Armatura-ural.zip

при запуске надо отключить библиотеку USB

Если вы будете делать другой проект то вам пригодятся настройки тактирования (рабочий пример)

После компиляции копируем файл "Armatura-ural.bin" на флэшку, вставляем в автономный контроллер ЧПУ и нажимаем ресет

Сразу пару комментариев:
1) С Алгоритмом Брезенхэма я не подружился. Накопительная ошибка и разница в скоростях перехода на шаг по X и Y (т.е. при разной длине шага X и Y нужно менять задержку)
2) В данных исходниках отсутствует меню настроек констант (т.е. настройки станка), если человек может скомпилировать программу, ему не сложно изменить константы в компиляторе.
Готовые прошивки будут выкладываться с более расширенными возможностями. Это сделано сознательно, для того чтобы этот контроллер не ушёл в китайскую серию в кратчайший срок.
3) Все прошивки полнофункциональные. Никаких демо-ограничений и т.п.

Прошивки буду выкладывать вверху страницы, для обновления нужно скопировать файл "Armatura-ural.bin" на флэшку, вставить в автономный контроллер ЧПУ и нажать ресет

Это первая моя программа (я не программист), т.ч. советы, комментарии, алгоритмы, идеи и многое другое приветствуется ))) пишите мне на электронку.

Весь проект скачать можно здесь.

Текст программы:

program Armatura_ural
const  dlina_impulsa_x = 0.1          'расстояние перемещения при одном импульсе мм
const  dlina_impulsa_y = 0.1          'расстояние перемещения при одном импульсе мм
const  dlina_impulsa_z = 0.1          'расстояние перемещения при одном импульсе мм
const  dlina_hoda = 0.05              'приращение хода по траектории мм (должно быть меньше dlina_impulsa_x и dlina_impulsa_y)
const  vremya_uskor_g0 = 4000         'время ускорения 2000 = 1сек до skorost_holost_hoda
const  skorost_holost_hoda = 8000     'скорость холостого хода мм в минуту
const  start_skor = 50                'стартовая скорость мм в минуту
const  skorost_max = 2000             'максимальная рабочая скорость мм в минуту
const  skorost_min = 50               'минимальная рабочая скорость мм в минуту
const  skorost_z = 500                'скорость хода z
const  z_up = 100                     'высота Z при холостом перемещении
const  z_down = -10                   'минимальная высота при поиске металла
const  z_probe = -3                   'высота при срабатывании датчика
const  z_start = 2                    'высота поджига плазмы
const  skorost_thc = 50               'скорость ТНС
const  thc_max = 50                   'высота макс ТНС
const  thc_min = -50                  'высота мин ТНС
const  thc_dopusk = 2                 'не реагирует на эту величину при изменнении ТНС
dim LCD_RS as sbit at GPIOA_ODR.12
dim LCD_EN as sbit at GPIOA_ODR.11
dim LCD_D4 as sbit at GPIOA_ODR.4
dim LCD_D5 as sbit at GPIOA_ODR.3
dim LCD_D6 as sbit at GPIOA_ODR.2
dim LCD_D7 as sbit at GPIOA_ODR.1
dim Mmc_Chip_Select as sbit at GPIOA_ODR.8
dim pin_step_x as sbit at GPIOB_ODR.14
dim pin_dir_x as sbit at GPIOB_ODR.13
dim pin_step_y as sbit at GPIOB_ODR.12
dim pin_dir_y as sbit at GPIOB_ODR.11
dim pin_step_z as sbit at GPIOB_ODR.10
dim pin_dir_z as sbit at GPIOB_ODR.9
dim plasma_on as sbit at GPIOB_ODR.15
dim probe as sbit at GPIOB_IDR.0
dim knopka_vpravo as sbit at GPIOC_IDR.13
dim knopka_vlevo as sbit at GPIOC_IDR.12
dim knopka_vniz as sbit at GPIOC_IDR.11
dim knopka_vverh as sbit at GPIOC_IDR.10
dim knopka_vniz_z as sbit at GPIOC_IDR.9
dim knopka_vverh_z as sbit at GPIOC_IDR.8
dim knopka_x0y0 as sbit at GPIOC_IDR.7
dim knopka_home as sbit at GPIOC_IDR.6
dim knopka_thc_off as sbit at GPIOC_IDR.5
dim knopka_thc_on as sbit at GPIOC_IDR.4
dim knopka_thc_minus as sbit at GPIOC_IDR.3
dim knopka_thc_plus as sbit at GPIOC_IDR.2
dim knopka_stop as sbit at GPIOC_IDR.1
dim knopka_start as sbit at GPIOC_IDR.0
dim x, y, x0, y0, x1, y1, x0stop, x1stop, y0stop, y1stop, skorost, l, l_uskor, dlina, pausa as float 'extended 'координаты текущие, начальные и конечные
dim z, i, j, a, a_start, a_end, a_shag, a_uskor, radius as float
dim koordinata, koordinata1 as integer           'переменные для вывода координат на экран
dim txt2 as char[2]
dim num5 as char[5]
dim txt5 as char[5]                              'для вывода на экран
dim txt6 as char[6]                              'для вывода на экран
dim txt8 as char[8]                              'для вывода на экран
dim txt20 as char[20]                              'для вывода на экран
dim txt22 as char[22]                              'для вывода на экран
dim thc_imp, thc_norma, adc, adc1, pausa_start, pausa_m3, pausa_m5 as word
dim flag, flag2 as word
dim time_start, time_start_y as word
dim pausa_min, pausa_min_temp, pausa_max, pausa_max_y, pausa_min_y, pausa_z, pausa_thc as word
dim time_uskor, vremya_uskor as longword
dim program_bin as char[11]
dim size, size1 as longword 
dim nomer_file as short
dim cd_byte as byte
dim flag_uskor as sbit at flag.0
dim flag_tormoz as sbit at flag.1
dim flag_uskor_x as sbit at flag.2
dim flag_tormoz_x as sbit at flag.3
dim flag_uskor_y as sbit at flag.4
dim flag_tormoz_y as sbit at flag.5
dim flag_adc as sbit at flag.6
dim flag_thc_on as sbit at flag.7
dim flag_thc_knopka as sbit at flag.8
dim flag_z_up as sbit at flag.9
dim flag_z_down as sbit at flag.10
dim flag_g0g1 as sbit at flag.11        ' 0 G0   0 G1   1 G2   1 G3
dim flag_g2g3 as sbit at flag.12        ' 0      1      0      1
dim flag_z_to_z_start as sbit at flag.13
dim flag_pausa_start as sbit at flag.14
dim flag_pausa_stop as sbit at flag.15
dim flag_cd_init as sbit at flag2.0
dim flag_cd_read as sbit at flag2.1
dim flag_thc_up as sbit at flag2.2
dim flag_thc_down as sbit at flag2.3
dim flag_stop as sbit at flag2.4
dim flag_stop_g0g1 as sbit at flag2.5
dim flag_stop_g2g3 as sbit at flag2.6
dim flag_stop_z_up as sbit at flag2.7
dim flag_stop_z_down as sbit at flag2.8
dim flag_stop_pausa_start as sbit at flag2.9
dim flag_stop_pausa_stop as sbit at flag2.10
dim flag_start as sbit at flag2.11
dim flag_z_down_and_start as sbit at flag2.12
dim flag_dont_read as sbit at flag2.13
dim flag_m30 as sbit at flag2.14
sub procedure Step_X_ON() iv IVT_INT_TIM1_UP ics ICS_AUTO '1 Step_X_ON
    TIM1_SR.UIF = 0  'сбрасываем флаг прерывания
    TIM1_CR1.CEN = 0  'выключаем счётчик 1
    pin_step_x = 0    'выключаем сигнал step_z
end sub
sub procedure Step_Y_ON() iv IVT_INT_TIM2 ics ICS_AUTO  '2 Step_Y_ON
    TIM2_SR.UIF = 0   'сбрасываем флаг прерывания
    TIM2_CR1.CEN = 0  'выключаем счётчик 2
    pin_step_y = 0    'выключаем сигнал step_x
end sub
sub procedure Step_Z_ON() iv IVT_INT_TIM4 ics ICS_AUTO  '4 Step_Z_ON
    TIM4_SR.UIF = 0  'сбрасываем флаг прерывания
    if ((flag_z_up = 1) or (flag_z_to_z_start = 1)) then 
       pin_dir_z = 0
    else if flag_z_down = 1 then pin_dir_z = 1 end if
    end if
    if pin_step_z = 1     'если есть сигнал
    then pin_step_z = 0   'тогда сбрасываем его
         if pin_dir_z = 0 then z = z + dlina_impulsa_z else z = z - dlina_impulsa_z end if
         BKP_DR10 = LoWord(z) BKP_DR11 = HiWord(z)  'запоминаем координату
    else
         if ((flag_z_up = 1) or (flag_z_down = 1))   'если движимся в автоматическом режиме
         then
             if flag_stop = 1 then      'если есть флаг остановки
               flag_z_down = 0          'убираем текущие флаги
               flag_z_up = 0
               flag_z_to_z_start = 0
               TIM4_CR1.CEN = 0          'останавливаю счётчик
               pin_dir_z = 0             'обнуляю вывод дир Z
               flag_uskor = 0 flag_tormoz = 0 'останавливаемся
               pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
               plasma_on = 0             'выключаю плазму
               x0stop = x  y0stop = y   'запоминаю координату начальную
               x1stop = x1 y1stop = y1  'и конечную
             end if
             if flag_z_up = 1 then 'если движение в холостом режиме G0, поднимаем горелку вверх
                if z > z_up  then       'если достигнута верхняя точка
                  flag_z_up = 0        'сбрасываем флаг автоматич. движения
                  TIM4_CR1.CEN = 0       'выключаю счётчик
                  if flag_m30 = 1 then 
                    flag_m30 = 0
                    flag_cd_init = 0
                  else
                    time_start = TIM7_CNT  'запоминаю время начала движения по X Y
                    TIM6_CR1.CEN = 1       'запускаю движение по X Y
                  end if
                else
                  pin_step_z = 1          'подаю сигнал
                end if
             end if
             if flag_z_down = 1   then  'если переходим в рабочий режим G1 G2 G3 - опускаем горелку вниз
                if flag_z_to_z_start = 0 then      'если нет флага перехода в высоте поджига
                   if ((z < z_down) or (probe = 0)) then  '<---------------------сюда надо будет дописать сообщение об ошибке при z=z_down
                      z = z_probe             'обнуляю z
                      flag_z_to_z_start = 1   'выставляю флаг на поднятие к точке прокола
                      pin_dir_z = 0           'меняю направление движения (вверх)
                   else
                      pin_dir_z = 1
                      pin_step_z = 1             'подаю сигнал
                   end if
                 else   'если есть флаг перехода к высоте поджига
                   if z > z_start then 'если высота поджига достигнута
                     TIM4_CR1.CEN = 0 'останавливаю счётчик
                     flag_z_down = 0 'сбрасываю флаг автоматического движения Z
                     flag_z_to_z_start = 0 'сбрасываю флаг на поднятие высоте поджига
                     flag_pausa_start = 1 'выставляю флаг начала паузы перед стартом
                     plasma_on = 1
                   else
                     pin_step_z = 1             'подаю сигнал
                   end if
                 end if
             end if
         else
             if ((flag_thc_up = 1) or (knopka_vverh_z = 0)) then 'если есть флаг ТНС ВВЕРХ или нажата кнопка ВВЕРХ Z
               pin_step_z = 1
               pin_dir_z = 0
             else
               if ((flag_thc_down = 1) or (knopka_vniz_z = 0)) then 'если есть флаг ТНС ВНИЗ или нажата кнопка ВНИЗ Z
                 pin_step_z = 1
                 pin_dir_z = 1
               else
                 TIM4_CR1.CEN = 0 pin_dir_z = 0  'останавливаю счётчик, обнуляю сигнал Дир
               end if
             end if
         end if
    end if
end sub
sub procedure chastota_imp_THC() iv IVT_INT_TIM5 ics ICS_AUTO  ' 5 скорость импульсов ТНС
    TIM5_SR.UIF = 0  'сбрасываем флаг прерывания
    thc_imp = TIM3_CNT  'запоминаем значение счётчика 3
    TIM3_CNT = 0        'обнуляем счётчик 3
end sub
sub procedure Step_XY() iv IVT_INT_TIM6 ics ICS_AUTO  ' 6 счётчик хода
    TIM6_SR.UIF = 0  'сбрасываем флаг прерывания
 if ((flag_uskor = 1) or (flag_tormoz = 1)) then ' <----------------- если есть движение в атоматич. режиме
  if ((flag_adc = 1) and ((flag_g0g1 = 1) or (flag_g2g3 = 1))) then pausa_min = pausa_min_temp flag_adc = 0 end if  'устанавливаем скорость
 '-----------линейное перемещение------------------
  if flag_g0g1 = 0 then
     l = l + dlina_hoda  'добавляем приращение хода траектории
     if l >= dlina then  'если длина пройденного больше длины отрезка
       flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
       pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
       if ((flag_cd_init = 1) and (flag_dont_read = 0)) then flag_cd_read = 1 end if 'читаем с флэшки, что делать дальше
     end if
     if ((flag_uskor = 0) and (flag_tormoz = 1)) then   'если тормозим
          time_uskor = TIM7_CNT 'текущее время торможения
          if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
          time_uskor = time_uskor - time_start    'значение времени торможения
          if time_uskor < vremya_uskor   'если текущее время торможения меньше максимального
          then pausa = ((pausa_min * vremya_uskor)/(vremya_uskor - time_uskor)) 'вычисляем текущую паузу (скорость)
               if pausa > pausa_max then TIM6_ARR = pausa_max else TIM6_ARR = pausa end if  'устанавливаем значение паузы
          else TIM6_ARR = pausa_max 'значение паузы для медленного хода
               if flag_stop = 1 then
                 flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
                 pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
                 plasma_on = 0
                 x0stop = x  y0stop = y   'запоминаю координату начальную
                 x1stop = x1 y1stop = y1  'и конечную
               end if
          end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 1)) then 'если состояние рабочего движения - устанавливаем рабочую скорость
        TIM6_ARR = pausa_min 
        if ((l_uskor > (dlina - l)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 0)) then  'если ускоряемся
       l_uskor = l          'запоминаем длину ускорения
       time_uskor = TIM7_CNT   'читаем время ускорения
       if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
       time_uskor = time_uskor - time_start    'значение текущего времени ускорения
       if time_uskor < vremya_uskor   'если текущее время ускорения меньше максимального
       then pausa = ((pausa_min * vremya_uskor)/time_uskor) 'вычисляем текущую паузу (скорость)
            TIM6_ARR = pausa 'устанавливаем значение паузы
       else TIM6_ARR = pausa_min   'значение паузы для рабочего хода
            flag_tormoz = 1        'флаг окончания ускорения
       end if
       if ((l_uskor > (dlina - l)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT - vremya_uskor + time_uskor end if
     end if
       if pin_dir_x = 0 then 'направление движения по Х
            if (x0 - x + ((x1 - x0)*l/dlina)) >= dlina_impulsa_x 'если приращение по Х больше длины щага
            then
             if pin_dir_x = 0 then x = x + dlina_impulsa_x else x = x - dlina_impulsa_x end if 'к координате прибавляем длину щага
             BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
             pin_step_x = 1    'подаём сигнал шага
             TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
            end if
        else
            if (x - x0 + ((x0 - x1)*l/dlina)) >= dlina_impulsa_x 'если приращение по Х больше длины щага
            then
             if pin_dir_x = 0 then x = x + dlina_impulsa_x else x = x - dlina_impulsa_x end if 'к координате прибавляем длину щага
             BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
             pin_step_x = 1    'подаём сигнал шага
             TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
            end if
        end if
         if pin_dir_y = 0 then  'направление движения по Y
            if (y0 - y + ((y1 - y0)*l/dlina)) >= dlina_impulsa_y  'если приращение по Y больше длины щага
            then
             if pin_dir_y = 0 then y = y + dlina_impulsa_y else y = y - dlina_impulsa_y end if 'к координате прибавляем длину щага
             BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
             pin_step_y = 1     'подаём сигнал шага
             TIM2_CR1.CEN = 1   'включаем таймер  для отключения pin_step_y через 10мкс
            end if
         else
            if (y - y0 + ((y0 - y1)*l/dlina)) >= dlina_impulsa_y 'если приращение по Y больше длины щага
            then
             if pin_dir_y = 0 then y = y + dlina_impulsa_y else y = y - dlina_impulsa_y end if 'к координате прибавляем длину щага
             BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
             pin_step_y = 1      'подаём сигнал шага
             TIM2_CR1.CEN = 1    'включаем таймер для отключения pin_step_y через 10мкс
            end if
         end if
  end if
  '---------------------------------------- G2 круговая интерполяция против часовой стрелке
  if ((flag_g0g1=1) and (flag_g2g3=0))then
     a = a - a_shag  'добавляем приращение угла хода траектории
     if ((flag_uskor = 0) and (flag_tormoz = 1)) then   'если тормозим
          time_uskor = TIM7_CNT 'текущее время торможения
          if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
          time_uskor = time_uskor - time_start    'значение времени торможения
          if time_uskor < vremya_uskor   'если текущее время торможения меньше максимального
          then pausa = ((pausa_min * vremya_uskor)/(vremya_uskor - time_uskor)) 'вычисляем текущую паузу (скорость)
               TIM6_ARR = pausa   'устанавливаем значение паузы
          else TIM6_ARR = pausa_max 'значение паузы для медленного хода
               if flag_stop = 1 then
                 flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
                 pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
                 plasma_on = 0
                 x0stop = x  y0stop = y   'запоминаю координату начальную
                 x1stop = x1 y1stop = y1  'и конечную
               end if
          end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 1)) then 'если состояние рабочего движения - устанавливаем рабочую скорость
        TIM6_ARR = pausa_min
        if ((a <= (a_end + a_uskor)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 0)) then  'если ускоряемся
       a_uskor = a_start - a          'запоминаем длину ускорения
       time_uskor = TIM7_CNT   'читаем время ускорения
       if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
       time_uskor = time_uskor - time_start    'значение текущего времени ускорения
       if time_uskor < vremya_uskor   'если текущее время ускорения меньше максимального
       then pausa = ((pausa_min * vremya_uskor)/time_uskor) 'вычисляем текущую паузу (скорость)
            TIM6_ARR = pausa 'устанавливаем значение паузы
       else TIM6_ARR = pausa_min   'значение паузы для рабочего хода
            flag_tormoz = 1        'флаг окончания ускорения
       end if
       if ((a <= (a_end + a_uskor)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT - vremya_uskor + time_uskor end if
     end if
     if (x + dlina_impulsa_x) <= (i + (radius*cos(a))) then
       pin_dir_x = 0
       x = x + dlina_impulsa_x
       BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
       pin_step_x = 1    'подаём сигнал шага
       TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
     else
       if (x - dlina_impulsa_x) > (i + (radius*cos(a))) then
        pin_dir_x = 1
        x = x - dlina_impulsa_x
        BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
        pin_step_x = 1    'подаём сигнал шага
        TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
       end if
     end if
     if (y + dlina_impulsa_y) <= (j + (radius*sin(a))) then
       pin_dir_y = 0
       y = y + dlina_impulsa_y
       BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
       pin_step_y = 1    'подаём сигнал шага
       TIM2_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
     else
       if (y - dlina_impulsa_y) > (j + (radius*sin(a))) then
        pin_dir_y = 1
        y = y - dlina_impulsa_y
        BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
        pin_step_y = 1    'подаём сигнал шага
        TIM2_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
       end if
     end if
   if a <= a_end then  'если угол пройденного больше угла заданного
        flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
        pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
        flag_cd_read = 1  'читаем с флэшки, что делать дальше
   end if
  end if
  '---------------------------------------- G3 круговая интерполяция по часовой стрелке
  if ((flag_g0g1=1) and (flag_g2g3=1))then
     a = a + a_shag  'добавляем приращение угла хода траектории
     if ((flag_uskor = 0) and (flag_tormoz = 1)) then   'если тормозим
          time_uskor = TIM7_CNT 'текущее время торможения
          if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
          time_uskor = time_uskor - time_start    'значение времени торможения
          if time_uskor < vremya_uskor   'если текущее время торможения меньше максимального
          then pausa = ((pausa_min * vremya_uskor)/(vremya_uskor - time_uskor)) 'вычисляем текущую паузу (скорость)
               TIM6_ARR = pausa   'устанавливаем значение паузы
          else TIM6_ARR = pausa_max 'значение паузы для медленного хода
               if flag_stop = 1 then
                 flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
                 pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
                 plasma_on = 0
                 x0stop = x  y0stop = y   'запоминаю координату начальную
                 x1stop = x1 y1stop = y1  'и конечную
               end if
          end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 1)) then 'если состояние рабочего движения - устанавливаем рабочую скорость
        TIM6_ARR = pausa_min
        if  ((a >= (a_end - a_uskor)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT end if
     end if
     if ((flag_uskor = 1) and (flag_tormoz = 0)) then  'если ускоряемся
       a_uskor = a - a_start          'запоминаем длину ускорения
       time_uskor = TIM7_CNT   'читаем время ускорения
       if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
       time_uskor = time_uskor - time_start    'значение текущего времени ускорения
       if time_uskor < vremya_uskor   'если текущее время ускорения меньше максимального
       then pausa = ((pausa_min * vremya_uskor)/time_uskor) 'вычисляем текущую паузу (скорость)
            TIM6_ARR = pausa 'устанавливаем значение паузы
       else TIM6_ARR = pausa_min   'значение паузы для рабочего хода
            flag_tormoz = 1        'флаг окончания ускорения
       end if
       if ((a >= (a_end - a_uskor)) or (flag_stop = 1)) then flag_uskor = 0 flag_tormoz = 1 time_start = TIM7_CNT - vremya_uskor + time_uskor end if
     end if
     if (x + dlina_impulsa_x) <= (i + (radius*cos(a))) then
       pin_dir_x = 0
       x = x + dlina_impulsa_x
       BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
       pin_step_x = 1    'подаём сигнал шага
       TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
     else
       if (x - dlina_impulsa_x) > (i + (radius*cos(a))) then
        pin_dir_x = 1
        x = x - dlina_impulsa_x
        BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
        pin_step_x = 1    'подаём сигнал шага
        TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
       end if
     end if
     if (y + dlina_impulsa_y) <= (j + (radius*sin(a))) then
       pin_dir_y = 0
       y = y + dlina_impulsa_y
       BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
       pin_step_y = 1    'подаём сигнал шага
       TIM2_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
     else
       if (y - dlina_impulsa_y) > (j + (radius*sin(a))) then
        pin_dir_y = 1
        y = y - dlina_impulsa_y
        BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
        pin_step_y = 1    'подаём сигнал шага
        TIM2_CR1.CEN = 1  'включаем таймер для отключения pin_step_x через 10мкс
       end if
     end if
    if a >= a_end then  'если угол пройденного больше угла заданного
        flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
        pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
        flag_cd_read = 1  'читаем с флэшки, что делать дальше
    end if
  end if
 else 'нет движ в автоматич. режиме
   if ((flag_uskor_x = 0) and (flag_tormoz_x = 1)) then 'если тормозим в ручном режиме
        time_uskor = TIM7_CNT   'читаем время торможения
        if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
        time_uskor = time_uskor - time_start   'значение текущего времени торможения
        if time_uskor < vremya_uskor_g0   'если текущее время торможения меньше максимального
        then pausa =  ((pausa_min * vremya_uskor_g0)/(vremya_uskor_g0 - time_uskor))    'вычисляем текущую паузу (скорость)
             if pausa < pausa_max then TIM6_ARR = pausa end if        'устанавливаем значение паузы
        else TIM6_ARR = pausa_max   'значение паузы для рабочего хода
             flag_tormoz_x = 0        'флаг окончания остановки
             TIM6_CR1.CEN = 0         'выключаем счётчик
        end if
        if (((pin_dir_x = 0) and (knopka_vpravo = 0)) or ((pin_dir_x = 1) and (knopka_vlevo = 0))) then 'если нажата кнопка по направлению движения
           flag_uskor_x = 1                                   'переходим в режим ускорения
           flag_tormoz_x = 0
           time_start =  TIM7_CNT - vremya_uskor_g0 + time_uskor   'делаю смещение от начальной скорости (если не полная остановка, то ускоряемся от этой скорости)
           TIM6_CR1.CEN = 1
        end if
   end if
     if ((flag_uskor_x = 1) and (flag_tormoz_x = 1)) then 'если перемещаемся в ручном режиме
        if (((knopka_vpravo = 1) and (pin_dir_x = 0)) or ((knopka_vlevo = 1) and (pin_dir_x = 1))) then  'если отжаты кнопки
         flag_uskor_x = 0           'переходим в режим торможения
         time_start = TIM7_CNT      'фиксируем время начала торможения
        end if
    end if
    if ((flag_uskor_x = 1) and (flag_tormoz_x = 0)) then 'если ускоряемся в ручном режиме
        time_uskor = TIM7_CNT   'читаем время ускорения
        if time_uskor < time_start then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
        time_uskor = time_uskor - time_start   'значение текущего времени ускорения
        if time_uskor < vremya_uskor_g0   'если текущее время ускорения меньше максимального
        then pausa = ((pausa_min * vremya_uskor_g0)/time_uskor)  'вычисляем текущую паузу (скорость)
             if pausa > pausa_max then TIM6_ARR = pausa_max else TIM6_ARR = pausa end if        'устанавливаем значение паузы
        else TIM6_ARR = pausa_min   'значение паузы для рабочего хода
             flag_tormoz_x = 1        'флаг окончания ускорения
        end if
        if (((knopka_vpravo = 1) and (pin_dir_x = 0)) or ((knopka_vlevo = 1) and (pin_dir_x = 1))) then  'если отжаты кнопки
         flag_uskor_x = 0   'переходим в режим торможения
         flag_tormoz_x = 1
         time_start = TIM7_CNT - vremya_uskor_g0 + time_uskor 'делаю смещение от начальной скорости (если не полное ускорение, то тормозим от этой скорости)
        end if
    end if
   if TIM6_CR1.CEN = 0 then pin_dir_x = 0 end if
   if pin_dir_x = 0 then x = x + dlina_impulsa_x else x = x - dlina_impulsa_x end if 'к координате прибавляем длину щага
   BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x) 'BKP_DR7 = HigherWord(x) BKP_DR8 = HighestWord(x) 'запоминаем переменную
   pin_step_x = 1    'подаём сигнал шага
   TIM1_CR1.CEN = 1  'включаем таймер для отключения pin_step_y через 10мкс
 end if
end sub
sub procedure Step_Y_Ruchnoy() iv IVT_INT_TIM8_UP ics ICS_AUTO '8 Step_Y ручной шаг
    TIM8_SR.UIF = 0  'сбрасываем флаг прерывания
   if ((flag_uskor_y = 0) and (flag_tormoz_y = 1)) then 'если тормозим в ручном режиме
        time_uskor = TIM7_CNT   'читаем время торможения
        if time_uskor < time_start_y then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
        time_uskor = time_uskor - time_start_y   'значение текущего времени торможения
        if time_uskor < vremya_uskor_g0   'если текущее время торможения меньше максимального
        then pausa =  ((pausa_min_y * vremya_uskor_g0)/(vremya_uskor_g0 - time_uskor))    'вычисляем текущую паузу (скорость)
             if pausa < pausa_max_y then TIM8_ARR = pausa end if        'устанавливаем значение паузы
        else TIM8_ARR = pausa_max_y   'значение паузы для рабочего хода
             flag_tormoz_y = 0        'флаг окончания остановки
             TIM8_CR1.CEN = 0         'выключаем счётчик
        end if
        if (((pin_dir_y = 0) and (knopka_vverh = 0)) or ((pin_dir_y = 1) and (knopka_vniz = 0))) then 'если нажата кнопка по направлению движения
           flag_uskor_y = 1                                   'переходим в режим ускорения
           flag_tormoz_y = 0
           time_start_y =  TIM7_CNT - vremya_uskor_g0 + time_uskor   'делаю смещение от начальной скорости (если не полная остановка, то ускоряемся от этой скорости)
           TIM8_CR1.CEN = 1
        end if
   end if
     if ((flag_uskor_y = 1) and (flag_tormoz_y = 1)) then 'если перемещаемся в ручном режиме
        if (((knopka_vverh = 1) and (pin_dir_y = 0)) or ((knopka_vniz = 1) and (pin_dir_y = 1))) then  'если отжаты кнопки
         flag_uskor_y = 0           'переходим в режим торможения
         time_start_y = TIM7_CNT      'фиксируем время начала торможения
        end if
    end if
    if ((flag_uskor_y = 1) and (flag_tormoz_y = 0)) then 'если ускоряемся в ручном режиме
        time_uskor = TIM7_CNT   'читаем время ускорения
        if time_uskor < time_start_y then time_uskor = time_uskor + 0xFFFF end if    'поправка на переполнение счётчика
        time_uskor = time_uskor - time_start_y   'значение текущего времени ускорения
        if time_uskor < vremya_uskor_g0   'если текущее время ускорения меньше максимального
        then pausa = ((pausa_min_y * vremya_uskor_g0)/time_uskor)  'вычисляем текущую паузу (скорость)
             if pausa > pausa_max_y then TIM8_ARR = pausa_max_y else TIM8_ARR = pausa end if 'устанавливаем значение паузы
        else TIM8_ARR = pausa_min_y   'значение паузы для рабочего хода
             flag_tormoz_y = 1        'флаг окончания ускорения
        end if
        if (((knopka_vverh = 1) and (pin_dir_y = 0)) or ((knopka_vniz = 1) and (pin_dir_y = 1))) then  'если отжаты кнопки
         flag_uskor_y = 0   'переходим в режим торможения
         flag_tormoz_y = 1
         time_start_y = TIM7_CNT - vremya_uskor_g0 + time_uskor 'делаю смещение от начальной скорости (если не полное ускорение, то тормозим от этой скорости)
        end if
    end if
   if TIM8_CR1.CEN = 0 then pin_dir_y = 0 end if
   if pin_dir_y = 0 then y = y + dlina_impulsa_y else y = y - dlina_impulsa_y end if 'к координате прибавляем длину щага
   BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y) 'BKP_DR3 = HigherWord(y) BKP_DR4 = HighestWord(y) 'запоминаем переменную
   pin_step_y = 1    'подаём сигнал шага
   TIM2_CR1.CEN = 1  'включаем таймер для отключения pin_step_y через 10мкс
end sub

main:
GPIO_Clk_Enable(@GPIOA_BASE)
GPIO_Clk_Enable(@GPIOB_BASE)
GPIO_Clk_Enable(@GPIOC_BASE)
GPIO_Config(@GPIOA_BASE, _GPIO_PINMASK_1 or _GPIO_PINMASK_2 or _GPIO_PINMASK_3 or _GPIO_PINMASK_4 or _GPIO_PINMASK_5 or _GPIO_PINMASK_6 or _GPIO_PINMASK_7 or
                         _GPIO_PINMASK_HIGH, _GPIO_CFG_MODE_OUTPUT or _GPIO_CFG_SPEED_MAX or _GPIO_CFG_OTYPE_PP)
GPIO_Config(@GPIOB_BASE, _GPIO_PINMASK_1 or _GPIO_PINMASK_2 or _GPIO_PINMASK_3 or _GPIO_PINMASK_4 or _GPIO_PINMASK_5 or _GPIO_PINMASK_6 or _GPIO_PINMASK_7 or
                         _GPIO_PINMASK_HIGH, _GPIO_CFG_MODE_OUTPUT or _GPIO_CFG_SPEED_MAX or _GPIO_CFG_OTYPE_PP)
GPIO_Config(@GPIOB_BASE, _GPIO_PINMASK_0, _GPIO_CFG_MODE_INPUT or _GPIO_CFG_PULL_UP)
GPIO_Config(@GPIOC_BASE, _GPIO_PINMASK_ALL, _GPIO_CFG_MODE_INPUT or _GPIO_CFG_PULL_UP)
GPIO_Alternate_Function_Enable(@_GPIO_MODULE_SPI1_PA567)
GPIO_Alternate_Function_Enable(@_GPIO_MODULE_SWJ_JTAGDISABLE)
GPIOA_ODR = 0
GPIOB_ODR = 0
GPIOC_ODR = 0
RCC_APB1ENR.PWREN = 1
RCC_APB1ENR.BKPEN = 1
PWR_CR.DBP = 1
'------------------------------------------------------------------------------- Таймер Step X ON
  RCC_APB2ENR.TIM1EN = 1 'подаём тактирование с шины АРВ2 на таймер 1
  TIM1_CR1.CEN = 0 ' отключаем таймер 1
  TIM1_PSC = 71 ' предделитель 71+1
  TIM1_ARR = 10 ' переполнение 10мкс
  NVIC_SetIntPriority(IVT_INT_TIM1_UP,_NVIC_INT_PRIORITY_LVL0) 'наивысший приоритет
  NVIC_IntEnable(IVT_INT_TIM1_UP) ' разрешаем прерывание по таймеру
  TIM1_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
'------------------------------------------------------------------------------- Таймер Step Y ON
  RCC_APB1ENR.TIM2EN = 1 'подаём тактирование с шины АРВ1 на таймер 2
  TIM2_CR1.CEN = 0 ' отключаем таймер 2
  TIM2_PSC = 71 ' предделитель 71+1
  TIM2_ARR = 10 ' переполнение
  NVIC_SetIntPriority(IVT_INT_TIM2,_NVIC_INT_PRIORITY_LVL0)  'наивысший приоритет
  NVIC_IntEnable(IVT_INT_TIM2) ' разрешаем прерывание по таймеру
  TIM2_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
'------------------------------------------------------------------------------- Счётчик импульсов ТНС
  RCC_APB1ENR.TIM3EN = 1 'подаём тактирование с шины АРВ1 на таймер 3
  TIM3_CR1.CEN = 0 ' отключаем таймер 3
  TIM3_PSC = 0 ' предделитель 0+1
  TIM3_ARR = 0xFFFF ' переполнение 65535
  TIM3_SMCR.ETF0 = 1  'фильтр внешнего запуска (для входа внешнего запуска ETR)
  TIM3_SMCR.ETF1 = 1  'спасибо http://lobotryasy.net/stm32_clock_sources.php
  TIM3_SMCR.ETF2 = 1  'фильтр внешнего запуска (для входа внешнего запуска ETR)
  TIM3_SMCR.ETF3 = 1  'фильтр внешнего запуска (для входа внешнего запуска ETR)
  TIM3_SMCR.ETP = 0   'Выбираем определение сигнала на ETR по нарастающему фронту
  TIM3_SMCR.ECE = 1   'Разрешаем режим 2 внешнего тактирования
  TIM3_CR1.CEN = 1    'Включаем тактирование счётчика
 '------------------------------------------------------------------------------ Таймер Step Z ON
  RCC_APB1ENR.TIM4EN = 1 'подаём тактирование с шины АРВ1 на таймер 4
  TIM4_CR1.CEN = 0 ' отключаем таймер 3
  TIM4_PSC = 719 ' предделитель 719+1
  TIM4_ARR = 1000 ' переполнение 1000мкс
  NVIC_SetIntPriority(IVT_INT_TIM4,_NVIC_INT_PRIORITY_LVL2) 'приоритет 2
  NVIC_IntEnable(IVT_INT_TIM4) ' разрешаем прерывание по таймеру
  TIM4_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
 '------------------------------------------------------------------------------ Таймер измерения ТНС
  RCC_APB1ENR.TIM5EN = 1 'подаём тактирование с шины АРВ1 на таймер 5
  TIM5_CR1.CEN = 0 ' отключаем таймер 5
  TIM5_PSC = 7199 ' предделитель 7199+1
  TIM5_ARR = 3000 ' переполнение 0.3с
  NVIC_SetIntPriority(IVT_INT_TIM5,_NVIC_INT_PRIORITY_LVL2) 'приоритет 2
  NVIC_IntEnable(IVT_INT_TIM5) ' разрешаем прерывание по таймеру
  TIM5_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
  TIM5_CR1.CEN = 1
 '------------------------------------------------------------------------------ Таймер хода (скорости) и ручного хода X
  RCC_APB1ENR.TIM6EN = 1 'подаём тактирование с шины АРВ1 на таймер 6
  TIM6_CR1.CEN = 0 ' отключаем таймер 6
  TIM6_PSC = 719 ' предделитель 719+1
  TIM6_ARR = 20 '
  NVIC_SetIntPriority(IVT_INT_TIM6,_NVIC_INT_PRIORITY_LVL1) 'приоритет 1
  NVIC_IntEnable(IVT_INT_TIM6) ' разрешаем прерывание по таймеру
  TIM6_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
 '------------------------------------------------------------------------------ Таймер времени для ускорения
  RCC_APB1ENR.TIM7EN = 1 'подаём тактирование с шины АРВ1 на таймер 7
  TIM7_CR1.CEN = 0 ' отключаем таймер 7
  TIM7_PSC = 35999 ' предделитель 35999+1
  TIM7_ARR = 0xFFFF '
  TIM7_CR1.CEN = 1
 '------------------------------------------------------------------------------ Таймер ручного шага Y
  RCC_APB2ENR.TIM8EN = 1 'подаём тактирование с шины АРВ2 на таймер 8
  TIM8_CR1.CEN = 0 ' отключаем таймер 1
  TIM8_PSC = 719 ' предделитель 719+1
  TIM8_ARR = 20 ' переполнение 10мкс
  NVIC_SetIntPriority(IVT_INT_TIM8_UP,_NVIC_INT_PRIORITY_LVL1) 'приоритет 1
  NVIC_IntEnable(IVT_INT_TIM8_UP) ' разрешаем прерывание по таймеру
  TIM8_DIER.UIE = 1 ' разрешаем таймеру создавать прерывание
 '------------------------------------------------------------------------------

  Lcd_Init()
  Lcd_Cmd(_LCD_CLEAR)
  Lcd_Cmd(_LCD_CURSOR_OFF)
  SPI1_Init_Advanced(_SPI_FPCLK_DIV2, _SPI_MASTER or _SPI_8_BIT or
                   _SPI_CLK_IDLE_LOW or _SPI_FIRST_CLK_EDGE_TRANSITION or
                   _SPI_MSB_FIRST or _SPI_SS_DISABLE or _SPI_SSM_ENABLE or _SPI_SSI_1,
                   @_GPIO_MODULE_SPI1_PA567)
  ADC_Set_Input_Channel(_ADC_CHANNEL_0)
  ADC1_Init()
  flag = 0                 'обнуляем флаги состояния
  flag2 = 0
  pausa_start = 0
  LoWord(y) = BKP_DR1 HiWord(y) = BKP_DR2 'HigherWord(y) = BKP_DR3 HighestWord(y) = BKP_DR4 'достаём переменную y из памяти
  LoWord(x) = BKP_DR5 HiWord(x) = BKP_DR6 'HigherWord(x) = BKP_DR7 HighestWord(x) = BKP_DR8 'достаём переменную x из памяти
  thc_norma = BKP_DR9
  LoWord(z) = BKP_DR10 HiWord(z) = BKP_DR11
  pausa_m3 = BKP_DR12
  pausa_m5 = BKP_DR13
  num5 = "     "

  pausa = dlina_impulsa_z * 3000000 / skorost_z     'расчет скорости движения Z
  pausa_z = pausa
  pausa = dlina_impulsa_z * 3000000 / skorost_thc   'расчет скорости движени я Z в режиме контроля высоты
  pausa_thc = pausa
  TIM4_ARR = skorost_z                              'устанавливаю скорость движения по умолчанию
  vremya_uskor = vremya_uskor_g0                    'устанавливаю время ускорения по умолчанию
    
  While true
  koordinata1 = x    'выделяем целую часть координаты
  IntToStr(koordinata1, txt6)    'преобразуем в символы
  koordinata = (x - koordinata1) * 100  'выделяем сотые
  IntToStrWithZeros(koordinata, txt5) 'преобразуем в символы
  txt8[0] = txt6[1] txt8[1] = txt6[2] txt8[2] = txt6[3] txt8[3] = txt6[4] txt8[4] = txt6[5] txt8[5] = "," txt8[6] = txt5[4] txt8[7] = txt5[5]
  LCD_Out(2,1,"X:")
  LCD_Out(2,3,txt8)
  koordinata1 = y      'выделяем целую часть координаты
  IntToStr(koordinata1, txt6)     'преобразуем в символы
  koordinata = (y - koordinata1) * 100  'выделяем сотые
  IntToStrWithZeros(koordinata, txt5)   'преобразуем в символы
  txt8[0] = txt6[1] txt8[1] = txt6[2] txt8[2] = txt6[3] txt8[3] = txt6[4] txt8[4] = txt6[5] txt8[5] = "," txt8[6] = txt5[4] txt8[7] = txt5[5]
  LCD_Out(3,1,"Y:")
  LCD_Out(3,3,txt8)
  koordinata1 = z    'выделяем целую часть координаты
  IntToStr(koordinata1, txt6)    'преобразуем в символы
  koordinata = (z - koordinata1) * 100  'выделяем сотые
  IntToStrWithZeros(koordinata, txt5) 'преобразуем в символы
  txt8[0] = txt6[1] txt8[1] = txt6[2] txt8[2] = txt6[3] txt8[3] = txt6[4] txt8[4] = txt6[5] txt8[5] = "," txt8[6] = txt5[4] txt8[7] = txt5[5]
  LCD_Out(4,1,"Z:")
  LCD_Out(4,3,txt8)  'вывожу на дисплей
  WordToStr(thc_imp, txt5)    'переводим количество импульсов за 0,5с в символы
  LCD_Out(2,12,"THC:")
  LCD_Out(2,16,txt5)          'выводим символы на дисплей
  if flag_thc_on = 1 then
     WordToStr(thc_norma, txt5) 'преобразую в символы
     LCD_Out(3,12,"YCT:")
     LCD_Out(3,16,txt5)          'вывожу на дисплей
  else LCD_Out(3,12,"-THC OFF-")
  end if
  adc1 = ADC1_Get_Sample(0)     'опрашиваем АЦП
  if ((adc1 > (adc + 5)) or (adc1 < (adc - 5))) then    'защита от помех и небольших изменений
     adc = adc1
     skorost = ((adc * (skorost_max - skorost_min) / 4093) + skorost_min)  'преобразуем в скорость
     flag_adc = 0  'запрет изменения скорости
     pausa_min_temp = (dlina_hoda * 6000000)/skorost     'рассчёт скорости
     flag_adc = 1  'разрешение на изменение скорости
  end if
  WordToStr(skorost, txt5) 'переводим в символы
  LCD_Out(4, 12, "CKOP")
  Lcd_Out(4, 16, txt5)     'выводим на дисплей
  LCD_Out(1,1,num5)
  
  if ((flag_thc_on = 1) and (plasma_on = 1) and (flag_z_up = 0) and (flag_z_down = 0)) then  'если включена ТНС, включена плазма и нет движения в ручном режиме
   if ((thc_imp > (thc_norma + thc_dopusk)) and  (z > thc_min)) then    ' если кол-во импульсов больше заданного с учётом допуска, то горелку нужно опустить
     flag_thc_down = 1 'флаг ТНС опускания горелки
     flag_thc_up = 0   'флаг ТНС поднятия горелки
     TIM4_ARR = pausa_thc 'скорость ТНС
     TIM4_CR1.CEN = 1     'запуск движения Z
   else
     if ((thc_imp < (thc_norma - thc_dopusk)) and (thc_norma > thc_dopusk) and  (z < thc_max)) then ' если кол-во импульсов меньше заданного с учётом допуска, то горелку нужно поднять
       flag_thc_down = 0 'флаг ТНС опускания горелки
       flag_thc_up = 1   'флаг ТНС поднятия горелки
       TIM4_ARR = pausa_thc 'скорость ТНС
       TIM4_CR1.CEN = 1     'запуск движения Z
     else
       flag_thc_up = 0       'если кол-во импульсов в пределах допуска, то обнуляю флаги ТНС
       flag_thc_down = 0
     end if
   end if
  else
    flag_thc_up = 0      'иначе обнуляю флаги ТНС
    flag_thc_down = 0
  end if
  '---------------------------------------------------кнопки
  if ((knopka_vverh_z = 0) and (knopka_vniz_z = 1)) then pin_dir_z = 0 TIM4_ARR = pausa_z TIM4_CR1.CEN = 1 end if 'если нажата Z++ то задаю направление и включаю счётчик Z
  if ((knopka_vniz_z = 0) and (knopka_vverh_z = 1)) then pin_dir_z = 1 TIM4_ARR = pausa_z TIM4_CR1.CEN = 1 end if 'если нажата Z-- то задаю направление и включаю счётчик Z
  if knopka_thc_on = 0 then flag_thc_on = 1 end if  'если нажата кнопка knopka_thc_on ставим флаг включения ТНС
  if knopka_thc_off = 0 then flag_thc_on = 0   'если нажата кнопка knopka_thc_off ставим флаг выключения ТНС
     Lcd_Cmd(_LCD_CLEAR)                  'очищаю дисплэй
     LCD_Out(2, 1, "pausa m3")            'вывожу на экран
     LCD_Out(3, 1, "pausa m5")
     LCD_Out(2, 17, "cek")
     LCD_Out(3, 17, "cek")
     while (knopka_thc_off = 0)         ' пока нажата кнопка knopka_thc_off
       if knopka_vverh = 0 then pausa_m3 = pausa_m3 + 1 while knopka_vverh = 0 delay_ms(10) wend end if  'если нажата кнопка knopka_vverh прибавляем паузу М3
       if knopka_vniz = 0 then pausa_m3 = pausa_m3 - 1 while knopka_vniz = 0 delay_ms(10) wend end if    'если нажата кнопка knopka_vniz убавляем паузу М3
       if knopka_vpravo = 0 then pausa_m5 = pausa_m5 + 1 while knopka_vpravo = 0 delay_ms(10) wend end if 'если нажата кнопка knopka_vpravo прибавляю паузу М5
       if knopka_vlevo = 0 then pausa_m5 = pausa_m5 - 1 while knopka_vlevo = 0 delay_ms(10) wend end if   'если нажата кнопка knopka_vlevo убавляю паузу М5
       WordToStr(pausa_m3, txt5) 'преобразую в символы
       txt6[0]=txt5[0] txt6[1]=txt5[1] txt6[2]=txt5[2] if pausa_m3 < 10 then txt6[3]= "0" else txt6[3]=txt5[3] end if txt6[4]= "," txt6[5]=txt5[4]
       LCD_Out(2, 10, txt6)      'вывожу на экран
       WordToStr(pausa_m5, txt5) 'преобразую в символы
       txt6[0]=txt5[0] txt6[1]=txt5[1] txt6[2]=txt5[2] if pausa_m5 < 10 then txt6[3]= "0" else txt6[3]=txt5[3] end if txt6[4]= "," txt6[5]=txt5[4]
       LCD_Out(3, 10, txt6) 'вывожу на экран
       delay_ms(10)  'пауза 0,01 сек
     wend
     BKP_DR12 = pausa_m3        'запоминаю значения
     BKP_DR13 = pausa_m5
     Lcd_Cmd(_LCD_CLEAR)        'очищаю экран
  end if
  if ((knopka_thc_plus = 1) and (knopka_thc_minus = 1 )) then flag_thc_knopka = 0 end if 'если обе кнопки отжаты - обнуляю флаг нажития кнопки ТНС
  if ((knopka_thc_plus = 0)  and (flag_thc_knopka = 0)) then thc_norma = thc_norma + 1 flag_thc_knopka = 1 BKP_DR9 = thc_norma end if 'если нажата кнопка изменяю и запоминаю значение уставки ТНС
  if ((knopka_thc_minus = 0) and (flag_thc_knopka = 0)) then thc_norma = thc_norma - 1 flag_thc_knopka = 1 BKP_DR9 = thc_norma end if 'если нажата кнопка изменяю и запоминаю значение уставки ТНС
  if ((flag_uskor = 0) and (flag_tormoz = 0) and (flag_z_down = 0) and (flag_z_up = 0) and (flag_z_to_z_start = 0) and (flag_pausa_start = 0) and (flag_pausa_stop = 0)) then 'если нет движения в атоматич режиме
    if knopka_x0y0 = 0 then 'если нажата кнопка обнуления
       x=0 y=0                                  'обнуляю координаты
       BKP_DR5 = LoWord(x) BKP_DR6 = HiWord(x)  'запоминаю X
       BKP_DR1 = LoWord(y) BKP_DR2 = HiWord(y)  'запоминаю Y
    end if
    if ((knopka_vpravo = 0) and (flag_uskor_x = 0) and (flag_tormoz_x = 0))  then  'если нажата кнопка вправо и нет движения в ручном режиме
        flag_uskor_x = 1     'флаг ускорения в ручном режиме
        pin_dir_x = 0        'направление - прямое
        pausa = (dlina_impulsa_x * 6000000)/skorost_holost_hoda  'расчет скорости рабочей
        pausa_min = pausa
        pausa = (dlina_impulsa_x * 6000000)/start_skor           'расчет скорости минимальной
        if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if         'подстраховка от переполнения
        TIM6_ARR = pausa_max                                         'устанавливая стартовую скорость
        time_start = TIM7_CNT                                          'фиксирую время начала
        TIM6_CR1.CEN = 1                                               'запускаю таймер
    end if
    if ((knopka_vlevo = 0) and (flag_uskor_x = 0) and (flag_tormoz_x = 0)) then   'если нажата кнопка влево  и нет движения в ручном режиме
        flag_uskor_x = 1    'флаг ускорения в ручном режиме
        pin_dir_x = 1       'направление - обратное
        pausa = (dlina_impulsa_x * 6000000)/skorost_holost_hoda  'расчет скорости рабочей
        pausa_min = pausa
        pausa = (dlina_impulsa_x * 6000000)/start_skor           'расчет скорости минимальной
        if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if         'подстраховка от переполнения
        TIM6_ARR = pausa_max                                        'устанавливая стартовую скорость
        time_start = TIM7_CNT                                         'фиксирую время начала
        TIM6_CR1.CEN = 1                                              'запускаю таймер
    end if
    if ((knopka_vverh = 0) and (flag_uskor_y = 0) and (flag_tormoz_y = 0)) then  'если нажата кнопка вверх и нет движения в ручном режиме
        flag_uskor_y = 1     'флаг ускорения в ручном режиме
        pin_dir_y = 0        'направление - прямое
        pausa = (dlina_impulsa_y * 6000000)/skorost_holost_hoda  'расчет скорости рабочей
        pausa_min_y = pausa
        pausa = (dlina_impulsa_y * 6000000)/start_skor           'расчет скорости минимальной
        if pausa > 65534 then pausa_max_y = 65534 else pausa_max_y = pausa end if         'подстраховка от переполнения
        TIM8_ARR = pausa_max_y                                        'устанавливая стартовую скорость
        time_start_y = TIM7_CNT                                       'фиксирую время начала
        TIM8_CR1.CEN = 1                                              'запускаю таймер
    end if
    if ((knopka_vniz = 0) and (flag_uskor_y = 0) and (flag_tormoz_y = 0)) then  'если нажата кнопка вниз и нет движения в ручном режиме
        flag_uskor_y = 1   'флаг ускорения в ручном режиме
        pin_dir_y = 1      'направление - обратное
        pausa = (dlina_impulsa_y * 6000000)/skorost_holost_hoda  'расчет скорости рабочей
        pausa_min_y = pausa
        pausa = (dlina_impulsa_y * 6000000)/start_skor           'расчет скорости минимальной
        if pausa > 65534 then pausa_max_y = 65534 else pausa_max_y = pausa end if         'подстраховка от переполнения
        TIM8_ARR = pausa_max_y                                        'устанавливая стартовую скорость
        time_start_y = TIM7_CNT                                       'фиксирую время начала
        TIM8_CR1.CEN = 1                                              'запускаю таймер
    end if
    if ((knopka_home = 0) and (TIM8_CR1.CEN = 0) and (TIM6_CR1.CEN = 0)) then  'если нажата кнопка домой и нет движения в ручном режиме
      if ((abs(x) > dlina_impulsa_x) or (abs(y) > dlina_impulsa_y)) then   'если текущие координаты больше длины шага импульса
        x0 = x  'приравниваем текущею координату к начальной траектории
        y0 = y
        x1 = 0   'конечная координата
        y1 = 0
        l = 0    'пройденная длина траектории
        adc = ADC1_Get_Sample(0)     'опрашиваем АЦП
        skorost = ((adc * (skorost_max - skorost_min) / 4096) + skorost_min)  'преобразуем в скорость
        dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
        pausa = (dlina_hoda * 6000000)/skorost_holost_hoda
        pausa_min = pausa
        pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
        if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
        if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
        if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
        TIM6_ARR = pausa_max    'стартовая скорость
        flag_z_up = 1      'флаг авто режима поднятия Z
        flag_uskor = 1        'ускорение
        flag_tormoz = 0
        flag_g0g1 = 0         'режим G0 (холостого хода)
        flag_g2g3 = 0
        vremya_uskor = vremya_uskor_g0
        TIM4_CR1.CEN = 1        'запуск Z
      end if
    end if
  end if 'закрытие ифа: если нет движения в атоматич режиме
  if flag_pausa_start = 1 then 'если есть пауза при включении плазмы
    flag_pausa_stop = 0   'флаг паузы стопа
    flag_cd_read = 0      'флаг чтения флэшки
    LCD_Out(1, 7, "pausa m3") 'вывожу на экран
    WordToStr(pausa_start, txt5) 'преобразую в символы
    txt6[0]=txt5[0] txt6[1]=txt5[1] txt6[2]=txt5[2] if pausa_start < 10 then txt6[3]= "0" else txt6[3]=txt5[3] end if txt6[4]= "," txt6[5]=txt5[4] 'вставляю запятую
    LCD_Out(1, 15, txt6) 'вывожу на экран
    pausa_start = pausa_start + 1 'считаю паузу
    delay_ms(100) 'делаю паузу 0,1сек
    if (pausa_start >=  pausa_m3) then 'если пауза больше заданной
       flag_pausa_start = 0 'убираю флаг паузы
       pausa_start = 0      'обнуляю счётчик
       Lcd_Cmd(_LCD_CLEAR)  'очищаю дисплей
       if flag_z_down_and_start = 1 then 'если стоит флаг старта после касания
          flag_z_down_and_start = 0      'обнуляю флаг
          time_start = TIM7_CNT          'запоминаю время старта
          TIM6_CR1.CEN = 1               'запускаю движение
       else flag_cd_read = 1   'флаг продолжения чтения флэшки
       end if
    end if
  end if
  if flag_pausa_stop = 1 then 'если есть флаг паузы после остановки
    flag_pausa_start = 0      'флаг паузы старта
    flag_cd_read = 0          'флаг продолжения чтения флэшки
    LCD_Out(1, 7, "pausa m5") 'вывожу на экран
    WordToStr(pausa_start, txt5)  'преобразую в символы
    txt6[0]=txt5[0] txt6[1]=txt5[1] txt6[2]=txt5[2] if pausa_start < 10 then txt6[3]= "0" else txt6[3]=txt5[3] end if txt6[4]= "," txt6[5]=txt5[4] 'вставляю запятую
    LCD_Out(1, 15, txt6) 'вывожу символы
    pausa_start = pausa_start + 1 'считаю паузу
    delay_ms(100) 'делаю паузу 0,1сек
    if (pausa_start >=  pausa_m5) then  'если пауза равно заданной
       flag_pausa_stop = 0  'убираю флаг
       pausa_start = 0      'обнуляю счётчик
       Lcd_Cmd(_LCD_CLEAR)  'очищаю дисплей
       plasma_on = 0        'выключаю плазму
       flag_cd_read = 1     'флаг продолжения чтения флэшки
    end if
  end if
  if ((knopka_start = 0) and (flag_cd_init = 0) and (TIM8_CR1.CEN = 0) and (TIM6_CR1.CEN = 0)) then  'если нажата кнопка старт кнопка старт
     if Mmc_Init() <> 0 then   'подключение флэшки                                              нет подключенной ранее флэшки и движения по X Y
        if Mmc_Init() <> 0 then  'повторяем несколько раз
           if Mmc_Init() <> 0 then
              if Mmc_Init() <> 0 then
               LCD_Out(1, 1, "No CD card") 'если не подключилась флэшка с четвёртой попытки - выводим сообщение
               delay_ms(1000)
               Lcd_Cmd(_LCD_CLEAR)
               goto out_if
              end if
           end if
        end if
     end if
     if FAT32_Init() <> 0 then  'читаем таблицу Fat32
        if FAT32_Init() <> 0 then 'не знаю зачем, я написал это в нескольких попытках
           if FAT32_Init() <> 0 then  'наверно это лишнее
              if FAT32_Init() <> 0 then
               LCD_Out(1, 1, "No FAT32")  'если не получилось с четвёртой попытки - выводим сообщение
               delay_ms(1000)
               Lcd_Cmd(_LCD_CLEAR)
               goto out_if
              end if
           end if
        end if
     end if
     program_bin="program.cnc"  'название файла который будем читать
     if FAT32_Exists(@program_bin) = 0  then  'проверяем существование файла
        LCD_Out(1, 1, "no file program.cnc")  'если его нет - выводим сообщение
        delay_ms(1000)  'пауза 1с
        Lcd_Cmd(_LCD_CLEAR) 'очищаю дисплей
        goto out_if         'выхожу из цикла
     end if
     FAT32_Size(@program_bin, @size) 'читаю размер файла
     nomer_file = FAT32_Open(@program_bin, FILE_READ)  'открываю файл для чтения и запоминаю его номер
     if nomer_file = -1 then
        LCD_Out(1, 1, "not open file") 'если файл не открылся - вывожу сообщение
        delay_ms(1000)  'пауза 1 сек
        Lcd_Cmd(_LCD_CLEAR)  'очистка дисплея
        goto out_if          'выход из цикла
     end if
     size1=0          'обнуляю счётчик размера прочтённой информации
     flag_cd_init = 1   'отмечаю флагом подключение флэшки
     flag_cd_read = 1   'разрешаю чтение файла
  end if 'кнопка старт

  While ((flag_cd_read = 1) and (TIM6_CR1.CEN = 0) and (flag_pausa_start = 0) and (flag_pausa_stop = 0)) 'если разрешенно чтение файла, нет движения по XY и нет паузы М3 М5
    FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   'читаю один байт, прибавляя счётчик
    if cd_byte = "N" then num5[0]= "N"                      'если почитан символ N
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   'читаю один байт, прибавляя счётчик
      if cd_byte <> 0x20 then                                 'если прочитанный символ не "пробел"
        num5[1]=cd_byte num5[2]=" " num5[3]=" " num5[4]=" "   'запоминаю его
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   'читаю один байт, прибавляя счётчик
        if cd_byte <> 0x20 then                                 'если прочитанный символ не "пробел"
          num5[2]=cd_byte num5[3]=" " num5[4]=" "               'запоминаю его
          FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   'читаю один байт, прибавляя счётчик
          if cd_byte <> 0x20 then                                 'если прочитанный символ не "пробел"
            num5[3]=cd_byte num5[4]=" "                           'запоминаю его
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if cd_byte <> 0x20 then                                 'если прочитанный символ не "пробел"
              num5[4]=cd_byte                                         'запоминаю его
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if cd_byte <> 0x20 then                                 'если прочитанный символ не "пробел"
                Lcd_Cmd(_LCD_CLEAR)                                   'очищаю дислей
                Lcd_Out(1, 1, "net probela posle N")                  'вывожу сообщение
                while true wend                                       'вечный стоп
              end if
            end if
          end if
        end if
      end if
    end if
    if cd_byte = "G" then                                     'если прочитанный символ "G"
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if cd_byte = "0" then                                   'если прочитанный символ "0"
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if cd_byte = "0" then flag_g0g1=0 flag_g2g3=0 flag_uskor=1 x0=x y0=y x1=0 y1=0 'если прочитанный символ "0", запонинаю режим G0
        else if cd_byte = "1" then flag_g0g1=0 flag_g2g3=1 flag_uskor=1 x0=x y0=y x1=0 y1=0 'если прочитанный символ "1", запонинаю режим G1
             else if cd_byte = "2" then flag_g0g1=1 flag_g2g3=0 flag_uskor=1 x0=x y0=y x1=0 y1=0 i=0 j=0  'если прочитанный символ "2", запонинаю режим G2
                  else if cd_byte = "3" then flag_g0g1=1 flag_g2g3=1 flag_uskor=1 x0=x y0=y x1=0 y1=0 i=0 j=0 'если прочитанный символ "3", запонинаю режим G3
                       else if cd_byte <> "4" then 'если прочинанный символ не 1,2,3,4
                              Lcd_Cmd(_LCD_CLEAR)  'очищаю дисплей
                              Lcd_Out(1, 5, "net 0123 posle G0") 'вывожу сообщение
                              while true wend  'вечный стоп
                            end if
                       end if
                  end if
             end if
        end if
      end if
    end if

    if cd_byte = "X" then 'если прочитанный символ "X"
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
        x1 = cd_byte - 48                                     'перевожу символ в число и приравниваю X
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
          x1 = x1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
          FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
            x1 = x1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              x1 = x1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                x1 = x1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  x1 = x1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
       if cd_byte = 0x2E then  'если прочитанный символ "."
         FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then          'если прочитана цифра 0-9
            pausa = cd_byte - 48 x1 = x1 + (pausa * 0.1)         'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              pausa = cd_byte - 48 x1 = x1 + (pausa * 0.01)         'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                pausa = cd_byte - 48 x1 = x1 + (pausa * 0.001)        'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  pausa = cd_byte - 48 x1 = x1 + (pausa * 0.0001)       'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
      end if
    end if

    if cd_byte = "Y" then
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
        y1 = cd_byte - 48                                     'перевожу символ в число  и считаю значение переменной
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
          y1 = y1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
          FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
            y1 = y1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              y1 = y1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                y1 = y1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  y1 = y1*10 + (cd_byte - 48)                           'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
       if cd_byte = 0x2E then  'если прочитанный символ "."
         FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then          'если прочитана цифра 0-9
            pausa = cd_byte - 48 y1 = y1 + (pausa * 0.1)         'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              pausa = cd_byte - 48 y1 = y1 + (pausa * 0.01)         'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                pausa = cd_byte - 48 y1 = y1 + (pausa * 0.001)        'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  pausa = cd_byte - 48 y1 = y1 + (pausa * 0.0001)       'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
      end if
    end if

    if cd_byte = "I" then 'I
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
        i = cd_byte - 48                                      'перевожу символ в число  и считаю значение переменной
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
          i = i*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
          FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
            i = i*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              i = i*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                i = i*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  i = i*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
       if cd_byte = 0x2E then 'если прочитанный символ "."
         FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then          'если прочитана цифра 0-9
            pausa = cd_byte - 48 i = i + (pausa * 0.1)           'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              pausa = cd_byte - 48 i = i + (pausa * 0.01)           'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                pausa = cd_byte - 48 i = i + (pausa * 0.001)          'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  pausa = cd_byte - 48 i = i + (pausa * 0.0001)         'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
      end if
    end if

    if cd_byte = "J" then      'J
      FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
        j = cd_byte - 48                                      'перевожу символ в число  и считаю значение переменной
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
          j = j*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
          FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
            j = j*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              j = j*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                j = j*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  j = j*10 + (cd_byte - 48)                             'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
        if cd_byte = 0x2E then 'если прочитанный символ "."
         FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
          if ((cd_byte >= 48) and (cd_byte <= 57)) then          'если прочитана цифра 0-9
            pausa = cd_byte - 48 j = j + (pausa * 0.1)           'перевожу символ в число  и считаю значение переменной
            FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
            if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
              pausa = cd_byte - 48 j = j + (pausa * 0.01)           'перевожу символ в число  и считаю значение переменной
              FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
              if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                pausa = cd_byte - 48 j = j + (pausa * 0.001)          'перевожу символ в число  и считаю значение переменной
                FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                if ((cd_byte >= 48) and (cd_byte <= 57)) then           'если прочитана цифра 0-9
                  pausa = cd_byte - 48 j = j + (pausa * 0.0001)         'перевожу символ в число  и считаю значение переменной
                  FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
                end if
              end if
            end if
          end if
        end if
      end if
    end if
    if cd_byte = "M" then 'если прочитанный символ "M"
    FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
      if cd_byte = "3" then 'если прочитанный символ "3"
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if cd_byte = "0" then 'если прочитанный символ "0" т.е. команда М30
          flag_cd_read = 0    'флаг чтения флешки (запрет)
          flag_z_up = 1       'флаг поднятия Z
          flag_z_down = 0     'флаг опускания Z
          flag_m30 = 1        'флаг конца программы
          TIM4_ARR = pausa_z  'скорость Z
          TIM4_CR1.CEN = 1    'запуск Z
          num5="     "        'очистка номера строки команды
          Lcd_Cmd(_LCD_CLEAR) 'очищаю дисплей
          LCD_Out(1, 1, "read file end!!!") 'вывожу сообщение
          delay_ms (1000)  'пауза 1 сек
          Lcd_Cmd(_LCD_CLEAR) 'очищаю дисплей
        end if
      end if
      if cd_byte = "0" then 'если прочитанный символ "0" после М
        FAT32_Read(nomer_file, @cd_byte, 1) size1 = size1 + 1   ' читаю один байт, прибавляя счётчик
        if cd_byte = "3" then 'если прочитан символ "3" код М3
          flag_cd_read = 0  'запрет чтения флэшки
          flag_z_down = 1   'флаг опускания горелки
          flag_z_up = 0     'флаг поднятия горелки
          TIM4_ARR = pausa_z  'скорость Z
          TIM4_CR1.CEN = 1    'запуск Z
        end if
        if cd_byte = "5" then 'если прочитан символ "5" код М5
          flag_pausa_stop = 1 'запуск паузы после движения
          flag_cd_read = 0    'запрет чтения флэшки
        end if
      end if
    end if
    if ((cd_byte = 0x0A) and (flag_uskor = 1)) then   'если прочитан конец строки и есть флаг начала движения
      if ((flag_g0g1 = 0) and (flag_g2g3 = 0)) then '<---------------- G00
        if ((abs(x0-x1) > dlina_impulsa_x) or (abs(y0-y1) > dlina_impulsa_y)) then   'если текущие координаты больше длины шага импульса
          l = 0    'пройденная длина траектории
          dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
          pausa = (dlina_hoda * 6000000)/skorost_holost_hoda         'рассчитываю рабочую скорость
          pausa_min = pausa
          pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
          if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
          if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
          if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
          TIM6_ARR = pausa_max    'стартовая скорость
          flag_z_up = 1      'флаг авто режима поднятия Z
          flag_tormoz = 0    'флаг торможения = 0 т.е. установка начала движения
          vremya_uskor = vremya_uskor_g0 'время разгона
          flag_cd_read = 0        'запрет чтения флэхи
          TIM4_ARR = pausa_z      'скорость Z
          TIM4_CR1.CEN = 1        'запуск Z
        else
          flag_uskor = 0   'если расстояние меньше длины шага, то отменяем начало движения
        end if
      end if
      if ((flag_g0g1 = 0) and (flag_g2g3 = 1)) then '<---------------- G01
        if ((abs(x-x1) > dlina_impulsa_x) or (abs(y-y1) > dlina_impulsa_y)) then   'если текущие координаты больше длины шага импульса
          l = 0    'пройденная длина траектории
          dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
          pausa = (dlina_hoda * 6000000)/skorost      'считаю паузу импульсов рабочего хода
          pausa_min = pausa
          pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
          if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
          if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
          if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
          TIM6_ARR = pausa_max    'стартовая скорость
          flag_tormoz = 0   'флаг торможения = 0 т.е. установка начала движения
          pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения
          vremya_uskor = pausa 'устанавливаю время ускорения
          flag_cd_read = 0     'запрет чтения флэхи
          time_start = TIM7_CNT  'запоминаю время начала движения по X Y
          TIM6_CR1.CEN = 1       'запускаю движение по X Y
        else
          flag_uskor = 0     'если расстояние меньше длины шага, то отменяем начало движения
        end if
      end if
      if ((flag_g0g1 = 1) and (flag_g2g3 = 0)) then '<---------------- G02 движение по часовой - угол старта больше угла окончания
        radius = sqrt(pow((x0 - i), 2) + pow((y0 - j), 2))  'рассчитываю радиус
        if radius > (dlina_impulsa_x + dlina_impulsa_y) then   'если радиус больше шага
          a_start=atan2((x0 - i),(y0 - j))   'рассчитываю угол старта
          a_end = atan2((x1 - i),(y1 - j))   'рассчитываю угол финиша
          if a_start <= (a_end + 0.02) then a_start = 2*PI + a_start end if 'если угол старта меньше угла финиша с учётом небольшой погрешности, то прибавляю полный оборот к стартовому углу
          a_shag = dlina_hoda / (2*radius) 'рассчёт угла шага, приращения угла
          a = a_start 'угол начала движения
          pausa = (dlina_hoda * 6000000)/skorost       'считаю паузу импульсов рабочего хода (скорость)
          pausa_min = pausa 'устанавливаю значение скорости
          pausa = (dlina_hoda * 6000000)/start_skor    'считаю паузу стартового хода
          if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if 'подстраховка от переполнения
          TIM6_ARR = pausa_max    'стартовая скорость
          flag_tormoz = 0  'флаг торможения = 0 т.е. установка начала движения
          pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения пропорционально скорости
          vremya_uskor = pausa 'запоминаю ускорение
          flag_cd_read = 0    'запрет чтения флэхи
          time_start = TIM7_CNT  'запоминаю время начала движения по X Y
          TIM6_CR1.CEN = 1       'запускаю движение по X Y
        else
          flag_uskor = 0  'если радиус меньше длины шага, то отменяем начало движения
        end if
      end if
      if ((flag_g0g1 = 1) and (flag_g2g3 = 1)) then '<---------------- G03 движение против часовой - угол старта меньше угла финиша
        radius = sqrt(pow((x0 - i), 2) + pow((y0 - j), 2)) 'рассчитываю радиус
        if radius > (dlina_impulsa_x + dlina_impulsa_y) then 'если радиус больше шага
          a_start=atan2((x0 - i),(y0 - j))  'рассчитываю угол старта
          a_end = atan2((x1 - i),(y1 - j))  'рассчитываю угол финиша
          if (a_start + 0.02) >= a_end then a_end = 2*PI + a_end end if 'если угол старта больше угла финиша с учётом небольшой погрешности, то прибавляю полный оборот к финишному углу
          a_shag = dlina_hoda / (2*radius) 'рассчёт угла шага, приращения угла
          a = a_start 'угол начала движения
          pausa = (dlina_hoda * 6000000)/skorost       'считаю паузу импульсов рабочего хода
          pausa_min = pausa 'устанавливаю значение скорости
          pausa = (dlina_hoda * 6000000)/start_skor    'считаю паузу стартового хода
          if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if 'подстраховка от переполнения
          TIM6_ARR = pausa_max    'стартовая скорость
          flag_tormoz = 0  'флаг торможения = 0 т.е. установка начала движения
          pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения
          vremya_uskor = pausa   'запоминаю ускорение
          flag_cd_read = 0       'запрет чтения флэхи
          time_start = TIM7_CNT  'запоминаю время начала движения по X Y
          TIM6_CR1.CEN = 1       'запускаю движение по X Y
        else
          flag_uskor = 0   'если радиус меньше длины шага, то отменяем начало движения
        end if
      end if
    end if
    if size1 >= (size - 1) then  'если размер прочитанных байт больше размера файла
      flag_cd_read = 0      'запрет чтения флэхи
      flag_cd_init = 0      'сброс инициализации флэхи
      num5="     "          'обнуляю инфу о номере строк
      Lcd_Cmd(_LCD_CLEAR)   'очищаю экран
      LCD_Out(1, 1, "read file end!!!") 'вывожу сообщение
      delay_ms (1000)                  'пауза 1 сек
      Lcd_Cmd(_LCD_CLEAR)    'очищаю экран
    end if
  wend
  out_if:
  if ((knopka_stop = 0) and (flag_cd_init = 1) and (flag_stop = 0) and (flag_start = 0)) then  'если нажата кнопка стоп есть движение по программе и нет флага остановки и запуска
    flag_stop_g0g1 = flag_g0g1   'запоминаю состояние флагов
    flag_stop_g2g3 = flag_g2g3
    flag_stop_z_up = flag_z_up
    flag_stop_z_down = flag_z_down
    flag_stop_pausa_start = flag_pausa_start
    flag_stop_pausa_stop = flag_pausa_stop
    flag_stop = 1               'выставляю флаг остановки
    LCD_Out(1, 7, "STOP      ")   'вывожу сообщение
    if ((flag_z_up = 1) or (flag_z_down = 1) or (flag_pausa_start = 1) or (flag_pausa_stop = 1)) then  'если режим движения Z или пауза М3 М5
      flag_uskor = 0 flag_tormoz = 0 TIM6_CR1.CEN = 0 'останавливаемся
      pin_dir_x = 0 pin_dir_y = 0 'обнуляю выводы дир
      plasma_on = 0        'выключаю плазму
      x0stop = x  y0stop = y   'запоминаю координату начальную
      x1stop = x1 y1stop = y1  'и конечную
      flag_z_up = 0            'обнуляю флаги
      flag_z_down = 0
      flag_z_to_z_start = 0
      flag_pausa_start = 0
      flag_pausa_stop = 0
      pausa_start = 0
      pin_dir_z = 0         'обнуляю выводы
      pin_step_z = 0
      TIM4_CR1.CEN = 0      'останавливаю движение Z
    end if
  end if
  if ((knopka_start = 0) and (flag_cd_init = 1) and (flag_stop = 1) and (TIM8_CR1.CEN = 0) and (TIM6_CR1.CEN = 0) and (TIM4_CR1.CEN = 0)) then 'если нажата кнопка СТАРТ в режиме СТОП и нет движения по X Y Z
    flag_start = 1   'выставляю флаг начала движения
    flag_stop = 0    'убираю флаг стопа
    LCD_Out(1, 7, "          ")   'убираю надпись STOP
    if ((abs(x - x0stop) > dlina_impulsa_x) or (abs(y - y0stop) > dlina_impulsa_y)) then   'если текущие координаты отличаются от координат остановки больше чем на длину шага импульса
      x0 = x  'приравниваем текущею координату к начальной траектории
      y0 = y
      x1 = x0stop   'конечная координата
      y1 = y0stop
      l = 0    'пройденная длина траектории
      dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
      pausa = (dlina_hoda * 6000000)/skorost_holost_hoda
      pausa_min = pausa
      pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
      if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
      if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
      if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
      TIM6_ARR = pausa_max    'стартовая скорость
      flag_z_up = 1      'флаг авто режима поднятия Z
      flag_uskor = 1        'ускорение
      flag_tormoz = 0
      flag_g0g1 = 0         'режим G0 (холостого хода)
      flag_g2g3 = 0
      flag_dont_read = 1     'запрет чтения флэхи после окончания движения
      vremya_uskor = vremya_uskor_g0 'скорость разгона (ускорение)
      TIM4_ARR = pausa_z      'выставляю скорость Z
      TIM4_CR1.CEN = 1        'запуск Z
    end if
  end if
  if ((flag_start = 1) and (flag_uskor = 0) and (flag_tormoz = 0) and (TIM8_CR1.CEN = 0) and (TIM4_CR1.CEN = 0)) then 'если есть флаг старта и нет движения по X Y Z
    flag_start = 0        'обнуляю флаг старта
    flag_dont_read = 0    'обнуляю флаг запрета чтения флэшки после остановки
    '-------- дальше рассматриваются варианты этапов работы, на котором была остановка, и продолжение прерваного действия
    if flag_stop_z_up = 1 then   'если горелка поднималась перед началом движения по G0
     flag_z_up = 1               'флаг поднятия горелки
     flag_z_down = 0             'обнуляю флаг опускания горелки
     flag_z_to_z_start = 0       'обнуляю флаг выхода на точку поджига
     flag_g0g1 = 0               'выставляю флаги G0
     flag_g2g3 = 0
     x0 = x y0 = y               'начальные координаты равны текущим
     x1 = x1stop y1 = y1stop     'конечные координаты которые запомнили при остановке
     l = 0    'пройденная длина траектории
     dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
     pausa = (dlina_hoda * 6000000)/skorost_holost_hoda        'рассчитываю скорость
     pausa_min = pausa                                        'запоминаю скорость
     pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
     if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
     if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
     if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
     TIM6_ARR = pausa_max    'стартовая скорость
     flag_uskor = 1          'выставляю флаг ускорения
     flag_tormoz = 0         'выставляю флаг ускорения (начала движения)
     vremya_uskor = vremya_uskor_g0 'время ускорения для  хол.хода
     TIM4_ARR = pausa_z     'скорость Z
     TIM4_CR1.CEN = 1        'запуск Z
    else
      if ((flag_stop_z_down = 1) or (flag_stop_pausa_start = 1)) then 'если была остановка при опускании горелки вниз или при паузе М3
        flag_z_up = 0       'выставляю флаги на опускание горелки вниз
        flag_z_down = 1
        flag_z_to_z_start = 0
        TIM4_ARR = pausa_z      'скорость Z
        TIM4_CR1.CEN = 1        'запуск Z
      else
        if flag_stop_pausa_stop = 1 then  'если остановились во время паузы М5
          flag_pausa_stop = 0       'выставляю флаги
          flag_pausa_start = 0
          flag_z_up = 0
          flag_z_down = 0
          flag_z_to_z_start = 0
          flag_cd_read = 1          'продолжаю чтение Flash-ки
        else
          if ((flag_stop_g0g1 = 0) and (flag_stop_g2g3 = 0)) then      '<------- G0 если была остановка при холостом перемещении
            flag_z_up = 1     'флаг поднятия горелки
            flag_z_down = 0         'флаг опускания горелки
            flag_z_to_z_start = 0   'флаг выхода на высоту поджига
            flag_g0g1 = 0           'флаги движения по G0
            flag_g2g3 = 0
            x0 = x y0 = y            'координаты начальные приравниваю к текущим
            x1 = x1stop y1 = y1stop  'вспоминаю конечные координаты при остановке
            l = 0    'пройденная длина траектории
            dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))   'вычисляем длину траектории по Пифагору
            pausa = (dlina_hoda * 6000000)/skorost_holost_hoda  'считаю скорость
            pausa_min = pausa                                   'запоминаю скорость
            pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
            if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
            if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
            if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
            TIM6_ARR = pausa_max    'стартовая скорость
            flag_uskor = 1          'флаги начала движения
            flag_tormoz = 0
            vremya_uskor = vremya_uskor_g0  'время ускорения для хол.хода
            TIM4_ARR = pausa_z      'скорость Z
            TIM4_CR1.CEN = 1        'запуск Z
          else
            if ((flag_stop_g0g1 = 0) and (flag_stop_g2g3 = 1)) then      '<------- G1 если была остановка при линейном рабочем движении
              l = 0    'пройденная длина траектории
              x0 = x y0 = y  'координаты начальные приравниваю к текущим
              x1 = x1stop y1 = y1stop  'вспоминаю конечные координаты до остановки
              dlina = sqrt(pow((x1 - x0), 2) + pow((y1 - y0), 2))        'вычисляем длину траектории по Пифагору
              pausa = (dlina_hoda * 6000000)/skorost      'считаю паузу импульсов рабочего хода
              pausa_min = pausa                           'запоминаю
              pausa = (dlina_hoda * 6000000)/start_skor              'считаю паузу стартового хода
              if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if       'подстраховка от переполнения
              if x1 > x0 then pin_dir_x = 0 else pin_dir_x = 1 end if    'направление движения
              if y1 > y0 then pin_dir_y = 0 else pin_dir_y = 1 end if    'тоже
              TIM6_ARR = pausa_max    'стартовая скорость
              pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения пропирционально скорости
              vremya_uskor = pausa   'запиминаю
              flag_cd_read = 0       'флаг чтения флэхи
              flag_uskor = 1         'далее два флага начала движения
              flag_tormoz = 0
              flag_g0g1 = 0          'затем два флага для G1 (рабочее линейное перемещение)
              flag_g2g3 = 1
              flag_z_down_and_start = 1  'флаг старта сразу после опускания горелки
              flag_pausa_stop = 0        'выставляю флаги состояния
              flag_pausa_start = 0
              flag_z_up = 0
              flag_z_down = 1            'флаг опускания горелки
              flag_z_to_z_start = 0
              TIM4_ARR = pausa_z      'скорость Z
              TIM4_CR1.CEN = 1        'запуск Z
            else
              if ((flag_stop_g0g1 = 1) and (flag_stop_g2g3 = 0)) then      '<------- G2 если была остановка при движении по окружности по часовой
                x0 = x y0 = y 'координаты начальные приравниваю к текущим
                x1 = x1stop y1 = y1stop  'вспоминаю конечные координаты до остановки
                radius = sqrt(pow((x0 - i), 2) + pow((y0 - j), 2)) 'рассчитываю радиус
                a_start=atan2((x0 - i),(y0 - j))  'стартовый абсолютный угол
                a_end = atan2((x1 - i),(y1 - j))  'конечный абсолютный угол
                if a_start <= (a_end + 0.02) then a_start = 2*PI + a_start end if  'если стартовый угол меньше конечного с учётом погрешности, то прибавляю один оборот
                a_shag = dlina_hoda / (2*radius) 'рассчитываю угол шага
                a = a_start 'начало движения
                pausa = (dlina_hoda * 6000000)/skorost       'считаю паузу импульсов рабочего хода
                pausa_min = pausa                            'запоминаю
                pausa = (dlina_hoda * 6000000)/start_skor    'считаю паузу стартового хода
                if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if 'подстраховка от переполнения
                TIM6_ARR = pausa_max    'стартовая скорость
                pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения в пропорции со скоростью
                vremya_uskor = pausa  'запоминаю
                flag_uskor = 1      'выставляю флаги начала движения
                flag_tormoz = 0
                flag_g0g1 = 1       'флаги режима круговой интерполяции G02 по часовой стрелке
                flag_g2g3 = 0
                flag_z_down_and_start = 1   'флаг начала движения после опускания горелки
                flag_pausa_stop = 0
                flag_pausa_start = 0
                flag_z_up = 0
                flag_z_down = 1
                flag_z_to_z_start = 0
                TIM4_ARR = pausa_z      'скорость Z
                TIM4_CR1.CEN = 1        'запуск Z
              else
                if ((flag_stop_g0g1 = 1) and (flag_stop_g2g3 = 1)) then      '<------- G3 если была остановка во время движения по круговой интерполяции против часовой стрелки
                  x0 = x y0 = y 'координаты начальные приравниваю к текущим
                  x1 = x1stop y1 = y1stop 'вспоминаю конечные координаты до остановки
                  radius = sqrt(pow((x0 - i), 2) + pow((y0 - j), 2)) 'рассчитываю радиус
                  a_start=atan2((x0 - i),(y0 - j)) 'стартовый абсолютный угол
                  a_end = atan2((x1 - i),(y1 - j)) 'конечный абсолютный угол
                  if (a_start + 0.02) >= a_end then a_end = 2*PI + a_end end if  'если стартовый угол больше конечного с учётом погрешности, то прибавляю один оборот
                  a_shag = dlina_hoda / (2*radius)  'рассчитываю угол шага
                  a = a_start  'начало движения
                  pausa = (dlina_hoda * 6000000)/skorost       'считаю паузу импульсов рабочего хода
                  pausa_min = pausa                            'запомнил
                  pausa = (dlina_hoda * 6000000)/start_skor    'считаю паузу стартового хода
                  if pausa > 65534 then pausa_max = 65534 else pausa_max = pausa end if 'подстраховка от переполнения
                  TIM6_ARR = pausa_max    'стартовая скорость
                  pausa = vremya_uskor_g0 * skorost / skorost_holost_hoda    'считаю время ускорения
                  vremya_uskor = pausa   'запоминаю в целочисленном виде
                  flag_uskor = 1     'флаги начала движения
                  flag_tormoz = 0
                  flag_g0g1 = 1      'флаги движения по круговой интерполяции G3 против часовой стрелки
                  flag_g2g3 = 1
                  flag_z_down_and_start = 1  'флаг начала движения сразу после опускания горелки и паузы
                  flag_pausa_stop = 0
                  flag_pausa_start = 0
                  flag_z_up = 0
                  flag_z_down = 1
                  flag_z_to_z_start = 0
                  TIM4_ARR = pausa_z      'скорость опускания горелки
                  TIM4_CR1.CEN = 1        'запуск Z
                 end if
              end if
            end if
          end if
        end if
      end if
    end if
  end if
 wend
end.

Пример.

чертёж

Программа

N1 G21
N2 G53 G90 G40
N3
N4 S500
N5 G00X63.158Y94.018
N6 M03
N7 G04 P0.6
N8 G03X49.436Y90.597I58.007J85.446
N9 G03X49.436Y90.597I70.865J77.721
N10 G03X51.146Y83.736I53.722J88.022
N11 M05
N12 G00X110.912Y123.777
N13 M03
N14 G04 P0.6
N15 G01X113.332Y114.074
N16 G01X119.38Y89.817
N17 G03X149.685Y71.607I143.637J95.865
N18 G02X131.476Y41.302I155.733J47.35
N19 G02X82.961Y29.206I107.218J35.254
N20 G01X34.446Y17.11
N21 G01X10.254Y114.139
N22 G01X113.332Y114.074
N23 G01X118.332Y114.071
N24 M05
N25 M30
 

Название файла с программой должно быть "program.cnc"