Практична №3
Тема: Декомпозиція систем та структурування
Мета: На прикладі простого пристрою навчитися проводити структурування та декомпозицію систем.
Встп
Теорія систем застосовується у різноманітних аспектах нашого життя. Для розуміння роботи тої чи іншої системи необхідно вміти розбити її на складові елементи та розробити її структурну та функціональні схеми. Підсистема – це множина елементів і зв’язків з основної системи, які можуть розглядатися як один елемент на структурній або функціональній схемі.
В лабораторній роботі досліджується пристрій, який дозволяє з дистанційного пульта включити двигун в прямому або реверсному режимі з різною швидкістю. Для розробки даної системи на початку необхідно визначити її функції та представити у вигляді підсистем. Функціональну схему показано на рис.1.

Рис. 1. Функціональна схема системи
Функції системи реалізуються оптимальною структурою за прийнятими критеріями оптимальності, які з практичної точки зору представляються в спрощеному вигляді як лінійне рівняння з локальних критеріїв: ціна, собівартість, швидкодія, зручність користування, простота рішення, універсальність, надійність, чутливість, тощо. В нашому прикладі основним критерієм є простота, тобто, мінімальна кількість елементів, що передбачає чітку структурованість і зрозумілість. Отже, дану функцінальну схему можна реалізувати наступною структурою системи:
Рис. 2. Структурна схема системи, що досліджується.
Останній крок створення системи оснований на стандартних рішеннях, які складають досвід проектувальника. Стандартне рішення – це таке рішення, яке виявилися найкрашим з практичної точки зору при реалізації. Стандартне рішення не гарантує оптимальності по заданому критерію, і тому необхідно враховувати інші можливі рішення.
Для коректного проектування необхідно представити функціонування системи в самих дрібних деталях, які в решті решт можуть вплинути на остаточне рішення, яке приймає проектувальник. Наприклад, необхідно врахувати, що на інфрачервоний датчик можуть впливати небажані випадкові сигнали або інтенсивний постійний фон. Для цього в систему введений стабілізатор, який примушує підсилювач працювати на грані спрацьовування одиниці.
Наступна деталь стосується програмування мікроконтроллера. Якщо для програмування необхідно буде кожний раз витягати мікросхему, то це приведе до її руйнування. Тому краще програмувати мікроконтроллер не витягаючи його з приладу. Оскільки для програмування необхідні ніжки PA5– PA6, то щоб не заважати програматору, їх бажано не задіювати в основній схемі або приєднувати через високоомні резистори. Тому остаточна електрична схема представлена на рис.3:
Рис. 3. Електрична схема системи.
В звіті до цієї лаборатоної роботи необхідно розбити вказану електричну схему на підсистеми та пояснити алгоритм її функціонування.
Опис електричної схеми
Структура схеми представлена на рис.2. Інфрачервоний датчик представлено фотодіодом D1. Підсилювач представлений транзисторами T1 – T2. Напруга на базі транзистора T1 приблизно дорівнює +0.6V, і це знчення підтримується напругою на стабілізуючому конденсаторі C1. Для відокремлення постійної складової напруги між датчиком та підсилювачем введено конденсатор C2. Алгоритм стабілізації перевіряє напругу на виході підсилювача. Якщо ця напруга більше заданого значення, то контроллер збільшує напругу на конденсаторі C1 через ніжку PA2.
Схема управління мотором представлена транзисторами T3 – T6. Транзистори T3 – T4 відкриваються одиницею, а T5 – T6 відкриваються нулем. Таким чином, існує безпечна комбінація значень на ніжках PA0 – PA7, при якій всі транзистори закриті: 00010010.
Для прокрутки мотора вправо необхідно подавати напругу на котушки L1 та L2 згідно діаграми, що представлена на рис.4. Для прокрутки мотора в зворотню сторону необхідно на діаграмі поміняти місцями надписи L1 та L2.
Для контролю роботи схеми виведено два сигнала: PA0 та PB6, які можна ввести в комп’ютер через LPT– порт. На PA0 видаються одинокі імпульси в кінці циклу вводу одного біта, а на PB6 видається введене значення – 0 або 1. До PB6 також приєднаний світлодіод.

Підсистема прокрутки мотора
Для подачі напруг на котушки L1, L2 згідно з діаграмою рис.4 можна користуватися наступною підпрограмою:
Motor1:
ld A,#255 ; кількість обертів на одну прокрутку
L_MOT1:
push A
ld A,#%10010000
call PORT_OUT
ld A,#%10011010
call PORT_OUT
ld A,#%00001010
call PORT_OUT
ld A,#%00000000
call PORT_OUT
pop A
dec A
jrne L_MOT1
ld A,#%00010010 ; Безпечний стан – всі транзистори закриті
call PORT_OUT
ret
Дана підпрограма використовує підпрограму PORT_OUT для виводу стнів на ніжки порту PA0 – PA7 та затримку. Від часу затримки залежить швидкість обертання:
PORT_OUT:
ld $0,A
ld A,#3
L_2:
push A
ld A,#180
L_1:
bset $2e,#6 ; watchdog reset (скинути сторожовий таймер)
dec A
jrne L_1
pop A
dec A
jrne L_2
ret
В звортньому напрямку мотор можна прокрутити наступною програмою:

