4. Процедурное программирование 4.1. Алгоритмическая декомпозиция программной системы; 4.2. Разновидности подпрограмм в С++; 4.3. Структура программы процедурного.

Презентация:



Advertisements
Похожие презентации
Одномерный массив. Цель урока: познакомить учащихся с понятием одномерный массив Задачи: дать определение массива дать представление: об описании массива.
Advertisements

Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
Практическое занятие 6. Функции. Большинство языков программирования используют понятия функции и процедуры. C++ формально не поддерживает понятие процедуры,
Массивы 9 класс. Основные теоретические сведения Примеры решения задач.
Лекция 14 Индуктивные измерительные устройства Индуктивный преобразователь представляет собой катушку индуктивности, полное сопротивление которой меняется.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
ПРОЦЕДУРЫ И ФУНКЦИИ CPascal Подпрограмма – группа операторов реализующая законченный алгоритм и оформленная как самостоятельная синтаксическая единица.
Инструкции C++ Условная инструкция Формат: if (условие) оператор; else оператор; Пример: if (i!=0) { if (j) j++; if(k) k++; else if(p) k--; } else i--;
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
МАССИВЫ 4 Определение 4 Описание 4 Обращение к элементам массива 4 Связь массивов с указателями 4 Примеры программ.
Тема 2. Способы адресации и система команд МП. Непосредственная адресация Суть способа. Требуемые данные (#data ̶ непосредственный операнд, константа)
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Прерывания Определение прерывания Прерывания представляют собой механизм, позволяющий координировать параллельное функционирование отдельных устройств.
Классификация методов нагружения электрических машин, используемых в качестве приводов нефтегазопромыслового оборудования, для проведения послеремонтных.
Лекция 9 Функции. Массивы-параметры функции Передача массива в функцию Пример: void array_enter(int a[], int size) { int i; for (i = 0; i < size; i++)
Процедуры и функции Вербицкая Ольга Владимировна, Заозерная школа 16.
Лекция 6. Способы адресации в микропроцессорных системах.
Алгоритм. Алгоритм это точно определённая инструкция, последовательно применяя которую к исходным данным, можно получить решение задачи. Для каждого алгоритма.
Лекция 7. Структура языка С/С++. Операторы ветвления: условный оператор if. Полное ветвление. Неполное ветвление. Оператор множественного выбора switch.
Центр дистанционных автоматизированных учебных лабораторий Институт радиоэлектроники и телекоммуникаций [
Транксрипт:

4. Процедурное программирование 4.1. Алгоритмическая декомпозиция программной системы; 4.2. Разновидности подпрограмм в С++; 4.3. Структура программы процедурного типа.

4.1. Алгоритмическая декомпозиция программной системы Алгоритмическая декомпозиция программы – ее представление в виде совокупности процедур, реализующих некие алгоритмы. В С/С++ программа может представлять собой набор функций. Одна из функций имеет имя main (Winmain в Windows) и ей передается управление при запуске программы. main fun1 fun2 fun3 fun4 fun5

4.1. Алгоритмическая декомпозиция программной системы Механизмы передачи параметров и возврата результатов Подпрограммы в языках высокого уровня: «процедуры»: не возвращают результата; параметры передаются по ссылке (фактически передаются адреса внешних объектов памяти); «функции»: возвращают результат; параметры передаются по значению (в стек заносятся копии внешних объектов памяти). В С/C++ реализованы только функции (которые, однако, могут и не возвращать результата). При необходимости передача ссылок может быть организована с помощью указателей и собственно ссылок.

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15; b= sqr(b); … } SP Stack Segment

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15; b = sqr(b); … } Локальная переменная b функции main помещается в стек SP Stack Segment b=15

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15; b = sqr(b); … } В стек помещается копия переменной b, адрес возврата АВ и старое значение регистра BP. В BP копируется содержимое указателя стека BP=SP Stack Segment b=15 15 АВ 15 BP стар.

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15,c; c = sqr(b); … } Локальная переменная а адресуется как [BP+4] BP=SP Stack Segment b=15 15 АВ a=15 BP стар.

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15; b = sqr(b); … } Результат произведения помещается в регистр (обычно это аккумулятор). В стеке читается адрес возврата. SP Stack Segment b=15 15 АВ a=15 BP стар. 225 AX

4.1. Алгоритмическая декомпозиция программной системы Передача параметров по значению int sqr(int a) { return a*a; } main() { int b = 15; b = sqr(b); … } Происходит переход по АВ, стек очищается от параметра, результат заносится в переменную b SP Stack Segment b= АВ a=15 BP стар 225 AX

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием указателя sqr(int *p) { *p*=*p; } main() { int b = 15; sqr(&b); … } Stack Segment b=15 0x21FF 0x2201 0x2203 0x2205 0x2207 0x2209 0x220B 0x220D 0x220F 0x2211 0x2213 SP Локальная переменная b функции main в стеке

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием указателя sqr(int *p) { *p*=*p; } main() { int b = 15; sqr(&b); … } Stack Segment b=15 0x21FF 0x2201 0x2203 0x2205 0x2207 0x2209 0x220B 0x220D 0x220F 0x2211 0x2213 SP В стек помещается адрес переменной b, адрес возврата АВ и старое значение регистра BP. В BP копируется содержимое указателя стека. 15 АВ 0x2213 BP стар.

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием указателя sqr(int *p) { *p*=*p; } main() { int b = 15; sqr(&b); … } Stack Segment b=15 0x21FF 0x2201 0x2203 0x2205 0x2207 0x2209 0x220B 0x220D 0x220F 0x2211 0x2213 SP 15 АВ p=0x2213 BP стар. Локальная переменная p адресуется как [BP+4]

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием указателя sqr(int *p) { *p*=*p; } main() { int b = 15; sqr(&b); … } Stack Segment b=255 0x21FF 0x2201 0x2203 0x2205 0x2207 0x2209 0x220B 0x220D 0x220F 0x2211 0x2213 SP 15 АВ p=0x2213 BP стар. То, что находится по адресу, записанному в указателе p, помножается на само себя.

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием указателя sqr(int *p) { *p*=*p; } main() { int b = 15; sqr(&b); … } Stack Segment b=255 0x21FF 0x2201 0x2203 0x2205 0x2207 0x2209 0x220B 0x220D 0x220F 0x2211 0x2213 SP 15 АВ p=0x2213 BP стар. Переход по адресу возврата и очистка стека.

4.1. Алгоритмическая декомпозиция программной системы Передача параметра по ссылке с использованием ссылки sqr(int &a) { a*=a; } main() { int b = 15; sqr(b); … } Ссылка – константный саморазыменовывающийся указатель. Фактически компилятор подготавливает точно такой же код, как при использовании указателя. Однако в теле функции и при ее вызове это не видно!: в теле функции не нужно применять операцию «*» (обращение по адресу); при вызове передается не адрес переменной, а как будто бы она сама. В приведенном примере после вызова функции изменится переменная b (станет равной 255)

