Пословица темы:  «Ужин не нужен, был бы обед».

  Форт-программа  управления эквивалента нагрузки

                                                   

Адрес документа:

http://90.189.213.191:4422/temp/sintep_v3_2spf/sintep_v3_2spf.doc    инд: 2-22-6   дан

 

Аннотация:

·        В данном документе приведена программа на языке Форт, которая управляет эквивалентном нагрузки и использует старт-стопный канал связи стандарта RS485;

·        Приведена схема управления эквивалента нагрузки с гальванической развязкой от компьютера, которая работает с данной программой;

·        Используется метод формирования заданного уровня сигнала из «сингулярной» последовательности блочного передаваемого кода;

·        Интегральное преобразование импульсных сигналов известно достаточно давно и автор только соединил известные принципы в предлагаемую схему и программу;

·        Конструкция доступна для повторения всеми желающими, предназначена для сокращения трудозатрат  в отладочных работах с блоками питания или другими задачами использования эквивалентов нагрузки;

·        Программа  имеет статус «свободного» применения, подготовлена в стиле  изучения языка программирования Форт. Автор постарался ввести максимально возможное количество  комментариев на действия программы. Показывается передача данных от RS485 на конкретной технической задаче;

 

Схема управления эквивалентом нагрузки от старт-стопного канала связи RS485

·        Ниже на рисунке представлена схема, с которой работает предлагаемая программа.

·        Программа формирует и передает блок байтов на подключенный порт RS485.

·        Скважность  импульсных сигналов формирует на интегрирующей цепи из С1 и оптопаре VT1 требуемый ток, который открывает выходной транзистор оптопары.

·        Выходной транзистор оптопары управляет  внешним блоком, состоящим из трех мощных транзисторов. Эти транзисторы выполняют рассеивание мощности на своих p-n-p переходах и поэтому обязательно должны быть на радиаторах.

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

·        В настоящее время имеется много недорогих  USB-RS485 преобразователей пригодных для эквивалента нагрузки по данной схеме. Некоторые виды  приведены ниже на рисунке;

·        Схема построена так, что бы при обрыве или отсутствии сигнала от RS485 электронное сопротивление имело максимальное значение;

·        Программа начинает работу с максимального значения и постепенно снижает до минимального значения;

·        Выбор значения емкости  интегрирующего конденсатора проводится из расчета То – минимальный импульс для  установленной скорости порта RS485.  

·        Для скорости V=115200 бит в секунду получаем То=~8 микросекунд. Сопротивление включенного светодиода в номинальном режиме свечения примерно составляет 50..150 ом.  Из формулы 3*R*C= Tз, где

o       R = 100 ом – среднее сопротивление включенного светодиода;

o       С = 2200 микрофарад – емкость интегрирующего конденсатора;

o       Тз=3*100* 2200*10^6,   Тз= 0.6 микросекунды

·        Таким образом,  То>Тз  с запасом более чем 10 раз. Этого вполне хватает для поддержания среднего тока при разных сигналах скважности «сингулярного» сигнала.

 

Программа на языке Форт для управления электронной нагрузкой

·        Файл программы upravlenie_ren_v1.f имеет текстовый формат и может редактироваться блокнотом или любым другим текстовым редактором.

·        Внимание! С учебной целью обратить внимание на понятие кодировки, текст программы дан в кодировке OEM-DOS. Если Вы используете блокнот, то выберите шрифт ТЕРМИНАЛ. 

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

·        В каталоге находиться, так же и компилятор языка forth spf4.exe автор А.Черезов http://www.forth.org.ru/ 

·        Текст программы приведен далее в таблице. Комментарии даны по ходу текста программы, иногда в сокращенном виде и  в терминах программирования. Возможны «ляпы» грамматики и лексики, но автор старался «вложить» смысл в действия  программы и ждет любую критику  для изучения способов обучения.

                                                  

\ текст программы на языке ФОРТ = Управление электронной нагрузкой=  upravlenie_ren_v1.f

\  -------------------------------------------------------------------------------

\

\ Пояснение по алгоритму программы:

\  - программа выдает последовательность кодов Ni блоком размером Nb байт;

\  - байты Ni из ряда 0x0 0x01 0x03 0x07 0x0F 0x1F 0x3F 0x7F 0xFF  общим количеством 9

\  - клавишами клавиатуры изменяется содержание блока, выход из программы клавиша ESC;

\  - скорость передачи определена в 115 кбит в секунду;

\  - предельная скорость зависит от используемого адаптера и может достигать до 2700 кбит в секунду;