Motor2:
ld A,#255
L_MOT2:
push A
ld A,#%00000000
call PORT_OUT
ld A,#%00001010
call PORT_OUT
ld A,#%10011010
call PORT_OUT
ld A,#%10010000
call PORT_OUT
pop A
dec A
jrne L_MOT2

ld A,#%00010010 ; ; Безпечний стан – всі транзистори закриті
call PORT_OUT
ret
Рис.4. Діаграма напруг на котушках синхронного мотора.
Отже, як видно з програми, одна прокрутка мотора складає рівно 255 обертів, після чого мотор зупиняється.
Підсистема прийняття сигналу
Прийняття інфрачервоного сигналу забезпечується фотодіодом D1. Для підсилення сигналу використовуються транзистори T1, T2. Дане з’єднання транзисторів забезпечує високий коефіцієнт підсилення, але є не стійким, оскільки вимагає підтримки напруги на базі T1 в дуже вузьких межах біля +0.6V. Для підтримки такого режиму роботи транзистора існує конденсатор C1, який забезпечує необхідну напругу. Цей конденсатор заряджається від ніжки PA2, на яку подаюся широтно-модульовані імпульси. Підсилені сигнали з фотодіоду вводяться в контроллер через ніжку PB0. Критерієм вірної роботи підсистеми прийняття інфрачервоного сигналу є середня напруга на ніжці PB0, яка приблизно дорівнює +3V. Таким чином, можна вважати, якщо напруга на PB0 менше +2.9V, то сприймається інфрачервоний імпульс, тобто транзистори T1, T2 відкриваються. Якщо напруга на PB0 стає більше +3V, або менше +3V, то система збільшує або зменшує ширину імпульсів на PA2, що приводить до збільшення або зменшення напруги на стабілізаційному конденсаторі C1. Завдяки такому регулюванню система не є чутливою до змін параметрів резисторів та конденсаторів вказаних на схемі.
Для реалізації алгоритму прийняття інфрачервоного сигналу можна скористатись наступним фрагментом:
;======================================
READ_SIGNAL: ; Початок циклу отримання наступного біту даних
LD A,$8B ; Помістити в A відкоректоване значення напруги
ld $18,A ; Задати цю напругу на PA2 шириною імпульсу ШИМ
LD A,#3 ; завантажити маску дозволу зміни значення ШИМ
LD $21,A ; дозвіл на зміну значення ШИМ
M3:
bset $2e,#6 ; watchdog reset (скинути сторожовий таймер)
btjf $08,#0,M3 ; Чекаємо переповнення Lite Timer 2
ld A,$08 ; для рівномірномірності часових проміжків.
call READ_PB0 ; Вимірюємо напругу на ніжці PB0 (буде в регістрі A).
;======================================
cp A,#154 ; Поріг між <1> і <0> - введений біт буде у прапорці переносу.
rlc $80 ; Посунути біт переносу в молодший біт
rlc $81 ; і всі введені біти зсунути на 1 біт вліво
rlc $82 ; через прапорець переносу.
rlc $83
rlc $84
rlc $85
rlc $86
rlc $87
;======================================
BSET $0,#0 ; Встановити біт PA0 для відладки програми
ld A,$80
rrc A
rrc A
rrc A ; Перемістити останній введений біт на ніжку PB6
and A,#%01000000 ; Маска ніжок порту для виводу на світлодіод
Ld $3,A ; Вивести імпульс на світлодіод
BRES $0,#0 ; Скинути біт PA0 для відладки програми
;======================================
tnz $80 ; якщо два останніх прийнятиих байти ($80–$81) нульові,
jrne CONTINUE
tnz $81
jrne CONTINUE
tnz $82 ; а $82 не нульовий,
jreq CONTINUE ; то почалася пауза між пакетами імпульсів.
;======================================
call TESTING ; Під час паузи можна порівняти пакет з оригіналом
;======================================
CONTINUE: ; Продовжити прийом коду
Ld A,$35 ; Взяти останнє прийняте значення напруги
cp A,#160 ; Порівняти його з нормою (3V),
jrc DEC_SENSOR ; і перейти, якщо цей рівень завищений;
jrne INC_SENSOR ; і перейти, якщо цей рівень занижений;
jp READ_SIGNAL ; інакше прочитати наступний біт даних.
INC_SENSOR: ; Підвищити напругу на C1:
inc $8B ; Збільшити старшу частину напруги C1,
jrne READ_SIGNAL ; і задати цю напругу на PA2.
dec $8B ; Напруга досягла максимального значення,
jp READ_SIGNAL ; прочитати новий біт.
DEC_SENSOR: ; Зменшити напругу на С1:
tnz $8B ; Якщо напруга нульова,
jreq READ_SIGNAL ; то зменшення напруги неможливо.
dec $8B ; Зменшити старшу частину напруги C1
jp READ_SIGNAL ; і прочитати новий біт.
;----------------- Підпрограма для читання значення напруги на ніжці PB0:
READ_PB0:
bset $2e,#6 ; watchdog reset (скинути сторожовий таймер)
LD A,#%01100000 ; Завантажити в A маску настройки АЦП для PB1
LD $34,A ; Записати її в регістр, що дає дозвіл аналогового вводу з ніжки PB0
M2: BTJF $34,#7,M2 ; Переписати біт EOC в CF і перейти на M2, якщо він нульовий.
LD A,$35 ; Зчитати в регістр A отримане значення.
ret
Початкове налаштування системи
Для правильної роботи системи її необхідно привести в правильний початковий стан. Під початковим станом будемо розуміти настройку ніжок контроллера та регістри ШИМ, яка здійснюється наступною програмою:
main:
RSP
bset $2e,#6 ; скинути сторожовий таймер
ld A,#%10011111 ; не задіяні ніжки PA5 – PA6.
ld $1,A
ld $2,A
; x--xx-x-
ld A,#%00010010 ; Безпечний стан ніжок при зупиненому моторі
ld $0,A