4.1. Алгоритмическая декомпозиция программной системы Преимущества использования ссылок: 1. возможность изменения параметров (теперь функция может возвращать более одного параметра). Пример: функция, определяющая максимальный элемент массива и его индекс: int maxelem(int M[ ], int n, int &ind) { ind = 0; for(int i=1; iM[ind]) ind = i; return M[ind]; } Вызов: int M[ ] = {1,4,3,6,2,5,7,0}, imax; cout

4.1. Алгоритмическая декомпозиция программной системы Преимущества использования ссылок: 2. возможность быстрой передачи «больших» переменных. Если нет необходимости их изменения, можно «подстраховаться», применив const: struct BigStruct { char name[30]; int * any_references[100]; //что-то еще увесистое }; anyfun(const BigStruct &bs) { …. } Вызов: BigStruct a; … anyfun(a);

4.2. Разновидности подпрограмм в С++ Функции с начальными значениями параметров (значениями по умолчанию) Все или часть формальных параметров функции могут иметь значения по умолчанию, в этом случае они должны быть указаны следующим образом: [ ] ([ ],[ ]) Пример: fun(int a, int b = 1, int c = 2) { cout

4.2. Разновидности подпрограмм в С++ Функции с переменным числом параметров Описание/ определение таких функций имеет вид: [ ] (,…) Явные параметры всегда должны присутствовать, иначе теряется доступ к неявным! Проблема обращения к неявным параметрам решается с помощью указателей. Это возможно благодаря тому, что известен порядок помещения параметров в стек (в С/C++ справа налево) Пример: сумма неизвестного количества элементов типа int: long summa(int k,…); // прототип long S = summa(5,2,1,4,8,5);// первый подход: k- число параметров long S = summa(2,1,4,8,5,0);// второй подход: последний элемент -0

4.2. Разновидности подпрограмм в С++ Определение функции summa при первом подходе: long summa(int k,…) { int *p = &k; long a =0; for (; k;k--) a+=*(++p); return a; } Определение функции summa при втором подходе: long summa(int k,…) { int *p = &k; long a =0; for (; *p;p++) a+=*p; return a; } k = 5 АВ BP стар. SP k = 2 АВ BP стар. SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции В С/C++ допускается использование рекурсивных функций! Рекурсивная функция прямо или косвенно (через другую функцию) вызывает саму себя. Классический пример: вычисление факториала (рекурсивная формула X! = X*(X-1)!): long fact(int k) { if(k ==1) return 1; return k*fact(k-1); }

4.2. Разновидности подпрограмм в С++ Рекурсивные функции К рекурсии нужно подходить осторожно: рекурсивная функция обязательно должна иметь механизм «возврата» из рекурсии (в примере это if(k ==1) return 1;); она не всегда эффективна (итерационный алгоритм всегда эффективней рекурсивного). Рассмотрим второй «недостаток».

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(4); 4 АВ BP стар. SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. SP 4*fact(3) 3 АВ BP стар.

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. 3*fact(2) 3 АВ BP стар. SP 2 АВ BP стар.

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. 2*fact(1) 3 АВ BP стар. 2 АВ BP стар. SP 1 АВ BP стар.

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. 3 АВ BP стар. 2 АВ BP стар. AX 1 1 АВ BP стар. 1 SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. 3 АВ BP стар. 2 2 АВ BP стар. AX 1 1 АВ BP стар. 2 SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 АВ BP стар. 3 3 АВ BP стар. 2 2 АВ BP стар. AX 1 1 АВ BP стар. 6 SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 4 АВ BP стар. 3 3 АВ BP стар. 2 2 АВ BP стар. AX 1 1 АВ BP стар. 24 SP

4.2. Разновидности подпрограмм в С++ Рекурсивные функции long fact(int k) { if(k ==1) return 1; return k*fact(k-1); } Вызов: long a = fact(3); 4 4 АВ BP стар. 3 3 АВ BP стар. 2 2 АВ BP стар. AX 1 1 АВ BP стар. 24 SP 24 a

4.2. Разновидности подпрограмм в С++ Итерационный вариант функции: long fact(int k) { long res = k; while(--k) res*=k; return res; } - выполняется гораздо быстрее рекурсивной функции!

4.2. Разновидности подпрограмм в С++ Подставляемые функции «Обычные» функции вызываются с помощью команды CALL, параметры передаются через стек, код функции локализован. В С++ можно определить функцию как подставляемую или встраиваемую с помощью служебного слова inline. Тогда код функции непосредственно встраивается в место вызова (аналог макроса ассемблера и C). Обычно как inline оформляют небольшие функции, например inline int abs(int a) {return a>0? a; - a;} Исходный код: int z = -123; cout

4.2. Разновидности подпрограмм в С++ Подставляемые функции Определение inline не гарантирует, что компилятор будет оформлять функцию как подставляемую. Это только рекомендация, которую он может и проигнорировать, сообщив об этом пользователю. Как inline не могут быть оформлены: «большие» функции; рекурсивные функции; Функции с циклами, переключателями, переходами. Если компилятор не может выполнить подстановку, он оформляет функцию как обычную, определенную как static, т.е. доступную только в данном модуле, как и предусмотрено для inline (действительно, подстановку можно сделать только в пределах модуля, - связь между модулями выполняет компоновщик).

4.2. Разновидности подпрограмм в С++ Указатели на функции Подобно указателям на переменные в С/С++ можно определить указатель на функцию: (* ) ([ ]); например, объявление указателя на функцию, принимающую char и возвращающую int: int (*pf) (char); Скобки обязательны, так как объявление int *pf (char); будет воспринято как прототип функции, возвращающей int*. обязателен! Иначе компилятор перепутает объявление с операцией. Если функция ничего не возвращает, нужно оформлять ее как void, если тип ее возвращаемого значения не указан, то как int.

4.2. Разновидности подпрограмм в С++ Настройка указателя на функцию Если определена некоторая функция, например int fun (char a) {…} то указатель можно на нее настроить «обычным» образом: pf = &fun; а можно и так: pf = fun; т.е. имя функции – по сути есть адрес функции (как и имя массива есть адрес первого его элемента).

4.2. Разновидности подпрограмм в С++ Вызов функции по указателю может быть осуществлен «обычным» образом: (*pf)(a); а можно и так: pf(a); Варианты использования указателей на функцию: организация меню; передача одной функции другой.

4.2. Разновидности подпрограмм в С++ Организация меню «Традиционное» решение: int n; // номер пункта меню cout > n; switch (n) { case 1: fun1(); break; case 2: fun2(); break; … case N: funN(); break; } Решение с помощью указателей: int n; // номер пункта меню cout > n; //массив указателей на функции void(*pf[ ])() = {fun1,fun2,..funN}; //вызов функции по указателю (*pf[n-1])();

4.2. Разновидности подпрограмм в С++ Передача одной функции другой Пример: требуется написать универсальную функцию, вычисляющую максимум математической зависимости. Математические зависимости, в свою очередь, задаются функциями вида: double math_fun_name(double x); Тогда функцию, находящую максимум, можно задать в виде: double math_fun_max(double (*pf)(double), double x_min, double x_max); Указатель на функцию, вычисляющую зависимость Пределы, в которых находится максимум

4.2. Разновидности подпрограмм в С++ Передача одной функции другой Вызов функции math_fun_max для нахождения максимума зависимости, заданной функцией math_fun_name, в диапазоне изменения аргумента -1,5…5,1: math_fun_max(& math_fun_name, -1.5, 5.1); Помимо указателей на функции введены также и ссылки на функции: void fun(void); //прототип функции void (&rf)(void) = fun; //ссылка на функцию rf(); // вызов функции через ссылку. Ссылка на функцию – это просто второе ее имя. Ссылки на функции применяют редко, так как значение ссылки в отличие от указателя изменить нельзя и, следовательно, настраивать ссылку на разные функции невозможно.

4.2. Разновидности подпрограмм в С++ Перегрузка функций Состоит в том, что в программе могут быть определены несколько функций с одинаковыми именами, но различными сигнатурами (списками формальных параметров, а точнее их типами). Пример: int fun(char a); long fun(char*p); int fun(char a, char b); float fun(char b); // ошибка: компилятор при вызове не отличит от первой

4.2. Разновидности подпрограмм в С++ Шаблоны функций Шаблоны – продолжение идеи перегрузки. С помощью шаблона компилятору дается задание самому сформировать функцию в зависимости от типов фактических параметров по вызову. Описание шаблона имеет вид: template ) (тип 1 параметр 1, тип 2 параметр 2,…); Пример (сумма элементов массива неизвестного типа): template T sum(T M[ ], int n) { T res = 0; for (int i =0; i

4.2. Разновидности подпрограмм в С++ Функция, описываемая шаблоном может иметь сколько угодно параметризированных формальных параметров, однако все параметры шаблона должны быть использованы в функции. Формирование функции по шаблону выполняется на этапе компиляции. Примеры: int M[ ] = {2, -3, 4, 1}; float A[ ] = {1.3, -2.1, 4,.2}; cout

4.3. Структура программы процедурного типа Структуру программы процедурного типа рассмотрим на примере программного обеспечения лабораторной установки, разработанной в рамках проведения экспериментов по теме диссертации Рыбалева А.Н. «Энергосберегающий частотно-управляемый электропривод механизмов циклического действия», АмГУ, 1997 год.

4.3. Структура программы процедурного типа Целью экспериментальных исследований являлась проверка полученных теоретических положений. В том числе ставились следующие задачи: реализация законов частотно-токового управления с использованием разработанных алгоритмов и экспериментальная проверка их эффективности; проверка методики проектирования асинхронного частотно- управляемого электропривода механизмов циклического действия; выявление эффективности применения частотного управления АД, характеризующейся как увеличением производительности (т.е. увеличением числа циклов на единицу времени), так и снижением расхода энергии на цикл по сравнению с системой прямого пуска и торможения противовключением.

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

4.3. Структура программы процедурного типа Состав установки Агрегат, состоящий из исполнительного асинхронного двигателя с короткозамкнутым ротором типа АИР 112М4Y3 (исполнительный двигатель) и асинхронного двигателя с фазным ротором типа MTF 011 6Y2 для создания момента сопротивления (нагрузочная машина). Последний работает в режиме противовключения. Регулирование момента сопротивления осуществляется с помощью индукционного регулятора и набора сопротивлений. Валы машин жестко соединены с помощью муфты. В состав агрегата также входит фотоэлектрический датчик углового положения ротора исполнительного двигателя, включающий в себя оптическую пару светодиод - фотодиод и подвижный диск с прорезями, установленный на муфте соединения валов. Число прорезей на диске 360.

4.3. Структура программы процедурного типа Состав установки Преобразователь частоты на базе ЭКТ 2Д. Применяется при частотном управлении исполнительным двигателем. Доработке подвергаются следующие узлы ЭКТ 2Д: силовая схема - с целью преобразования ее из инвертора напряжения в инвертор тока; схема управления инвертором - для получения возможности непосредственного управления процессом коммутации тиристоров инвертора от персонального компьютера. Персональный компьютер, с помощью которого формируется диаграмма движения в цикле, а также, - при частотном управлении, - сигналы задания по току и управления инвертором. На вход ПК (порт COM2) подаются импульсы с датчика углового положения ротора. Происходит вычисление угла поворота и скорости движения исполнительного вала двигателя. На основе этой информации алгоритм, заложенный в компьютерную программу, формирует сигналы управления магнитными пускателями, а также код задания по току и сигналы управления инвертором (при частотном управлении).

4.3. Структура программы процедурного типа Состав установки Щит управления, интегрирующий все силовые и управляющие цепи экспериментальной установки. Щит содержит: блок магнитных пускателей, коммутирующих цепи питания двигателей по сигналам ПК или с помощью ручного управления в отладочных режимах; переключатель структуры системы, задающий режим работы установки (прямой пуск или частотное управление); счетчик активной энергии; устройства защиты и сигнализации. Защита двигателей осуществляется с помощью автоматических выключателей и тепловых реле. При частотном управлении дополнительно двигатель и преобразователь защищены предохранителями. Система измерения температуры нагрева исполнительного двигателя. Система включает в себя термопару, укладываемую в лобовую часть статорной обмотки исполнительного двигателя на стороне, противоположной крыльчатке вентиляции (где наблюдается наибольший нагрев) и вторичный измерительный прибор (самописец) типа РП 160.

4.3. Структура программы процедурного типа Д - двигатель ; ДТМ - датчик температуры ; ДУП - датчик углового положения ротора ; ПК - персональный компьютер ; РП - регистрирующий прибор ; СЗМС - система задания момента сопротивления ; СУП - схема управления пускателями.

4.3. Структура программы процедурного типа ДТ - датчик тока; РТ - регулятор тока; И - инвертор; УВ - управляемый выпрямитель; ПЧ - преобразователь частоты; ЦАП - цифроаналоговый преоб-ль.

4.3. Структура программы процедурного типа Исполнительный двигатель М1 подключается к питающей линии через контакты магнитных пускателей КМ1, КМ2, соединенных по схеме позволяющей осуществлять пуск двигателя в направлениях вращения «вперед» (КМ1) и «назад» (КМ2). Питание двигателя производится либо непосредственно от сети (прямые пуски), либо от преобразователя частоты ПЧ. Режим питания задается с помощью переключателя S6. В фазу «А» питания исполнительного двигателя включен первичная обмотка трансформатора тока Т1. Вторичная цепь Т1 содержит амперметр и токовую обмотку счетчика активной энергии Wh. Обмотка напряжения счетчика включена к выводам фазы «А» и «0». Включение и отключение цепи измерения производится с помощью выключателя S5. Силовая схема

4.3. Структура программы процедурного типа Нагрузочная машина М2 получает питание от сети через контакты пускателя КМ3. Для регулирования напряжения на статоре М2 в схему введен индукционный регулятор напряжения ИРН, который получен путем изменения схемы включения обмоток фазорегулятора ФР-50. Регулирование напряжения на его выходе осуществляется путем изменения взаимной ориентации статорной и роторной обмоток. Напряжение контролируется с помощью вольтметра. В роторную цепь нагрузочной машины включен набор сопротивлений R1 - R9, содержащий три ступени сопротивлений. Коммутация ступеней производится командоконтроллером S7 на 4 позиции (первая позиция соответствует короткому замыканию фаз ротора, четвертая - включению всех трех ступеней сопротивлений). Силовая схема

4.3. Структура программы процедурного типа Схема управления магнитными пускателями позволяет осуществлять процессы ручного и компьютерного управления двигателями М1 и М2. Схема содержит катушки КМ1, КМ2, КМ3, контакты реле К1 и К2 компьютерного управления пуском и переключатели S2, S3, S4. Переключатель S2 («Нагрузка») задает режим работы нагрузочной машины и имеет три позиции. Первая позиция соответствует независимому пуску двигателя М2. Во второй позиции двигатель не работает (за исключением описанного ниже случая). В третьей позиции осуществляется режим подчиненного пуска, когда питание на катушку КМ3 подается через дополнительные замыкающие контакты пускателей КМ1 и КМ2. Такой режим применяется при компьютерном управлении и позволяет включать и выключать нагрузочную машину синхронно с исполнительным двигателем. Силовая схема

4.3. Структура программы процедурного типа Переключатель S3 («Структура») служит для задания структуры компьютерного управления. В положении «1» (показанном на рис.) контакт К1 управляет пуском и остановом системы, а контакт К2 - реверсом двигателя М1. Данная структура позволяет организовать процессы прямого пуска и торможения противовключением исполнительного двигателя. При этом режим нагрузки задается переключателем S2. В положении «2» контакт К1 управляет пуском исполнительного двигателя М1, контакт К2 - пуском нагрузочной машины М2. Такая структура управления позволяет исследовать процессы резкого изменения («наброса») нагрузки. Переключатель S2 в данном случае должен быть переведен в позицию 2 («Выключено»). Силовая схема

4.3. Структура программы процедурного типа Переключатель S4 служит для ручного управления пуском «вперед», «назад», а также реверсом исполнительного двигателя. При компьютерном управлении переключатель переводится в положение «Выключено». Защита силовой части схемы осуществляется автоматическим выключателем KF1, схемы управления пускателями - предохранителем F1. Защита двигателей от перегрузок осуществляется тепловыми реле KT1, KT2. Силовая схема

4.3. Структура программы процедурного типа Схема преобразователя частоты ПЧ содержит силовой управляемый выпрямитель УВ, дроссель L1 и автономный инвертор тока АИТ. Силовой управляемый выпрямитель представляет собой трехфазную мостовую схему на тиристорах V1-V6. Регулирование величины выпрямленного тока в УВ достигается изменением угла управления тиристоров, которое осуществляется системой фазоимпульсного управления (СУВ). К выходу УВ подключен реактор L1, который выполняет функцию сглаживания пульсаций выпрямленного тока. Задачей управления УВ является регулирование тока статора исполнительного двигателя. Помимо УВ в контур тока входят датчик тока ДТ, регулятор тока РТ и система СУВ. Схема преобразователя частоты

4.3. Структура программы процедурного типа Датчик тока представляет собой автономный блок типа S402, осуществляющий усиление и гальваническую развязку напряжения на сопротивлении R д. Регулятор тока выполнен на трех усилителях: интегрирующем - DA1, инвертирующем - DA2 и пропорционально-интегрирующем - DA3. Переменные резисторы R9 и R10 служат для регулировки, соответственно, изодромной постоянной времени и коэффициента передачи пропорциональной части пропорционально-интегрирующего усилителя DA3. На вход регулятора тока подается разность сигналов задания по току от ЦАП и измеренного с помощью датчика тока значения тока на выходе УВ. Выходной сигнал регулятора тока является сигналом задания для системы СУВ. Схема преобразователя частоты

4.3. Структура программы процедурного типа Система управления выпрямителем преобразует сигнал задания в последовательности импульсов управления тиристорами, сдвинутыми по фазе от напряжения сети на электрический угол, пропорциональный данному сигналу. Система полностью взята из ЭКТ2Д. Автономный инвертор тока собран по схеме инвертора с пофазной коммутацией. АИТ содержит мост основных тиристоров (V9 - V12), мост коммутирующих тиристоров (V13 - V18), коммутирующие конденсаторы (С7-С9). Система управления инвертором СУИ осуществляет очередную коммутацию групп вентилей АИТ при изменении уровня входного управляющего сигнала от схемы сопряжения («Линия управления инвертором»). Схема СУИ при таком управлении получена путем введения линии сигнала задания в соответствующую часть схемы СУИ ЭКТ2Д. Схема преобразователя частоты

4.3. Структура программы процедурного типа Система управления выпрямителем преобразует сигнал задания в последовательности импульсов управления тиристорами, сдвинутыми по фазе от напряжения сети на электрический угол, пропорциональный данному сигналу. Система полностью взята из ЭКТ2Д. Автономный инвертор тока собран по схеме инвертора с пофазной коммутацией. АИТ содержит мост основных тиристоров (V9 - V12), мост коммутирующих тиристоров (V13 - V18), коммутирующие конденсаторы (С7-С9). Система управления инвертором СУИ осуществляет очередную коммутацию групп вентилей АИТ при изменении уровня входного управляющего сигнала от схемы сопряжения («Линия управления инвертором»). Схема СУИ при таком управлении получена путем введения линии сигнала задания в соответствующую часть схемы СУИ ЭКТ2Д. Схема преобразователя частоты

4.3. Структура программы процедурного типа Схема сопряжения персонального компьютера с оборудованием экспериментальной установки содержит цифроаналоговый преобразователь (ЦАП), усилитель сигналов компьютерного управления (УСКУ) и схему датчика углового положения ротора исполнительного двигателя (ДУП). Цифроаналоговый преобразователь, используемый в установке взят из лабораторного прибора СУЛ3. Сигнал задания по току исполнительного двигателя в виде восьмиразрядного цифрового кода подается на вход DD1 по восьми линиям данных параллельного порта персонального компьютера LPT1. Сигнал STROB (логическая единица) используется в качестве разрешающего сигнала для считывания входной информации в регистр DD1. ЦАП имеет смещенную характеристику, позволяющую получать на его выходе сигналы разной полярности. При этом цифровому коду «0» соответствует сигнал на выходе -10В., коду «127» - 0В. И коду «256» - +10В. Схема сопряжения

4.3. Структура программы процедурного типа Усилитель сигналов компьютерного управления предназначен для управления магнитными пускателями и формирования сигнала управления линией коммутации АИТ. УСКУ построен на микросхеме DD2 (логический элемент «НЕ»), ключей на транзисторах VT1 - VT3 и реле К1, К2. В качестве входных линий управления используются линии порта LPT1 персонального компьютера AFD (управление коммутациями), INIT (управления реле К1) и SELIN (управления реле К2), состояние которых изменяется компьютерной программой. Высокому и низкому уровням сигнала на линии AFD соответствуют напряжения +12В. и +0,5В. на линии управления коммутациями. Низкому уровню сигнала на линиях INIT и SELIN соответствует включение реле К1 и К2. Схема сопряжения

4.3. Структура программы процедурного типа Схема датчика углового положения ротора исполнительного двигателя состоит из источника и приемника светового излучения (лампы HL1 и фотодиода VD1) и усилителя DA1, охваченного положительной обратной связью. Усилитель работает в режиме насыщения. Если фотодиод VD1 не освещен, напряжение на выходе DA1 12В., а на выходе делителя R5-R6 6В. При попадании светового потока от лампы на фотодиод через прорезь диска датчика на выходе DA1 формируется напряжение +12В., на выходе делителя +6В. Выходной сигнал схемы подается на линию RI (Ring Indicator) последовательного интерфейса персонального компьютера COM2. При этом сигналу 6В. соответствует уровень логического «0», а сигналу +6В. - уровень логической «1» на данной линии. Контроллер интерфейса программируется таким образом, что при каждом переходе сигнала на входе от «0» к «1» генерируется единичное аппаратное прерывание программы. Яркость свечения лампы регулируется переменными сопротивлениями R12 (грубо) и R17 (точно). Схема сопряжения

4.3. Структура программы процедурного типа Компьютерная программа управления установкой Компьютерная программа управления электроприводом экспериментальной установки выполняет следующие основные функции: управление электроприводом в режиме прямых пусков и торможений противовключением с целью отработки заданного количества циклов заданного угла перемещения вала исполнительного двигателя при заданном времени паузы. частотное управление электроприводом с целью отработки заданного количества циклов заданного угла перемещения вала исполнительного двигателя при заданном времени паузы. При этом программа формирует сигналы задания по току исполнительного двигателя и управления коммутациями АИТ, реализуя законы частотно-токового управления. Программным путем решается также задача регулирования скорости вращения на участке установившегося движения.

4.3. Структура программы процедурного типа Программа работает со следующей аппаратурой персонального компьютера. Интервальный таймер, с помощью которого производится отчет промежутков времени. Таймер производит счет импульсов внешнего кварцевого генератора, частота следования которых составляет 1,19 МГц. С приходом очередного импульса значение внутреннего двухбайтного регистра-счетчика таймера уменьшается на единицу. Начальное значение регистра задается программно. При достижении счетчиком нуля происходит прерывание обрабатываемое программой. Контроллер последовательного интерфейса COM2, который программируется таким образом, что при изменении состояния линии RI с «0» к «1», что соответствует повороту диска датчика углового положения на шаг деления (1 ), контроллер вырабатывает прерывание обрабатываемое программой.

4.3. Структура программы процедурного типа Контроллер параллельного интерфейса LPT1, линия данных которого используется программой для передачи кода задания тока, а регистр управления для формирования сигналов по линиям STROB, AFD, INIT, SELIN с целью управления процессом передачи, управления линией коммутации инвертора и магнитными пускателями.

4.3. Структура программы процедурного типа Основные переменные, используемые программой описаны ниже. Угол поворота вала исполнительного двигателя исчисляется в градусах и равен числу прерываний от последовательного порта COM2 за рассматриваемый промежуток времени. В программе используются следующие переменные: count - угол поворота с момента начала движения; count1 - угол поворота с момента последнего определения скорости; count3 - угол поворота с момента очередной коммутации. Под хранение переменных count, count1, count3 выделяется по 4 байта памяти. Таким образом максимальный угол поворота, обслуживаемый программой составляет =

4.3. Структура программы процедурного типа Промежутки времени измеряются в программе числом импульсов кварцевого генератора, который использует таймер. Период следования импульсов - 8, сек. Под хранение переменных, относящихся к промежуткам времени, отводится по 4 байта. Максимальная величина промежутка времени, корректно воспринимаемая программой составляет ( ) 8, сек. 1 час. Переменными такого типа являются: time_out - массив переменных времени для вывода результатов в файл; delta2 - величина промежутка времени от последнего прерывания COM2; delta3 - величина промежутка времени с момента последней коммутации АИТ.

4.3. Структура программы процедурного типа Скорость вращения вала двигателя выражается в программе машинным временем (числом импульсов кварцевого генератора) на 1 поворота вала. Под переменные скорости отводится по 2 байта памяти. Синхронная скорость двигателя 1500 об./мин. представляется значением 139. Минимальная скорость различаемая программой соответствует коду = и равна примерно 3 об./мин. Программой используются следующие переменные, характеризующие скорость: speed - текущая скорость, вычисляемая через каждые 5 поворота вала; speed_ref - заданная скорость на участке установившегося движения; speed_break - скорость, при которой происходит отключение электропривода; speed_0 - скорость, при которой производится перевод двигателя в режим торможения при регулировании скорости и др.

4.3. Структура программы процедурного типа Частота тока ротора представляется временем изменения фазы тока ротора на 1. В программе используются следующие переменные: rotor_freq - текущая частота тока ротора при пуске; rotor_freq_start - частота тока ротора при пуске; rotor_freq_stop - частота тока ротора при торможении; rotor_freq_cont - частота тока ротора на участке установившегося движения; Значения rotor_freq_start, rotor_freq_stop, rotor_freq_cont вычисляются исходя из заданных величин пускового и тормозного абсолютного скольжения п, т, у. Величина тока статора исполнительного двигателя кодируется однобайтным значением. Цифровому коду 0 соответствует задание по току статора 2 I н = 22 А, коду задание 0А. и коду задание 2 I н = +22 А. Код задания по току отражен в переменной current_code ( локальная переменная в функции current).

4.3. Структура программы процедурного типа Программное управление исполнительным двигателем обеспечивает пуск и торможение двигателя с постоянными пусковым и тормозным моментами, соответствующими значениями заданных токов статора и частот тока ротора при пуске и торможении. Управление коммутациями АИТ производится с использованием ранее полученных алгоритмов.

4.3. Структура программы процедурного типа Помимо функций управления электроприводом в циклическом режиме программа выполняет ряд дополнительных функций среди которых: Тестирование работы оборудования; Тестовый запуск системы с целью определения значения угла поворота вала двигателя, достижение которого соответствует началу торможения; Ввод исходных данных и их сохранение в файле на жестком диске ПК; Вывод и сохранение данных о процессе отработки заданного движения ( последовательностей значений угла поворота и текущего времени) в файле на жестком диске ПК. (Дальнейшая обработка экспериментальных данных и вывод графиков изменения угла поворота и скорости производится в среде Matlab).

4.3. Структура программы процедурного типа Программа управления экспериментальной установкой #include // задание констант #define INTR_com2 0x0B #define INTR_timer 0x08 #define com2 0x2f8 #define timer_data 0x40 #define timer_cont 0x43

4.3. Структура программы процедурного типа //прототипы функций void interrupt hand_com2(__CPPARGS); void interrupt hand_timer(__CPPARGS); void sensor_ready(float,void interrupt (*)(__CPPARGS), void interrupt (*)(__CPPARGS)); void sensor_return(void); int question(char s[20] ); int one_test_starter(void); int test_starter(void); int test_sensor(void); int test(void); int ndinp(void); int data_out(void); int com_cont(unsigned, unsigned, int); int speed_define(void); void initial(void); void current (char);

4.3. Структура программы процедурного типа // прототипы функций void current (char); void revers_to_move(unsigned); int speed_control(int); int first_start(unsigned); int first_start_freq(unsigned); int work_in_circle(unsigned,unsigned,unsigned); int work_in_circle_freq(unsigned,unsigned,unsigned); int work(int); inline void start_to(void) { outp(0x37A,(inp(0x37A) | 0x02) & 0xF7);} inline void start_back(void) { outp(0x37A,inp(0x37A) & 0xF5); } inline void stop(void) { outp(0x37A,inp(0x37A) | 0x0a); }

4.3. Структура программы процедурного типа // глобальные переменные char current_start, current_stop; unsigned long count, count1, count3; unsigned timer, timer1, timer2, timer3; unsigned clock1, clock2, clock3, clock_nd; unsigned num; unsigned speed, speed_max, speed_min, speed_ref; unsigned rotor_freq_start, rotor_freq_stop,rotor_freq_cont; unsigned long count_out[400]; unsigned long time_out[400]; unsigned long k1,k2,k3,k4; unsigned num_end = 400; float _dt = 0.055; int mask_old; unsigned rbr,lcr,ier,mcr,msr; void interrupt ( *oldhand_com2)(__CPPARGS); void interrupt ( *oldhand_timer)(__CPPARGS);

4.3. Структура программы процедурного типа // int main(void) { stop(); printf("\n ПРОГРАММА УПРАВЛЕНИЯ ЭЛЕКТРОПРИВОДОМ"); printf("\n Подготовьте все системы к работе и нажмите любую клавишу"); getch(); char var = '6'; while (var!='5') { clrscr(); printf("\n \n 1) Ввод данных \n 2) Тест оборудования "); printf("\n 3) Прямые пуски \n 4) Частотные пуски \n 5) Выход"); printf("\n \n Выберите вариант"); var = getch();

4.3. Структура программы процедурного типа switch (var) { case '1': ndinp(); break;ndinp() case '2': test(); break;test() case '3': work(0); break;work(0) case '4': work(1); break;work(1) case '5': if (!question("\n \n Вы уверены? (y/n)")) var = '6';question default: break; } return 0; }

4.3. Структура программы процедурного типа / /-- Ввод начальных данных int ndinp(void) { FILE *stream; char q = 'n'; float data[13]; while (q!='y'& q!='Y') { clrscr(); printf("\n Число циклов: "); scanf("%f",&data[0]); printf("\n Угол поворота в радианах:"); scanf("%f",&data[1]); printf("\n Время паузы:"); scanf("%f",&data[2]); printf("\n Абсолютное скольжение при пуске:"); scanf("%f",&data[3]);

4.3. Структура программы процедурного типа printf("\n Абсолютное скольжение при торможении:"); scanf("%f",&data[4]); printf("\n Абсолютное скольжение при уст.движении:"); scanf("%f",&data[5]); printf("\n Скорость задания:"); scanf("%f",&data[6]); printf("\n Скорость отключения:"); scanf("%f",&data[7]); printf("\n Интервал регулирования,(о.е.) минимум:"); scanf("%f",&data[8]); printf("\n Интервал регулирования,(о.е.) максимум:"); scanf("%f",&data[9]); printf("\n Пусковой ток (о.е., 0...2):"); scanf("%f",&data[10]);

4.3. Структура программы процедурного типа printf("\n Тормозной ток (о.е., 0...2):"); scanf("%f",&data[11]); printf("Ввести? (y/n)"); q = getch(); } stream = fopen("ndata.sav", "wb"); fwrite(&data, sizeof(data),1,stream); fclose(stream); return 0; }

4.3. Структура программы процедурного типа //-- Обработчик прерываний COM2 - датчика углового положения void interrupt hand_com2(__CPPARGS) { count++; count1++; count3++; outp(timer_cont,0); clock2 = inp(timer_data) + inp(timer_data)

4.3. Структура программы процедурного типа //-- Установка обработчиков прерываний и инициализация таймера void sensor_ready(float dt, void interrupt (*hand_com2)(__CPPARGS), void interrupt (*hand_timer) (__CPPARGS)) { clock_nd = (unsigned) (65536*(dt/ )); unsigned char clock_h = (unsigned char) (clock_nd >> 8); unsigned char clock_l = (unsigned char) (clock_nd & 0x00ff); disable(); // Сохранение старой маски прерываний и установка новой mask_old = inp(0x21); outp(0x21,0xF6); // Сохранение регистров COM2 rbr=inp(com2); lcr=inp(com2+3); ier=inp(com2+1); mcr=inp(com2+4);

4.3. Структура программы процедурного типа msr=inp(com2+6); // Программирование COM2 outp(com2+1,8); outp(com2+4,8); _AH = inp(com2+6); // Программирование таймера outp(timer_cont,0x34); outp(timer_data,clock_l); outp(timer_data,clock_h); // Сохранение старых векторов прерываний и установка новых oldhand_com2 = getvect(INTR_com2); oldhand_timer = getvect(INTR_timer); setvect(INTR_com2, hand_com2); setvect(INTR_timer, hand_timer); enable(); }

4.3. Структура программы процедурного типа //-- Восстановление обработчиков прерываний и параметров таймера void sensor_return(void) { // Восстановление параметров COM2 outp(com2,rbr); outp(com2+3,lcr); outp(com2+1,ier); outp(com2+4,mcr); outp(com2+6,msr); // Восстановление параметров таймера outp(timer_cont,0x36); outp(timer_data,0);

4.3. Структура программы процедурного типа // Восстановление векторов прерываний setvect(INTR_com2, oldhand_com2); setvect(INTR_timer, oldhand_timer); // Восстановление маски прерываний disable(); outp(0x21,mask_old); enable(); }

4.3. Структура программы процедурного типа //-- «Вопрос» int question(char s[20] ) { printf(s); char q = getch(); if (q == 'y' | q == 'Y') return 1; else return 0; }

4.3. Структура программы процедурного типа //-- Единичный тест работы системы пускателей int one_test_starter(void) { printf("\n Пуск вперед (пуск АИР), нажмите любую клавишу"); getch(); start_to(); printf("\n Пуск назад (пуск МТF), нажмите любую клавишу"); getch(); start_back(); printf("\n Останов, нажмите любую клавишу"); getch(); stop(); return(question("\n \n Все нормально? (y/n)")); }

4.3. Структура программы процедурного типа //-- Полный тест системы пускателей int test_starter(void) { clrscr(); printf("\n ТЕСТ ПУСКАТЕЛЕЙ"); stop(); printf("\n \n Убедитесь в правильности соединений"); printf("\n Включите СУЛ и щит управления"); printf("\n Подайте питание на схему 220 в. щита управления"); printf("\n\n Проверка пускателя АИР...\n Нажмите любую клавишу"); getch();

4.3. Структура программы процедурного типа if (one_test_starter() == 0) return 0;one_test_starter() printf("\n\n Проверка совместной работы пускателей..."); printf("\n Включите режим подчиненного пуска. \n Нажмите любую клавишу"); getch(); if (one_test_starter() == 0) return 0;one_test_starter() printf("\n\n Проверка раздельной работы пускателей..."); printf("\n Выключите режим подчиненного пуска,"); printf("\n включите режим раздельного управления \n Нажмите любую клавишу"); getch(); if (one_test_starter() == 0) return 0;one_test_starter() return 1; }

4.3. Структура программы процедурного типа //-- Тест системы датчика углового положения int test_sensor(void) { short int i=0; unsigned clock_h, clock_l, clock; float time, speed; clrscr(); printf("\n ТЕСТ ДАТЧИКА СКОРОСТИ"); printf("\n \n Запустите двигатель на холостом ходу."); printf("\n С помощью осциллографа и показаний скорости на экране монитора"); printf("\n добейтесь правильной работы датчика, регулируя напряжение на лампе."); printf("\n Если на экране сообщается, что скорость равна нулю,"); printf("\n датчик однозначно работает неверно и по достижении индексом значения 100"); printf("\n тест будет завершен. В противном случае для остановки теста"); printf("\n выключите двигатель");

4.3. Структура программы процедурного типа printf(" \n \n Для запуска теста нажмите любую клавишу"); getch(); sensor_ready sensor_ready( ,hand_com2,hand_timer); count = 0; timer = 0; while (i < 100) { while (count < 360 & timer < 5); disable(); outp(timer_cont,0); clock_l= (unsigned)inp(timer_data); clock_h= (unsigned)inp(timer_data); clock = (clock_h

4.3. Структура программы процедурного типа printf(" \n Скорость %f об/мин, %d",speed,i); i = i+timer; timer = 0; count = 0; enable(); // Перепрограммирование таймера outp(timer_cont,0x34); outp(timer_data,0); enable(); } sensor_return(); clrscr(); return (question("Все нормально? y/n")); }

4.3. Структура программы процедурного типа //-- Тестирование оборудования int test(void) { printf("\n ПРОГРАММА ТЕСТИРОВАНИЯ ОБОРУДОВАНИЯ"); if (test_starter() == 0)test_starter() { printf("\n Ремонтируйте"); delay(1000); } if (test_sensor() == 0)test_sensor() { printf("\n Ремонтируйте"); delay(1000); return 1; } printf("\n Тест пройден"); getch(); return 0;return 0 }

4.3. Структура программы процедурного типа //-- Запоминание текущих данных (времени и угла поворота) int data_out(void) { if (num

4.3. Структура программы процедурного типа //-- Обслуживание коммутаций АИТ int com_cont(unsigned rotor_freq,unsigned angle_end,int reg) { unsigned long delta2, delta3; unsigned clock, angle; outp(timer_cont,0); clock = inp(timer_data) + inp(timer_data)

4.3. Структура программы процедурного типа if (angle>angle_end) { outp(0x37A,inp(0x37A)^4); count3 = 0; timer3 = 0; clock3 = clock; return 0; } return 1; }

4.3. Структура программы процедурного типа //-- Определение скорости вращения вала двигателя int speed_define(void) { if (count1 > 5) { speed = (timer1*clock_nd - clock2 + clock1)/count1; clock1 = clock2; count1 = 0; timer1 = 0; return 0; } return 1; }

4.3. Структура программы процедурного типа //-- Инициализация системы void initial(void) { timer = 0; timer1 = 0; timer2 = 0; timer3 = 0; count = 0; count1 = 0; count3 = 0; sensor_ready(_dt, hand_com2, hand_timer); clock1 = clock_nd; clock2 = clock_nd; clock3 = clock_nd; speed =0xffff; num = 0; time_out[0] = 0; count_out[0] = 0; }

4.3. Структура программы процедурного типа //-- Задание величины тока статора void current (char current_code) { outp(0x37A,inp(0x37A) & 0xFE); outp(0x378,~current_code); outp(0x37A,inp(0x37A) | 0x01); } //-- «Быстрый» переход в двигательный режим void revers_to_move(unsigned rotor_freq) { while (com_cont(rotor_freq,200,1)) if (!speed_define()) data_out(); while (com_cont(rotor_freq,200,1)) if (!speed_define()) data_out(); while (com_cont(rotor_freq,200,1)) if (!speed_define()) data_out(); }

4.3. Структура программы процедурного типа //-- Регулирование скорости (частотные пуски) int speed_control(int reg) { if (speed < speed_max) { current(current_stop); if (reg==1) { while (com_cont(rotor_freq_stop,1800,0)) if (!speed_define()) data_out(); } else while (com_cont(rotor_freq_stop,600,0)) if (!speed_define()) data_out(); return 0; }

4.3. Структура программы процедурного типа if (speed > speed_min) { current(current_start); if (reg==0) revers_to_move(rotor_freq_start); else while (com_cont(rotor_freq_start,600,1)) if (!speed_define()) data_out(); return 1; }

4.3. Структура программы процедурного типа if (speed < speed_0) { current((char)(k2/speed-k1)); if (reg==1) { while (com_cont(rotor_freq_cont,1800,0)) if (!speed_define()) data_out(); } else while (com_cont(rotor_freq_cont,600,0)) if (!speed_define()) data_out(); return 0; }

4.3. Структура программы процедурного типа current((char)(k3 - k4/speed)); if (reg==0) revers_to_move(rotor_freq_cont); else while (com_cont(rotor_freq_cont,600,1)) if (!speed_define()) data_out(); return 1; }

4.3. Структура программы процедурного типа //-- Первый запуск - для определения момента начала торможения (прямые пуски) int first_start (unsigned speed_break) { initial(); start_to(); while(speed>speed_min) { speed_define();speed_define() if (timer1 >=10){ stop; sensor_return(); return 1;}sensor_return() } data_out();data_out( start_back(); while(speed

4.3. Структура программы процедурного типа //-- Первый запуск - для определения момента начала торможения (частотные пуски) int first_start_freq(unsigned speed_break) { initial();initial() start_to(); current current(current_start); while (com_cont(rotor_freq_start,600,1));com_cont while (com_cont(rotor_freq_start,300,1));com_cont if (count==0) {current(127); stop(); sensor_return(); return 1;}currentsensor_return() while (speed > speed_min) while (com_cont(rotor_freq_start,600,1)) speed_define();speed_define() data_out(); while (com_cont(rotor_freq_start,1800,1));com_cont current(current_stop);current

4.3. Структура программы процедурного типа while (speed

4.3. Структура программы процедурного типа //-- Работа в цикле (прямые пуски) int work_in_circle (unsigned count_befor, unsigned timer_pause,unsigned speed_break) { initial();initial() start_to(); while(count < count_befor) { if (!speed_define()) data_out();speed_define()data_out() if (timer1 >=100){ stop(); sensor_return(); return 1;}sensor_return() } start_back(); while(speed

4.3. Структура программы процедурного типа //--Работа в цикле (частотные пуски) int work_in_circle_freq(unsigned count_befor, unsigned timer_pause, unsigned speed_break) { int reg=1; initial(); start_to(); current(current_start);current data_out data_out(); while (com_cont(rotor_freq_start,600,1));com_cont data_out();data_out() while (com_cont(rotor_freq_start,300,1))com_cont if (!speed_define()) data_out();speed_definedata_ou if (count==0) {current(127); stop(); sensor_return(); return 1;}currensensor_return

4.3. Структура программы процедурного типа while (speed > speed_min) while (com_cont(rotor_freq_start,600,1))com_cont if (!speed_define()) data_out();speed_definedata_out(); while (count < count_befor) reg = speed_control(reg);speed_control current(current_stop); while (com_cont(rotor_freq_cont,1800,0))com_cont if (!speed_define()) data_out();speed_define(data_out() while (speed

4.3. Структура программы процедурного типа timer3 = 0; while (!timer3); current(127); stop(); while (timer3

4.3. Структура программы процедурного типа int work(int type_of_start) { FILE *stream; int h,i; unsigned long count_all, count_start, count_stop,count_befor,time_start, time_stop; unsigned timer_pause, speed_break; float data[10], v_break; stream = fopen("ndata.sav", "rb"); if (stream == NULL) { clrscr(); printf("Файл исходных данных не найден. Нажмите любую клавишу"); getch(); ndinp(); return 0; }

4.3. Структура программы процедурного типа fread(&data, sizeof(data),1,stream); fclose(stream); h = (int)data[0]; v_break = data[6]; count_all = (unsigned)(data[1]*57.3); timer_pause = (unsigned)(data[2]/_dt); rotor_freq_start = (unsigned)(66/data[3]); rotor_freq_stop = (unsigned)(66/data[4]); rotor_freq_cont = (unsigned)(66/data[5]); speed_ref = (unsigned)(20735/data[6]); speed_break = (unsigned)(20735/data[7]); speed_min = (unsigned)(20735/(data[6]*data[8])); speed_max = (unsigned)(20735/(data[6]*data[9])); speed_0 = (unsigned)(20735/(data[6]*(data[8]+data[9])/2)); ; current_start = (char)(data[10]*64+127);

4.3. Структура программы процедурного типа current_stop = (char)(data[11]*64+127); k2 = (unsigned long)speed_max*speed_0*(current_start-127)/(speed_0- speed_max); k1 = k2/speed_0-127; k4 = (unsigned long)speed_min*speed_0*(current_start-127)/(speed_min- speed_0); k3 = k4/speed_0+127; clrscr(); printf("\n \n Данные величины будут использованы при работе"); printf("\n \n Число циклов: %d",h); printf("\n Угол поворота в радианах: %f",data[1]); printf("\n Время паузы: %f",data[2]);

4.3. Структура программы процедурного типа if (type_of_start) { printf("\n Абсолютное скольжение при пуске: %f",data[3]); printf("\n Абсолютное скольжение при торможении: %f",data[4]); printf("\n Абсолютное скольжение при уст. движении: %f",data[5]); printf("\n Скорость задания (рад./сек.: %f",data[6]); printf("\n Скорость отключения (рад./сек.: %f",data[7]); printf("\n Интервал регулирования (о.е.): %f - %f",data[8],data[9]); printf("\n Пусковой ток (о.е.): %f", data[10]); printf("\n Тормозной ток (о.е.): %f", data[11]); } if (!question("\n \n Вы согласны? (y/n)")) { ndinp();ndinp() return 0; }

4.3. Структура программы процедурного типа char answ = '3'; while (answ == '3') { clrscr(); printf("\n \n Сейчас будет произведен пробный запуск с целью определения"); printf("\n момента начала торможения"); printf("\n \n Нажмите любую клавишу"); getch(); if (type_of_start) { if (first_start_freq(speed_break)==1) { printf("\n \n Запуск не состоялся"); getch(); return 1;}first_start_freq } else { if (first_start(speed_break)==1) { printf("\n \n Запуск не состоялся"); getch(); return 1;}first_start }

4.3. Структура программы процедурного типа time_start = (time_out[1] - time_out[0]); time_stop = (time_out[2] - time_out[1]); count_start= (count_out[1] - count_out[0]); count_stop = (count_out[2] - count_out[1]); clrscr(); printf("\n \n Время пуска - %f сек",(float)time_start* ); printf("\n Угол поворота при пуске - %f рад. или %d град.",(float)count_start/57.3,count_start); printf("\n \n Время торможения - %f сек",(float)time_stop* ); printf("\n Угол поворота при торможении - %f рад. ",(float)count_stop/57.3); printf(" или %d град.",count_stop);

4.3. Структура программы процедурного типа count_befor = count_all - count_stop; if ((float)(count_befor/57.3) - (float)(count_start/57.3) < 0) { printf("\n \n Выполнить данное задание программа не в состоянии,"); printf("\n так как заданный угол поворота %f рад. ",(float)count_all/57.3); printf("\n меньше суммы углов поворота при пуске и торможении"); printf(" %f + %f ",(float)count_start/57.3,(float)count_stop/57.3); printf("= %f рад.",(float)(count_start+count_stop)/57.3); getch(); return 1; }

4.3. Структура программы процедурного типа printf("\n \n \n Таким образом перед торможением двигатель должен отработать"); printf("\n %f - %f ", (float)count_all/57.3,(float)count_stop/57.3); printf(" = %f рад. или %u град.", (float)count_befor/57.3,count_befor); printf("\n \n Вы согласны с приведенными параметрами движения ?"); printf("\n 1 - да, продолжить, \n 2 - нет, выйти из программы работы"); printf("\n 3 - нет, изменить параметр v для минимизации выбега");

4.3. Структура программы процедурного типа answ = getch(); if (answ=='3') { clrscr(); printf("\n Предыдущее значение скорости отключения v = %f рад./сек.",v_break); printf("\n \n Для минимизации выбега измените v"); printf("\n \n v = "); scanf("%f",&v_break); speed_break = (unsigned)(20735/v_break); } else if (answ!='1') return 0; }

4.3. Структура программы процедурного типа printf("\n \n Для выполнения задания нажмите любую клавишу"); getch(); for (i=0;i < h;i++) { clrscr(); printf("\n \n Пуск номер %d:",i+1); printf("\n Задание - %f рад. или %d град.",data[1],count_all); if (type_of_start) { if (work_in_circle_freq(count_befor,timer_pause,speed_break)==1)work_in_circle_freq { printf("\n \n Запуск не состоялся"); getch(); return 1; } } else { if (work_in_circle_freq(count_befor,timer_pause,speed_break)==1)work_in_circle_freq { printf("\n \n Запуск не состоялся"); getch(); return 1; } }

4.3. Структура программы процедурного типа getch(); stream = fopen("outdata.sav", "wb"); fwrite(&num, sizeof(num),1,stream); fwrite(&time_out, sizeof(time_out),1,stream); fwrite(&count_out, sizeof(count_out),1,stream); fclose(stream); return 0; }

4.3. Структура программы процедурного типа main ndinp test work test_starter test_sensor first_start first_start_freq work_in_circle work_in_circle_freq sensor_ready sensor_return initial speed_control current com_cont speed_define data_out

4.3. Структура программы процедурного типа Программа вывода экспериментальных данных (Язык Matlab 4.0) % Вывод графиков изменения угла поворота и скорости % вала исполнительного двигателя во времени fid = fopen('outdata.sav','r'); [size, count] = fread(fid,1,'int16'); [time, count] = fread(fid,size,'ulong'); [angle, count] = fread(fid,size,'ulong'); fclose(fid); time = time* ; % перевод в сек. angle= angle/57.3; % перевод в рад. speed = diff(angle)./diff(time); % скорость for i=1:1:(length(time)-1) time_s(i) = (time(i+1)+time(i))/2; %"усредненное" время end figure plot(time, angle),grid, xlabel('time'), ylabel('angle') figure plot(time_s, speed),grid, xlabel('time'), ylabel('speed')