\  - увеличение скорости создает уменьшение длительности импульсов, что позволяет использовать меньшую емкость;

\  - порт задается в командной строке цифрой номера порта;

\  - второй цифрой в командной строке допускается задать начальное значение электронной нагрузки;

\  - каждое значение Ni - определяет среднее значение интегрального тока и соответственно эквивалент нагрузки;

\  - количество Nb байтов в блоке передачи выбирается от 1го и верхняя граница ограничена разумным выбором; 

\  - если  задать Nb=8 то получим 8*9= итого 72 значения интегрального тока или значений электронной нагрузки;

\  - используется принцип "сингулярного управления" http://www.sciteclibrary.ru/rus/catalog/pages/14764.html

\  - точное значение электронной нагрузки зависит и от ВАХ используемых PNP транзисторов;

\  - программа оформлена в виде окна консоли;

\  - программа приведена для примера обучения программированию на языке ФОРТ и доступна всем желающим.

\  - все изменения Вам доступны, но за изменения отвечает изменяющий!

\  - подробное назначение схемы, по которой работает программа, на сайте по клавише 8

\  - Исполняемый файл upravlenie_ren_v1.exe формируется при компиляции всеми версиями spf-форта;

\ 

\ Успехов и здоровья!  

\ автор Шабронов Андрей Анатольевич тс +7-913-905-8839  shabronov@ngs.ru

 

 

\ начало текста программы ---------------------------------------------------

\ определим основные характеристики программы константами данных

DECIMAL ( устанавливаем дальнейшую работу  в десятичной системе счисления )

115200 CONSTANT  V_PORT       ( КОНСТАНТA устанавливает скорость порта  )

64     CONSTANT  NUM_PORT     ( КОНСТАНТA устанавливает порт по умолчанию иначе надо задавать в комтроке  )

100    CONSTANT  REN_BAIT_MAX ( КОНСТАНТA определяет количество байт в блоке  Nb это точность уставки Rэн )

 

\  далее слова для   контроля и отладки ?KEY1 STOP1

: ?KEY1  ( K --> код клавиши без останова  )   KEY? IF  PENDING-CHAR @  ELSE 0  THEN ;

: ?KEY0!  PENDING-CHAR 0!  ;  (  сбрасываем полученный код клавиши )

: STOP1 BEGIN ?KEY1 DUP 0x1B = IF BYE THEN 0x20 = UNTIL ( останов, выход по нажатию ESC продолжить - Пробел  ) ;

CREATE KKS_B  0 ,  ( переменная для временного хранения системы счисления )

: KKS (  контроль стека с предупреждением о  исчерпании стека )

  BASE @ KKS_B ! ( систему счисления  на сохранение )

  CR ."  ctk,N--> " DECIMAL

  DEPTH DUP 1 < IF  DUP 0= IF  .  ."  STEK PUSTO!" ( при 0 )

                           ELSE  DROP ." ОШИБКА! - СТЕК ИСЧЕРПАН !!! "

                           THEN

                ELSE  DUP  .  HEX ."  = "     .SN

                THEN      ."   -->  "

       KKS_B @ BASE ! ( вернули систему счисления  )      ;

\ далее слова для выполнения действий по программе  ----------------------------  

 

: BEEP3   7 EMIT ; ( ЗВУК ЧЕРЕЗ ДИНАМИК будет  ПИ-ПИ )

WINAPI:   ShellExecuteA     shell32.dll  ( подключаем библиотеку для работы оболочкой выполнения )

WINAPI:   MessageBoxA       USER32.DLL   ( подключаем библиотеку сообщений окна  )

5  CONSTANT SW_SHOW  ( КОНСТАНТA ДЛЯ РАБОТЫ С БИБЛИОТЕКАМИ dll ВИНДОВС )

 

: START_S ( An n  -  на входе адрес выполнения сайта или других действий )

     DROP ( убрали количество знаков )

     SW_SHOW ( из библиотеки виндовс )

     0 0      ( An K1 K2 K3 -- )  3 ROLL

     ( K1 K2 K3 An -- )

     S" open" DROP    0 ShellExecuteA  (  pz- --- остался признак выполнили или нет ) 

     DROP  ( удалили признак без контроля выполнения )  ;

 

: DISPETCHER_PK ( - вызвать диспетчера устройств компьютера  )

  SW_SHOW  0 S" devmgmt.msc" DROP  S" mmc.exe" DROP S" open" DROP   0 ShellExecuteA DROP ;

 