ld A,#%01000000 ; Ніжка PB6 буде використовуватись для індикації
ld $4,A
ld $5,A
ld $3,A
clr $36 ; Для швидкої роботи АЦП
;-------------------------------------------------------------------------
LD A,#%00010000 ; завантажити маску джерела таймеру
LD $0D,A ; джерело таймеру від тактової частоти
LD A,#%00000001 ; завантажити маску дозволу ШИМ
LD $12,A ; дозвіл ШИМ на PA2.

LD A,#%00001111 ; CNTR1 = 0..255:
LD $10,A ; початкове значення старшої частини лічильника
LD $17,A ; дорівнює старшій частині регістра порівняння
CLR $11 ; Молодша частина лічильника починається з <0>.
;-------------------------------------------------------------------------
clr $08 ; Онулити регістр управління таймером
ld A,#230 ; Початкове значення Lite-Timer2 після переповнення.
ld $09,A

Підсистема порівняння
Для порівняння необхідно вибрати момент, коли закінчилась послідовність імпульсів, тобто, почалася тривала послідовність нулів. Байти починаються з кінця: $81..$87. В кожному байті останній прийнятий біт – молодший. Для отримання своїх даних від пульта використовуйте програму OSC.EXE.
data1 dc.b 0,%00111111,%00001110,%11111000,%11110001,%11000000,%00001111
data2 dc.b 0,%11100111,%00011000,%00000111,%11100011,%01111100,%11100000
;====================================================================
TESTING: ; Блок порівняння з взірцем
BUTTON1:
ld X,#6 ; 6 байт
clr $8C ; онулити кількість розбіжностей
L_TEST1:
ld A,($81,X) ; читання комірок $87..$82,
xor A,(data1,X) ; порівняння з data1+6..data1+1
call COUNT_8С ; підрахувати кількість розбіжностей і зберегти у $8C
dec X
jrne L_TEST1
ld A,#5 ; рівень випадкових помилок
cp A,$8C
jrc BUTTON2
ld A,#%01000000
ld $3,A
call Motor1
call CLEAR
ret
;======================
BUTTON2:
ld X,#6
clr $8C
L_TEST2:
ld A,($81,X) ; $87..$82
xor A,(data2,X) ; data1+6..data1+1
call COUNT_8С ; підрахувати кількість розбіжностей і зберегти у $8C
dec X
jrne L_TEST2
ld A,#5 ; рівень випадкових помилок
cp A,$8C
jrc BUTTON3
ld A,#%01000000
ld $3,A
call Motor2
call CLEAR
ret
BUTTON3:
Ret
;=========================================
COUNT_8С: ; підрахувати кількість розбіжностей і зберегти у $8C
bset $2e,#6 ; watchdog reset (скинути сторожовий таймер)
ld $80,A
ld A,#8
L_COUNT1:
btjf $80,#0,C_COUNT2
inc $8C
C_COUNT2:
rrc $80
dec A
jrne L_COUNT1
ret
;=======================
CLEAR:
clr $80
clr $81
clr $82
clr $83
ret