CREATE DAN_REN_V1 0 ,  REN_BAIT_MAX  9 * ,   ( Важная ячейка 4+ =число= * 9 определяет точность уставок )

\  РЕЗЕРВИРУЕМ ячейку в которой будет адрес выделеной памяти для работы с программой

\  в +4 данные о количестве байт на передачу. В данной версии = 100. Можно изменить свою точность

CREATE DAN_REN_V2  0x0 C, 0x01 C, 0x03 C, 0x07 C, 0x0F C,  0x1F C, 0x3F C, 0x7F C, 0xFF  C,

\  записываем байты для выдачи. Их всего 9 и они передаются через RS485 

CREATE WasWrite    0 ,  ( количество переданных байт )

0 VALUE  handle1  ( указатель порта 1 )

 

\ пояснение по использованию 4 + для сдвига границ на в адресном пространстве

\ в библиотеке есть слово CELL оно равно выполнению -> 4  т положить на стек число

\  а также                CELL+                     -> 4 + т.е. положить 4 и сложить

\ Автор не использует их, а пишет числа и действия. Уж такой автор, не любит лишних знаков.

 

 

\  библиотеки DLL для работы с консолью ВИНДОВСа

WINAPI: SetConsoleCursorPosition     KERNEL32.DLL

WINAPI: GetLargestConsoleWindowSize  KERNEL32.DLL

WINAPI: FillConsoleOutputCharacterA  KERNEL32.DLL

WINAPI: SetConsoleTextAttribute      KERNEL32.DLL

 

: ?WinError   0= IF GetLastError THROW THEN  ;

: TEXT-ATTR ( fg bg -- установка цвета знака fg фона bg )   0x10 * + H-STDOUT SetConsoleTextAttribute ?WinError ;

: UST_ATR_LIM_CMD    0xF  8  TEXT-ATTR ( fg bg -- установка цвета знака fg фона bg )   ;

: UST_ATR_LIM1_CMD    0xF  5  TEXT-ATTR ( fg bg -- установка цвета знака fg фона bg )   ;

: UST_ATR_LIM2_CMD    0xF  0xA  TEXT-ATTR ( fg bg -- установка цвета знака fg фона bg )   ;

: UST_ATR_NORM_CMD    0x7  0  TEXT-ATTR ( fg bg -- установка цвета знака fg фона bg    0xF - больая яркость знака ) ;

: COORD ( x y -- COORD )  ( 65536 ) 0x10000 * +  ( всe в HEX перевод в 32х разрядность ) ;

: GotoXY ( x y --  установка координаты курсора в консоли )  COORD H-STDOUT SetConsoleCursorPosition ERR THROW ;

: MAX-XY ( -- x y )   H-STDOUT GetLargestConsoleWindowSize   DUP 0x10 RSHIFT SWAP 0xFFFF AND SWAP  ;

: CLS ( стирает экран )    0 >R RP@ 0 MAX-XY * BL H-STDOUT FillConsoleOutputCharacterA R>  2DROP ;

: FIX  ( M --> ) 0x100 /MOD   GotoXY ( x y -- Установить курсор в нужное место консоли по x- y )  ;

 

: MENU_REN_V1_DAN ( -- выдаем цифры изменения )

   0x11A FIX   DAN_REN_V1  @  2 4 * + @ . ( отображаем значение порта последовательной выдачи )

   DAN_REN_V1  @  3 4 * + @ 0= IF  UST_ATR_LIM1_CMD  S" ERR" ELSE S" ok!" THEN TYPE  UST_ATR_NORM_CMD

   0x323 FIX   DAN_REN_V1 DUP  @  @  . 4 + @ 1 - S" /" TYPE  . (  выдача значения кода  Rэн и Rэн_max-1 отсчет от 0 ) ;

 

: MENU_REN_V1 ( - выдается меню выбора режимов и изменения по нажатию клавиши )

 CLS  0 FIX  ( стираем и устанавливаем в левый верхний угол курсор )

 \   0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

 \   0               1               2               3     

  S" Программа управления электронной нагрузкой - upravlenie_ren_v1.f" TYPE CR  ( 0x0 - адрес начала строки )

  S" Установлен порт rs485 N = "           TYPE CR  ( 0x100 - адрес начала строки )

  S" Клавиши выбора значения:"             TYPE CR  ( 0x200 - адрес начала строки )

  S" 1/2 - увеличить/уменьшить Rэн/Rmax= " TYPE CR  ( 0x300 - адрес начала строки ) 

  S" q/w -  +10    /  -10  "               TYPE CR  ( 0x400 - адрес начала строки ) 

  S" a/s -  +40    /  -40  "               TYPE CR  ( 0x500 - адрес начала строки и т.д. )   

  S" Дополнительные возможности:"          TYPE CR 

  S" 6 - включить/выключить режим автоперебора;" TYPE CR

  S" 7 - включить/выключить визуализацию дампа;" TYPE CR

  S" 8 - открыть сайт описания программы;" TYPE CR 

  S" 9 - вызвать диспетчер устройств;"     TYPE CR 

 

  \ -------------

   MENU_REN_V1_DAN ( -- выдаем цифры изменения ) ;

 

: OPTIONS1 ( -> )  ( интерпретировать командную строку )

   GetCommandLineA  ASCIIZ> (  An n --> адрес кол-во ком строки по TYPE  посмотреть )

   TIB SWAP C/L MIN  DUP #TIB ! MOVE ( u1 u2 n --> копирование только для n>0 )

   >IN 0! ( --> в ТИБ строка и колво )

   TIB C@ [CHAR] "  = IF  [CHAR] "   ELSE BL THEN

   WORD DROP  \  код s или что будет на этом месте  

   DEPTH 0= IF NUM_PORT THEN ( устанавливаем  свой порт, если не планируем вводить в ком строке )

   DEPTH 1 > IF DAN_REN_V1 @ 6 4 * + !  (  значение для первичной установки Rэн )   THEN  ;

 

: MEM_OUT_ZAPOLNEN ( -- выполняется заполнение памяти по условиями значения Rэн )

\ Пояснение

\ Память заполняется кодами на основе выбранного значения электронного сопротивления Rэн

\ Если код =0xFF, то передаются все минимальные длительности. Если 0 - то максимальные.

\ Пример для 8ми байт или 8*9 значений установки Rэн

\ Таблица зависимости кодов от значения Rэн 

\  1   2     7  8  байт  на передачу

\  0   0 ....0  0  -  Rэн=0  - максимальная длительность и соответственно минимальное Rэн

\  0   0 ....0  1  -     =1

\  0   0 ....0  3  -     =2

\  0   0 ....0  7  -     =3

\  0   0 ....0  F  -     =4

\  0   0 ....0 1F  -     =5

\  0   0 ....0 3F  -     =6

\  0   0 ....0 7F  -     =7

\  0   0 ....0 FF  -     =8

\  0   0 ....1 FF  -     =9

\  0   0 ....3 FF  -     =10

\        ....

\ FF  FF ...FF FF  -     =71 - минимальная длительность и соответственно максимальное Rэн

\ ------------------------------------------------------------------------------------------

     DAN_REN_V1 @ 4 4 * + @ ( Ab -- )

 DUP DAN_REN_V1 4 + @ 9 /  ( Ab Ab Nb-max -- )  0 FILL ( уст все 0= и потом заполняем )

 DAN_REN_V1  @ @   ( 0...Rэн-max )   9 /MOD    (  0..8 0..Nb -- )

 \ смотрим что в стеке, если указать не 8, а меньшее количество. Даже 1 байт можно.

 \ один байт  (  0..8 0.0 -- )

 \ два байта  (  0..8 0.1 -- )

 \ ТРИ байта  (  0..8 0.2 -- )

 \ 4 байта    (  0..8 0.3 -- )

( Ab   0..8 0..Nb-max  -- )

 2 PICK OVER 0xFF FILL  ( заполняем  по частному  )

 ROT  + (  0..8  Ab' -- )  SWAP (  Ab' 0..8 -- )

 DAN_REN_V2 + C@ ( Ab' Kb -- )  SWAP C! ( устанавливаем по остатку )  ;

 

:NONAME  ( отдельный поток тип =без имени= )

   DROP ( Adan - не нужен т.к. он в глобальной переменной )

\ резервируем память под передачу байт

  DAN_REN_V1 DUP 4 + @ 9 / ALLOCATE THROW ( An Abuf-N -- ) SWAP @ 4 4 * + ! 

  MEM_OUT_ZAPOLNEN ( -- выполняется заполнение памяти по условиями значения Rэн )

  BEGIN ( цикл в потоке начался )

  DAN_REN_V1 @  3 4 * + @

   IF  ( порт в работе можно передавать )

        0  WasWrite  

        DAN_REN_V1 4 + @ 9 / ( Nb )

       DAN_REN_V1 @  4 4 * + @  ( Ab )   handle1   WriteFile 1 = IF ( ok  ) ELSE ( err ) THEN    

   ELSE  0x100 PAUSE ( ставим паузу что бы не грузить процессор если порта нет )

   THEN

  0 UNTIL  ;

 TASK:  REN_V1_OUT_DAN ( создается код для выполнения  потока, он выполняет передачу данных в установленный rs485 )

 

\ работа с СОМ-портами под виндовсом установка библиотек и переменных

WINAPI: GetCommState              KERNEL32.DLL 

WINAPI: SetCommState              KERNEL32.DLL 

WINAPI: SetCommTimeouts           KERNEL32.DLL

 

  0x80000000 NEGATE  CONSTANT GENERIC_READ

  0x40000000         CONSTANT GENERIC_WRITE

 

\  резервирование переменных для данных, таймаутов, и портов

0 

CELL -- ReadIntervalTimeout

CELL -- ReadTotalTimeoutMultiplier

CELL -- ReadTotalTimeoutConstant

CELL -- WriteTotalTimeoutMultiplier

CELL -- WriteTotalTimeoutConstant

CONSTANT COMMTIMEOUTS  ( =14  все разное )

HERE DUP >R COMMTIMEOUTS DUP ALLOT ERASE R> VALUE CommTimeouts

 

0

CELL -- DCBlength         \ sizeof(DCB)  размер используемых двойных слов

CELL -- BaudRate          \ current baud rate   текущий диапазон скорсти

CELL -- Mode              \     режим 3го слова   тут биты

2 -- wReserved            \ not currently used

2 -- XonLim               \ transmit XON threshold

2 -- XoffLim              \ transmit XOFF threshold

1 -- ByteSize             \ number of bits/byte, 4-8

1 -- Parity               \ 0-4=no,odd,even,mark,space  четность 0=нет 1-добавочный 2 четный

1 -- StopBits             \ 0,1,2 = 1, 1.5, 2

1 -- XonChar              \ Tx and Rx XON character

1 -- XoffChar             \ Tx and Rx XOFF character

1 -- ErrorChar            \ error replacement character

1 -- EofChar              \ end of input character

1 -- EvtChar              \ received event character

2 -- wReserved1           \ reserved; do not use

CONSTANT DCB ( 1C  =  0001-1100 )

HERE DUP >R DCB DUP  ALLOT ERASE R>  VALUE MyDCB   (  размер = 0x1C )

 

: S+++ ( A1 N1  A2 N2 -- A1' N1+N2 -- сложения литералов, но первичынй должен быть всегда с запасом )

  2OVER + ( A1 N1 A2 N2 A3 -- )

  OVER  (   A1 N1  A2 N2 A3 N2 --  )

  3 ROLL (  A1 N1  N2 A3 N2 A2 -- )

  ROT ROT   ( A1 N1   N2  A2 A3 N2--- ) CMOVE  +   ( A1 N1+N2 --- )  ;

 

\ подготовка для замены на текст по номеру

: NCOM0_9  S" com1" ;

: NCOM10_99  S" com99" ;

: NCOM100_999 S" com999" ;

: NCOM_P1  S" \\.\" ; ( добавка для работы с номерами портов больше 9 )

 

: IZM_UST_P2 ( N-1..255  - An n )

     DUP  0xA < IF ( 1..9 )

                  ( N=1..9 --> )   0x30 + NCOM0_9  (  K An n --> )  + 1 - C!  (  вписали код )

                   NCOM0_9 ( An n --- )

                ELSE  ( 10.. 255 )

                   DUP 9 > OVER  0xA DUP *  < AND

                   IF  ( N=10..99 )

                       0xA /MOD   0x30 + SWAP 0x30 + ( Kdec Keд --> )

                       NCOM10_99 DROP (  Kdec Ked An --> )  4 + C!

                       NCOM10_99 DROP (  Kdec  An --> )     3 + C!

                        NCOM10_99 ( An n --- ) NCOM_P1  2SWAP S+++

                   ELSE ( 100...255 )

                       0xA /MOD   0xA /MOD  ( Ked Kdec Kcot --> )

                       0x30 +   NCOM100_999 DROP 3 + C!  ( Ked Kdec --> )

                       0x30 +   NCOM100_999 DROP 4 + C!  ( Ked  --> )

                       0x30 +   NCOM100_999 DROP 5 + C!  (  --> )

                          NCOM100_999 ( An n --- ) NCOM_P1  2SWAP S+++

                   THEN

              THEN       ( An n -- )   ;

 

: CommOpen ( addr n -- -1|handle  0/0 -err  )

 CR  2DUP TYPE   ( показываем установку в ходе работы программы  )

 DROP >R

 0 0 OPEN_EXISTING 

 0 0 GENERIC_READ GENERIC_WRITE

 OR  R>

\ Ниже формат заголовка для создания файла или устройства

\     - адрес handle - дескриптора   0=

\     - атрибут                      0=

\     - параметры создания 3=

\     - атрибут защиты               0=

\     - тип совместного доступа      0=

\     - способ доступа               -40000000

\     - имя обьекта                  Au -COMnn

\ ----------------------------------------------------------------

 CreateFileA  ( fr - указатель или -1 если не создали )

DUP -1 = IF CR ." eror CreateFileA " ELSE CR ." ok - CreateFileA" THEN

DUP -1 = IF DROP 0  ELSE TO handle1 -1  THEN  ;

 

: CommInit ( --  0=err -1 ok установки порта на скорость и тип данных )

   DCB         MyDCB  DCBlength !

   MyDCB       handle1 GetCommState  ( --> 0= eror  0<> - ok   )

   0<> IF ( если порт доступен для настроек, то устанавливаем свои данные )

   V_PORT   MyDCB BaudRate  !   ( записали скорость  )

 \ Пояснения по установке скорости порта. 

 \  Чем больше скорость тем меньше длительность и можно задествовать меньшую емкость - это gut т.е. хорошо по немецки.

 \  Но большая скорость и быстрее выдаются блоки, а между ними неизбежны паузы - это не gut т.е. плохо.

 \  Если увеличить размер передачи  блока, то будет большая точность - это gut.

 \  Но если надо менять не плавно, а в широком диапозоне, то при большом блоке потребуется время это не gut.

 \  Вывод: необходимо определиться с "золотой срединой" что бы и быстро изменялась интегральная составляющая

 \          и что бы была приемлемая точность.

 \ ---------------------------------------------------------------------------------------         

     8          MyDCB ByteSize C!      ( размер принимаемого блока и тип 8 2 1 )

     0          MyDCB StopBits C!      (  0,1,2 = 1, 1.5, 2   количество стоп-битов   )

     0          MyDCB Parity   C!    (  =1 пров чет  0 нет 2 пров не чет   )

   MyDCB       handle1   SetCommState   ( --> 0= eror  0<> - ok   )

      ELSE  ( ошибка ) 0 (  выходим с признаком ошибкой ) THEN      ;

 

: Timeouts ( PZ1 PZ2 --  записываем данные на таймауты устанавливаем для ЦП 1.4ггц   )     

1  CommTimeouts   ReadIntervalTimeout         !   (  =1 )

1  CommTimeouts   ReadTotalTimeoutMultiplier  !  (  =1 )

1  CommTimeouts   ReadTotalTimeoutConstant    !   (  =1 для  8..7 > ЦП-700мгц  )

1  CommTimeouts   WriteTotalTimeoutMultiplier !   (  =1 )

1  CommTimeouts   WriteTotalTimeoutConstant   !  ( о =1 )

     CommTimeouts handle1                    SetCommTimeouts      ; 

 

: UST_PORTA ( установка порта RS-485 из командной строки. По умолчанию устанавливается СОМ-2 )

   OPTIONS1 ( Nprt -> )  ( интерпретировать только цифру командной строки - т..е только НОМЕР ПОРТА текст НЕЛЬЗЯ! )

   DUP DAN_REN_V1  @  2 4 * + ! ( Nprt cохраняем значение порта )

   IZM_UST_P2 ( N-1..255  - An n  номер порта переводим в литерал для открытия порта )

   CommOpen  ( 0=er -1-ok )   DUP

      IF  CommInit ( 0= er 0<> = ок )

          Timeouts ( 0= er 0<> ok  - PZ1 PZ2 PZ3 ) 

          0<> SWAP 0<> AND 0<> AND  ( 0=er 0<>=ok )

     THEN   (  записали признак -1 ok порт 0= не создали  )

     DAN_REN_V1 @  3 4 * + ! ( Nprt cохраняем 0= ошибка создания -1 порт ок открыли  )        ;

 

: DAN_REN_V1_INP (  N -- ввод данных и проверка на допустимое значение 0 .. 8*9 )

  DAN_REN_V1   @ OVER OVER @ +  DUP 0< SWAP  DAN_REN_V1 4 + @ 1 - > OR   IF 2DROP BEEP3   ELSE  +!  THEN

  MEM_OUT_ZAPOLNEN ( меняем область памяти для выдачи )

  MENU_REN_V1_DAN  ( выдаем значение на экран )  ;

 

: START_REN_V1  ( главное слово программы  выход по клавише ESC )

\  STARTLOG ( ВКЛЮЧИТЬ ФАЙЛ ОТЧЕТА SPF.LOG используется при отладке )

\  ENDLOG (  выключить файл отчета )

   8 4 *   ALLOCATE THROW DAN_REN_V1 !  ( память под данные для работы, ячейки назначения ниже )

   \ +0 - пишем значение Nep 0..9

   \ + 1 4* - пишем указатель на закрытие потока выдачи при выходе из программы

   \ + 2 4* - номер СОМ-порта заданный в ком строке при выполнении программы

   \ + 3 4* -  СОМ-порта заданный в ком строке ок=-1  или не открыли =0

   \ + 4 4* - адрес начала буфера байт передачи  количество в DAN_REN_V1 4+ задано ранее

   \ + 5 4* - адрес признака для выдачи дампа памяти блока на экран    

   \ + 6 4* - адрес значения Reн определенного в командной строке сразу запускается    

   \ + 7 4* - адрес признака для выдачи по автоперебору

   \ -----------------------------------------------------------------------

   UST_PORTA ( установка порта RS-485 из командной строки. По умолчанию устанавливается СОМ-2 )

   DAN_REN_V1 DUP 4 + @ 1 - SWAP @ !  (  установили максимальное значение Rэн сразу же )

   MENU_REN_V1 ( - выдается меню выбора режимов и изменения по нажатию клавиши )

   DAN_REN_V1 @ DUP  REN_V1_OUT_DAN  START SWAP 4 + !  ( запускаем поток на выполнение передачи данных)

    0 ( k -- в стек задаем первичный код  опроса клавиши т.е. 0  )

   BEGIN  ( основной цикл программы  выбор действий по клавишам )

DUP [CHAR] 1 = IF  ?KEY0!                     1             DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

DUP [CHAR] 2 = IF  ?KEY0!                    -1             DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

DUP [CHAR] q = OVER [CHAR] Q = OR  IF ?KEY0! 0xA            DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

DUP [CHAR] w = OVER [CHAR] W = OR  IF ?KEY0! 0xA NEGATE     DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

DUP [CHAR] a = OVER [CHAR] A = OR  IF ?KEY0! 0xA 4 *        DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

DUP [CHAR] s = OVER [CHAR] S = OR  IF ?KEY0! 0xA 4 * NEGATE DAN_REN_V1_INP  ( -- меняем Rэн )  THEN

     \  удобства в работе вызов дополнительных программ

DUP [CHAR] 6 = IF  ?KEY0! DAN_REN_V1 @ 7 4 * + DUP @ 0= IF -1 ELSE 0 THEN SWAP !    THEN               

DUP [CHAR] 7 = IF  ?KEY0! DAN_REN_V1 @ 5 4 * + DUP @ 0= IF -1 ELSE MENU_REN_V1 0  THEN SWAP !    THEN               

DUP [CHAR] 8 = IF  ?KEY0!  S" http://90.189.213.191:4422/temp/sintep_v3_2spf/" START_S ( An n - ) THEN               

DUP [CHAR] 9 = IF  ?KEY0!  DISPETCHER_PK ( - вызвать диспетчера устройств компьютера )    THEN           

      \ действия по  признакам при нажатии клавиши 6 или 7 и информации командной строки

DAN_REN_V1 @ 5 4 * + @ IF  0xB00 FIX DAN_REN_V1 DUP @ 4 4 * + @ ( Adr )  SWAP 4 + @ 9 /  DUMP  THEN

DAN_REN_V1 @ 6 4 * + DUP @ 0<> IF DUP @ SWAP 0! 0x10 PAUSE  DAN_REN_V1  @ 0! ( Rуст=0 -- ) DAN_REN_V1_INP ELSE DROP THEN

DAN_REN_V1 DUP @ 7 4 * + @ IF ( A'Rэп ) DUP @ @ OVER 4 + @ 1 - = IF @ 0! ELSE DROP THEN  1 DAN_REN_V1_INP ELSE DROP THEN

      \  получение кода от нажатия клавиатуры

        DROP ?KEY1 ( K -- )  DUP 0x1B ( КОД ESC ) =

    UNTIL   DROP ( вышли из цикла работы программы )

    DAN_REN_V1 @ 4 + @  STOP (  остановили поток передачи данных )

    BYE  ( вышли из программы и освободили занятую память ) ;

  

'  START_REN_V1   TO <MAIN>     ( установили выполняемое слово )

   S" upravlenie_ren_v1.exe" SAVE  ( записали файл выполнения )

   BYE   ( вышли из компиляции текста  )

\ текст программы окончен

 

Создание исполняемого приложения из текста и работа с программой

·        Текст компилируется компилятором spf4.exe. Задается файл компилятора и далее текст программы, нажимается клавиша <Enter>. Ниже на рисунке-gif показан процесс получения файла исполнения из файла программы.  Справа  рисунок исполняемой программы с портом 77, который подключить не удалось.

 

 

·        При выполнении рисунка-gif видно, что скомпилированная программа выполняется в режиме отображения дампа передаваемого блока с автоперебором.  Для этого, надо нажать клавишу 6 и 7. Видно, что используется порт 64 и он подключен =ОК=.

·        Если указанного порта нет, то отображается ошибка =ERR= что показано на рисунке справа.

·        Получаемый файл исполнения upravlenie_ren_v1.exe  можно скачать из каталога данных программы, если компиляция не проходит на Вашем компьютере.

·        Причины прерывания компиляции могут быть разные: запрет программы антивируса на создание файла,  программа «защитник виндовс» может запретить обращение к портам, брандмаузер компьютера предупредит, что вдруг начались опасные события.

·        Помните шутку про безопасность? -  Умный муж позволяет жене знать, где у него заначка.  — Это повышает доверие в семье, женскую самооценку и безопасность ОСНОВНОЙ ЗАНАЧКИ. Воспользуйтесь этим правилом и при программировании. Разрешите знать  фрейволам и брандмаузерам, где работает Ваша программа.  

·        Окно программы формируется в консольном режиме  и предназначено для управления от клавиатуры. Показано на рисунке ниже в таблице слева. А справа - слово выполнения MENU_REN_V1 ( слово  это термин языка ФОРТ), формирующее данное окно.  

                                                  

 

: MENU_REN_V1 ( - выдается меню выбора режимов и изменения по нажатию клавиши )

CLS  0 FIX  ( стираем и устанавливаем в левый верхний угол курсор )

\   0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

\   0               1               2               3     

  S» Программа управления электронной нагрузкой - upravlenie_ren_v1.f» TYPE CR  ( 0x0 - адрес начала строки )

S» Установлен порт rs485 N = « TYPE CR  ( 0x100 - адрес начала строки )

S» Клавиши выбора значения:»   TYPE CR  ( 0x200 - адрес начала строки )

S» 1/2 - увеличить/уменьшить Rэн/Rmax= « TYPE CR ( 0x300 - адрес начала строки ) 

q/w -  +10  /  -10  « TYPE CR  ( 0x400 - адрес начала строки ) 

a/s -  +40  /  -40  « TYPE CR  ( 0x500 - адрес начала строки и т.д. )   

S» Дополнительные возможности:»          TYPE CR 

S» 7 - включить/выключить визуализацию дампа;» TYPE CR

S» 8 - открыть сайт описания программы;» TYPE CR 

S» 9 - вызвать диспетчер устройств;»     TYPE CR 

  \ -------------

   MENU_REN_V1_DAN ( -- выдаем цифры изменения ) ;

·        Текст программы свободно изменяется  под свои реквизиты или желаемый вид отображения.  Для указания словом FIX - места установки курсора, используется кодировка Y-X одним числом, например:

o       0x100 FIX  это  1-я строка 0-й столбец

o       0x525 FIX это 5-я строка 25-й столбец и т.д.

·        Программа работает при любых состояниях назначенного порта, но данные передаются, только если выполнены условия подключения и настройки.

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

 

Выводы.

·        Существуют «забугорные» изделия «электронных сопротивлений», например ds2890, которые управляются по своему собственному интерфейсу, требуют адаптеров, и могут быть недоступны потребителям из-за пресловутой «цены вопроса».

·        Предлагаемая схема и программа снижает «цену вопроса»  систем управления, которым необходимы аналоговые сигналы.

·        Применение доступных оптопар,  интерфейса RS485    и приведенного программного обеспечения предлагают другие технических решения с использованием устройств «электронных сопротивлений».

 

Автор - Шабронов Андрей Анатольевич   тс.  +7-913-905-8839     e_mail -  shabronov@ngs.ru  

ред.2018-1-15     Успехов и здоровья!