МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра САПР
ЗВІТ
До виконання лабораторної роботи №6
На тему: “ Передача даних з використанням послідовного комунікаційного порта ”
З курсу “ Системне програмування та операційні системи ”
Львів – 2012
1. МЕТА РОБОТИ
Мета роботи – створення програмного забезпечення для передачі даних з використанням послідовного порту RS-232.
2. КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
При асинхронному зв'язку машина посилає або приймає байти інформації порціями по одному біту. Тимчасові інтервали між байтами при цьому несуттєві, але дуже важливі є інтервали між окремими бітами байта. Сигнал на лінії може бути високого або низького рівня, що відповідає логічним нулю і одиниці, і кажуть, що лінія відмічена (marking), коли рівень високий, і пуста (spacing), коли рівень низький. Лінія підтримується у відміченому стані, коли по ній не передають даних. На початку передачі байта даних сигнал падає у 0, відмічаючи стартовий біт. Потім слідують вісім бітів даних (іноді менше) у вигляді набору високих і низьких рівнів. Останній біт даних може супроводжуватися бітом парності, що використовується для виявлення помилок, а потім у послідовність включаються 1 або більше стоп-біти, яким відповідає високий рівень. Ці стоп-біти починають відмічений стан, який буде зберігатися до тих пір, поки не почнеться передача наступного байта даних; число стоп-бітів суттєве, оскільки вони встановлюють мінімальний час, який повинен пройти перед наступним стартовим бітом. На рис. 1 представлена ця послідовність. Звичайно, передаюча і приймальна станції повинні застосовувати один і той же протокол для ланцюжків бітів і працювати з однією і тією ж швидкістю обміну (що вимірюється у бітах за секунду, які також називаються бодами). Під час обміну можуть легко виникати помилки, тому комунікаційне обладнання надає різносторонню інформацію про статус як самого порту, так і про приєднаного до нього модему. Задачею модему є перетворення сигналу, що генерується портом комунікації, в акустичний сигнал, який може потім бути переданий по телефонному каналу. Більшість модемів надає також додаткові комунікаційні можливості, такі, як автоматичний виклик і відповідь, які не підтримуються самим портом комунікації.
Рис.1. Передача одного байта послідовних даних.
2.1. Програмування мікросхеми UART 8250
Послідовний зв'язок настільки складний, що були розроблені спеціальні мікросхеми. Вони виконують роботу з формування і синхронізації рядків бітів, що складають послідовні дані. Такі мікросхеми називають універсальним асинхронним приймачем-передавачем (universal asynchronous receiver transmitter або UART). IBM PC використовує UART 8250 фірми Intel. Так як операційна система підтримує 2 порти комунікації, то в машині є 2 мікросхеми. Їх базові адреси зберігаються в комірках 0040:0000 для СОМ1 і 0040:0002 для COM2. (Базова адреса - це двобайтова адреса порту, яка є молодша із групи адрес портів, що дають доступ до UART.) На всіх машинах, крім PCjr, COM1 має базову адресу 3F8H, а COM2 - 2F8H; PCjr має свій внутрішній модем за адресою 3F8H, а COM1 - за адресою 2F8H. Для зручності ми надалі будемо завжди нумерувати регістри 3FxH, але все сказане в рівній мірі можна застосовувати і до регістрів 2FxH. Мікросхема 8250 має 10 програмованих однобайтових регістрів, за допомогою яких керується і контролюється порт комунікації. Більшість з них займається ініціалізацією порту, процесом, в якому виникає багато ускладнень. Доступ до цих 10 регістрів здійснюється через сім адрес портів з номерами 3F8H - 3FEH (або 2F8H - 2FEH). У п'яти випадках регістр, до якого отримуємо доступ через даний порт, залежить від того, як встановлений біт 7 в регістрі контролю лінії, який є єдиним регістром з адресою порту 3FBH. Ось ці регістри:
3F8H (OUT, біт 7 = 0 в 3FBH)
Регістр зберігання передавача
3F8H (IN, біт 7 = 0 в 3FBH)
Регістр даних приймача
3F8H (OUT, біт 7 = 1 в 3FBH)
Дільник швидкості обміну (молодший)
3F9H (IN, біт 7 = 1 в 3FBH)
Дільник швидкості обміну (старший)
3F9H (OUT, біт 7 = 0 в 3FBH)
Регістр дозволу переривання
3FAH (IN)
Регістр ідентифікації переривання
3FBH (OUT)
Регістр управління лінії
3FCH (OUT)
Регістр управління модемом
3FDH (IN)
Регістр статусу лінії
3FEH (IN)
Регістр статусу модему
Із десяти регістрів тільки шість необхідні для простого послідовного зв'язку. Регістр зберігання передавача містить байт даних, які будуть надіслані [6.], а регістр даних приймача - останній отрийнятий байт даних [7.]. Регістри управління і статусу лінії ініціалізують і управляють лінією зв'язку, використовуючи швидкість обміну, що міститься у двох регістрах дільника швидкості обміну [2.]. З чотирьох регістрів, що залишилися, регістри управління і статусу модему необхідні тільки для зв'язку через модем [5.], а два регістри, пов'язаних з перериваннями - тільки в процедурах, керованих перериваннями [8. ].
Переривання при зв'язку використовують в цілях ефективності. Звичайна комунікаційна процедура безперервно перевіряє регістр статусу лінії, чекаючи символа, що вводиться або вказівки, що все готове для передачі наступного байта даних. Оскільки процесор працює дуже швидко, в порівнянні із звичайними швидкостями, з якими передаються послідовні дані, то цей метод марно витрачає процесорний час, який може використовуватися для обробки даних, що поступають або передаються. З цієї причини мікросхема 8250 може бути встановлена в режим, що спричиняє переривання при появі символа, виникненні помилки і т.п. Це переривання вмить викличе процедуру вашої програми, яка, скажемо, буде передавати наступний символ з комунікаційного буфера.
2.2. Ініціалізація послідовного порту
При ініціалізації ( "відкритті") порту комунікації встановлюються всі його параметри. Ці параметри включають в себе довжину слова, число стоп-бітів, установку парності і швидкість обміну. Довжина слова - це число бітів, яке утворює основну одиницю даних. Хоч зазвичай працюють з порціями по 8 біт, але для стандартних файлів ASCII (в яких всі символи мають коди, що не перевищують ASCII 128) досить 7 біт, а для передачі числових даних - всього 4 біт.
Середній рівень
Функція 0 переривання 14Н BIOS ініціалізує порт комунікації. У DX повинен знаходитися номер комунікаційного каналу (COM1 = 0, COM2 = 1). У AL повинен міститися байт, що ініціалізує дані, значення бітів якого може бути наступним:
біти 1-0 довжина слова. 10 = 7 біт, 11 = 8 біт
2 число стоп-бітів. 0 = 1, 1 =2
4-3 парність. 00 або 10 = немає, 01 = непарн., 11 = парн.
7-5 швидкість обміну.
000 = 110 бод
001 = 150 бод
010 = 300 бод
011 = 600 бод
100 = 1200 бод
101 = 2400 бод
110 = 4800 бод
111 = 9600 бод
У даному прикладі порт ініціалізується зі словом, рівним 8 бітам, одним стоп-бітом і парною парністю. Швидкість обміну -1200 бод.
; присвоюємо значення параметрів змінним
MOV WORDLENGTH,00000011В ;довжина слова 8 біт
MOV STOPBITS, 00000000B ;1 стоп-біт
MOV PARITY, 00011000В ;парна парність
MOV BAUDRATE,10000000В ;швидкість 1200 бод
;ініціалізувати СОМ1
MOV AL,0 ;чистимо AL
OR AL,WORDLENGTH ;встановлюємо потрібні біти
OR AL,STOPBITS
OR AL,PARITY
OR AL,BAUDRATE
MOV AH, 0 ;функція ініціалізації порту
MOV DX, 0 ;вибераємо СОМ1
INT 14H ;ініціалізувати порт
Низький рівень
Незалежно від того, займаємося ми вводом або виводом, як мінімум, 4 регістри мікросхеми 8250 повинні бути ініціалізованими для операцій обміну. Це регістри дільника швидкості обміну, регістр контролю лінії і регістр дозволу переривання.
Ініціалізація швидкості обміну. Дільник швидкості обміну – це число, на яке треба розділити частоту системних годин (1190000 Гц), щоб отримати бажану швидкість обміну. Наприклад, для швидкості обміну 1200 бод дільник швидкості обміну повинен бути рівний 96, оскільки 1190000/96 приблизно дорівнює 1200. Чим більший дільник, тим менша швидкість обміну. Швидкість обміну 300 бод і менше вимагає двобайтового числа для дільника. Старший байт посилається в 3F9H (або 2F9H), а молодший - в 3F8H (2F8H). У обох випадках біт 7 регістра управління лінії повинен бути встановлений в 1 перед засиланням значення, в іншому випадку за цими двома адресами значення будуть адресовані в інші регістри . Ось деякі значення, необхідні для звичайних швидкостей обміну:
Швидкість обміну
3F9H
3F8H
110
04H
17H
300
01H
80H
600
00H
C0H
1200
00H
60H
1800
00H
40H
2400
00H
30H
3600
00H
20H
4800
00H
18H
9600
00H
0CH
Завжди встановлюйте регістри швидкості обміну першими, оскільки вони єдині, які вимагають установки біта 7 в регістрі контролю лінії. Після цього треба змінити вміст регістра контролю лінії, скидаючи біт 7, щоб всі інші доступи до регістрів були правильними. Оскільки регістр контролю лінії є регістром тільки для запису, то немає способу повернути біт 7 назад в 1 без одночасної установки всіх інших бітів цього регістра. Зазначимо, що PCjr використовує інших дільників, опис яких ви можете знайти в технічному керівництві.
Ініціалізація регістра контролю лінії. Значення бітів регістра контролю лінії, адреса порту якого рівна 3FBH (або 2FBH), можуть бути наступними:
біти 1-0 довжина символа. 00 = 5 біт, 01=6 біт, 10=7 біт, 11=8 біт
2 число стоп-бітів. 0 = 1, 1 = 1,5, якщо довжина символів рівна п'яти, інакше - 2
3 парність. 1 = генерується біт парності, 0 = немає
4 тип парності. 0 = непарна, 1 = парна
5 фіксація парності. Примушує біт парності завжди бути 0 або 1.
0 = відмінена
1 = завжди 1, якщо біт 3 = 1 & біт 4=0
або 1 = завжди 0, якщо біт 3 = 1 & біт 4 = 1 або
1 = немає парності, якщо біт 3 = 0
6 установка перерви. Викликає виведення строки нулів як сигнал віддаленої станції. 0 = заборонено, 1 = перерва
7 міняє адреси портів інших регістрів
Зазвичай биті 5-7 скинені в 0. Інші описують значення, що визначаються протоколом обміну.
Регістр дозволу переривання. Навіть якщо ви не використовуєте переривання, все одно треба зробити запис в регістр дозволу переривання, щоб бути упевненим, що переривання заборонені. Просто вмістіть в цей регістр 0. Регистр ідентифікації переривання можна ігнорувати.
Ініціалізація інших регістрів пов'язана з модемами. Ясно, що модеми потрібні тільки для зв'язку з віддаленими пристроями, а не для управління сусідніми, такими, як послідовний принтер. У [5] пояснено, як ініціалізувати регістр контролю модему.
У наступному прикладі з області даних BIOS береться базова адреса СОМ1, після чого різні регістри ініціалізуються для швидкості обміну 1200 бод, семибітових даних, парної парності і одного стоп-біта.
;отримуємо базову адресу СОМ1
MOV AX, 40H ;ES вказує на область даних BIOS
MOV ES, AX
MOV DX, ES:[0] ;отримуємо базову адресу СОМ 1
; ініціалізувати регістри дільника швидкості обміну на 1200 бод
ADD DX, 3 ;вказуємо на регістр контролю лінії
MOV AL, 10000000В ;встановлюємо біт 7
OUT DX, AL ;посилаємо байт
DEC DX ;вказуємо на старший байт дільника
DEC DX ;швидкості обміну
MOV AL, 0 ;старший байт для 1200 бод
OUT DX, AL ;посилаємо старший байт для 1200 бод
DEC DX ;вказуємо на молодший байт дільника
MOV AL, 60H ;молодший байт дільника для 1200 бод
OUT DX, AL ;посилаємо молодший байт
;ініціалізувати регістр контролю лінії
MOV AL, 0 ;обнулюємо AL
OR AL, 10B ;довжина даних 7 біт
OR AL, 000B ;1 стоп-біт
OR AL,1000B ;генерується біт парності
OR AL,10000B ;парна парність
ADD DX, 3 ;вказуємо на регістр контролю лінії
OUT DX, AL ;посилаємо значення ініціалізації
;ініціалізувати регістр дозволу переривання
DEC DX ;вказуємо на регістр дозволу
DEC DX ;переривання
MOV AL, 0 ;забороняємо переривання
OUT DX, AL ;посилаємо байт
2.3. Установка поточного комунікаційного порту
Є два способи, за допомогою яких програма може визначити, який з комунікаційних портів повинен використовуватися. Один з них – вказівка номера каналу в операторі програми. Другий спосіб – написання програми для обміну через порт СОМ1, але зміна комунікаційного адаптера, доступ до якого йде через СОМ 1. Область даних BIOS містить місце для чотирьох двобайтовий змінних, в яких знаходяться базові адреси комунікаційних каналів (MS-DOS підтримує тільки перші два з них). Базова адреса порту - це молодша з групи адрес портів, через які можна отримати доступ до даного комунікаційного каналу. Базова адреса для СОМ1 зберігається в комірці 0040:0000, а для COM2 - в комірці 0040:0002. Для зміни комунікаційних портів треба просто поміняти ці два значення. Повторна зміна значень приведе до початкового призначення портів.
Середній рівень
Якщо програма звертається до комунікаційного порту через переривання 14Н BIOS, то СОМ-порт визначається в DX, що дорівнює 0 або 1 (для СОМ1 або COM2). Замість того щоб присвоювати DX безпосереднє значення, заповнюйте його зі змінної, якій може бути присвоєне значення 0 або 1. Программи, які використовують комунікаційні функції 3 і 4 переривання 21Н, завжди адресуються до СОМ1. У цьому випадку треба поміняти базові адреси:
; обмін базових адрес для СОМ1 і COM2
MOV AX, 40H ;ES вказує на область даних BIOS
MOV ES, AX
MOV DX, ES:[0] ;поміщуємо 1-у базову адресу в DX
MOV AX, ES:[2] ;поміщуємо 2-у базову адресу в AX
MOV ES: [0], АХ ;обмінюємо адреси
MOV ES:[2], DX
2.4. Визначення статусу комунікаційного порту
Регістр статусу лінії мікросхеми UART 8250 визначає протокол зв'язку. Цей регістр має адресу порту на 5 більшу, ніж базова адреса даного каналу. Звичайно він постійно переглядається в процесі комунікаційного обміну. При передачі даних регістр повідомляє, що попередній символ вже посланий, дозволяючи програмі записати новий символ. При прийомі даних регістр інформує програму про надходження наступного символу, з тим щоб програма могла прочитати його перед тим, як він буде знищений наступним прибулим. Значення бітів цього регістра наступні:
біт 0 1 = байт даних отриманий
1 1 = отримані дані були перезаписані (попередній символ не був вчасно прочитаний)
2 1 = помилка парності (ймовірно, через шум в лінії)
3 1 = помилка оточення (передача не синхронізована)
4 1 = виявлена перерва (отриманий довгий рядок одиниць, який відображає, що інша станція запитує кінець передачі)
5 1 = регістр збереження передавача пустий (в цей регістр повинні вміщуватися дані, що передаються )
6 1 = регістр зсуву передавача пустий (цей регістр отримує дані з регістра зберігання і перетворює їх в послідовний вид)
7 1 = тайм-аут (пристрій не зв'язаний з машиною)
Середній рівень
Функція 3 переривання 14Н BIOS повертає в АН регістр статусу лінії (AL отримує регістр статусу модему [5]). При вході DX повинен містити номер комунікаційного порту, до якого здійснюється доступ, де СОМ1 = 0, а COM2 = 1. Перевіряється наявність перерви:
MOV AH, 3 ;номер функції
MOV DX, 1 ;вибираємо COM2
INT 14H ;отримуємо байт статусу
TEST AH, 10000В ;виявлена перерва?
JNZ BREAK_DETECT ;якщо так, то переходимо до процедури обробки
Низький рівень
З області даних BIOS прочитується базова адреса комунікаційного каналу, до нього додається 5, а потім з отриманої адреси порту прочитується байт статусу.
MOV AX, 40H ;ES вказує на область даних BIOS
MOV ES, AX
MOV DX, ES:[2] ;отримуємо базову адресу COM2
ADD DX, 5 ;додаємо 5 для регістра статусу
IN AL, DX ;отримуємо байт статусу
TEST AL, 10000B ;біт 5 встановлений?
JNZ BREAK_DETECT ;якщо так, то переходимо до обробки перерви
2.6. Передача даних
Передача даних простіша, ніж їх прийом, оскільки програма повністю контролює склад даних і швидкість, з якою вони повинні посилатися. Проте процедури передачі можуть бути досить складними, якщо вони обробляють дані по мірі того, як вони посилаються. Можуть бути також проблеми з синхронізацією при використанні протоколу XON/XOFF. Цей протокол використовує коди ASCII 17(XON) і 19(XOFF), для того щоб сигналізувати приймаючій станції, що передавач хоче продовжити передачу тимчасово перерваного потоку даних. Щоб прийняти ці сигнали, програма повинна безперервно аналізувати символи, що приймаються при передачі (у повнодуплексном режимі, в якому зазвичай працюють модеми, сигнали одночасно йдуть в обидві сторони по телефонному каналу). Крім того, щоб виявити, що віддалена станція посилає рядок нулів як сигнал перерви, повинен безперервно аналізуватися статус біта перерви (номер 4) регістра статусу лінії [4].
Внаслідок цих причин представлені тут процедури, окремо передаючі дані, є штучними. Але їх можна скомбінувати з процедурами прийому даних, описаними в [7], для створення загального уявлення. Ясно, що для створення діючої процедури необхідно затратити великі зусилля, особливо в частині виявлення і виправлення помилок при передачі даних.
Середній рівень
Функція 1 переривання 14Н BIOS посилає символ, що знаходиться в AL, в комунікаційний канал. При вході DX містить номер порту (0 або 1). При поверненні AH отримує байт статусу, в якому біт 7 = 1, якщо операція неуспішна. У цьому випадку мають значення наступні біти:
біт 4 виявлений перерва (сигнал "стоп" від приймаючої станції)
5 регістр зсуву передавача пустий
6 регістр зберігання передавача пустий
MS-DOS має функцію для передачі по комунікаційному каналу символа, що вміщується в DL. Це функція номер 4 переривання 21Н, але у неї немає ніяких переваг перед функцією BIOS; вона не повертає статусної інформації і не дозволяє призначати, який з комунікаційних портів треба використати (це завжди СОМ1).
Щоб вивести рядок даних, скористайтеся функцією 40Н переривання 21Н. Це звичайна функція виводу для всіх файлів і пристроїв методом доступу дескриптора файлів. СОМ1 має визначений номер - #3. Вмістіть номер файла в BX, а число байтів, що передаються в CX. Нехай DS:DX вказують на буфер даних, що виводяться, потім викликайте функцію.
MOV AH,40H ;номер функції
MOV BX,3 ;наперед визначений номер файла для СОМ 1
MOV CX,50 ;виводимо 50 байт
LEA DX,BUFER ;DS:DX вказують на буфер даних
INT 21Н ;посилаємо дані
JC COM_ERROR ;відхід на обробку помилки
Зазначимо, що при використанні визначених номерів файлів їх не треба відкривати. Якщо сталася помилка, встановлюється прапор переносу, а в АХ повертається 5, якщо комунікаційний порт не готовий, і 6 при вказівці неправильного номера файла.
Низький рівень
Коли байт даних вміщується в регістр зберігання передавача, то він автоматично виводиться в послідовний канал через регістр зсуву передавача, якого серіалізує дані. Немає необхідності в імпульсі біта стробу, як це робиться у разі паралельного адаптера. Біт 5 регістру статусу лінії показує, чи вільний регістр зберігання передавача для прийому даних. Регістр постійно перевіряється доти, поки біт 5 не стане рівним 1. Після цього в регістр зберігання передавача посилається черговий байт. У процесі передачі біт 5 рівний 0, і тільки коли він знову стане рівним 1, в регістр зберігання передавача може бути посланий наступний символ. Цей процес повторюється доти, поки в цьому є необхідність.
У наступному прикладі дані основні поняття про цю процедуру. Звичайно, вона може бути створена надзвичайно складної (зокрема, програмування зв'язку вимагає особливо ретельних процедур виявлення помилок і відновлення при збоях). У прикладі передбачається, що комунікаційний порт і модем вже ініціалізовані, як показано в [2] і [5]. Перша частина це цикл перевірки помилок і прийому символів. У [7] приведений код для процедури прийому даних.
; чекаємо, поки все буде готове для посилки символа
KETRY: MOV DX, BASADR ;базова адреса
ADD DX,5 ;вказуємо на регістр статусу лінії
IN AL,DX ;отримуємо байт статусу
TEST AL,00011110B ; перевіряємо на помилку
JNZ ERRROUT ;якщо є, то на процедуру обробки помилки
TEST AL,00000001B ;перевіряємо, чи отримані дані
JNZ RECEIVE ;якщо так, то на процедуру прийому
TEST AL,00100000B ;перевіряємо готовність до передачі
JZ KETRY ;якщо немає, то повертаємося назад
;передаємо символ, що приймається з клавіатури
MOV AH, 1 ;функція перевірки натиснення клавіші
INT 16H ;переривання клавіатури BIOS
JZ KETRY ;повернення, якщо не було натиснення
MOV AH,0 ;функція отримання коду з клавіатури
INT 16H ;тепер потрібний символ в AL
SUB DX, 5 ;адреса регістра зберігання передавача
OUT DX, AL ;посилаємо символ
JMP SHORT KETRY ;повертаємося на початок циклу
2.7. Отримання даних
Як тільки ініціалізувати комунікаційний порт [2] і встановлений зв'язок з віддаленою станцією [5] - комунікаційна програма готова приймати дані. Прийом даних ніколи повністю не відділений від їх передачі, оскільки програмі може стати потрібним послати сигнал XOFF (ASCII 19), щоб зупинити потік даних, якщо вони поступають дуже швидко і вона не встигає їх обробляти. Код XON (ASCII 17) повідомляє віддаленій станції, що можна продовжити передачу. Зазначимо, що PCjr не може приймати дані під час дискових операцій; щоб зняти це обмеження, треба застосовувати XON і XOFF.
У залежності від складності протоколу обміну дані, що приймаються можуть вимагати простої або складної обробки. Може бути отриманий будь-який код з набору керуючих кодів. Ті з них, які є обмежувачами даних, частіше виявляються при синхронному обміні. При виведенні отримуваних символів на екран враховуйте вплив символів переведення рядка (ASCII 10), оскільки деякі мови автоматично вставляють їх після кожного символа повернення каретки; в цьому випадку виключайте символи переведення рядка з даних, що приймаються, щоб уникнути пустих рядків при виведенні. На мал. 7.2 показана комунікаційна процедура, що включає також код передачі, який обговорюється в [6].
Середній рівень
Функція 2 переривання 14Н BIOS чекає символ з послідовного порту, вміщує його в AL при отриманні і потім повертається в програму. При вході треба помістити номер порту (0-1) в DX. При поверненні АХ рівний нулю, якщо не було помилки. Якщо AH не рівний 0, то може бути повернений байт статусу, в якому мають значення тільки 5 біт. Це наступні біти:
біт 1 помилка переповнення (новий символ поступив раніше, ніж був видалений старий)
2 помилка парності (ймовірно, через проблеми в лінії)
3 помилка оформлення (стартовий або стоп-біти невірні)
4 виявлена перерва (отриманий довгий рядок бітів 0)
5 помилка тайму-ауту (не отриманий сигнал DSR)
MS-DOS також надає комунікаційну функцію для прийому одного символа - функцію 3 переривання 21Н. Вона чекає символ з СОМ1 і вміщує його в AL. Зазначимо, що при цьому немає функції ініціалізації порту, яку треба робити за допомогою процедури BIOS або безпосередньо, як показано в [2]. По замовчуванні порт ініціалізується зі значеннями 2400 бод, немає контролю парності, один стоп-біт і 8 біт на символ. Ця функція не має ніяких переваг в порівнянні з функцією BIOS і не повертає інформації про статус.
Низький рівень
При отриманні даних без використання комунікаційного переривання [8] програма повинна постійно перевіряти регістр статусу лінії, адресу порту якого на 5 більша базової адреси комунікаційного адаптера, що використовується. Біт 0 цього регістра буде рівний нулю, поки не буде отриманий символ в регістрі даних приймача. Коли біт 0 стає рівним 1, треба негайно зчитати його з регістра, з тим щоб на нього не наклався наступний символ, що приймається. Після того як символ прочитаний, біт 0 знову стає рівним 0 і залишається таким, поки не прибуде новий символ.
Хоч про це ще не згадувалося, але ви повинні знати, що комунікаційні процедури звичайно створюють циклічний буфер для збору поступаючих символів. Ви повинні також знати, що якщо поступаючі дані подавати на екран з швидкістю 1200 бод, то процедура зсуву екрана BIOS не буде устигати і станеться переповнення. Просте розв'язання цих проблем складається у використанні комунікаційного переривання.
У наступному прикладі частково повторюється вміст попереднього параграфа, що відноситься до передачі символів. Як і в тому випадку, код починається з нескінченного циклу. Об'єднайте ці дві процедури з процедурами ініціалізації з [2] і [5] для створення закінченої процедури введення/виведення через комунікаційний канал.
KETRY: MOV DX, BASADR ;базова адреса
ADD DX, 5 ;вказуємо на регістр статусу лінії
IN AL, DX ;отримуємо байт статусу
TEST AL, 00011110В ;перевіряємо на помилку
JNZ ERRROUT ;якщо так, то на обробку помилки
TEST AL,00000001B ;перевіряємо, чи отримані дані
JNZ RECVE ;на процедуру прийому даних
TEST AL,00100000B ;перевіряємо готовність до передачі
JZ KETRY ;якщо немає, то на початок циклу
.
(тут розташована процедура передачі )
.
; отримуємо дані і виводимо їх на екран
RECVE: MOV DX,BASE_ADDRESS ;базова адреса
IN AL,DX ;читаємо отриманий символ
CMP AL,19 ;перевірка на XOFF
JE XOFF_ROUTINE
; (і т.д.)
MOV DL,AL ;готуємо символ для виведення на екран
MOV AH,2 ;функція виведення
INT 21Н ;виводимо його
JMP SHORT KETRY ;повертаємося на початок циклу
Власний варіант програми:
Програма-передавач:
title com_send
sseg segment stack
db 256 dup(?)
sseg ends
dseg segment
string db 256 dup(0)
adres dw ?
dseg ends
cseg segment
assume ss:sseg,cs:cseg,ds:dseg
getstr proc near ;процедура зчитування даних з клавіатури
xor si,si
a1: mov ah,1
int 21h
cmp al,0dh
je a2
mov string[si],al
inc si
jmp a1
a2: inc si
mov string[si],0
xor si,si
ret
getstr endp
start: push ds ;початок
mov ax,dseg
mov ds,ax
mov ax,40h ;взяття адреси
mov es,ax
mov dx,es:[0]
mov adres,dx
add dx,3
mov al,10000000b ;для дільників
out dx,al
sub dx,2 ;старший дільник
mov al,0
out dx,al
dec dx ;молодший дільник
mov al,60h
out dx,al
add dx,3
mov al,00000011b ;для налаштувань лінії
out dx,al
sub dx,2 ;заборона переривань
mov al,0
out dx,al
call getstr ;виклик процедури зчитування даних
mov dx,adres
add dx,5
b1: in al,dx ;перевірка готовності
test al,00100000b
jz b1
sub dx,5 ;посилання символа
xor si,si
mov al,string[si]
out dx,al
test al,al
jz exit
inc si
jmp b1
exit: mov ax,4c00h ;вихід з програми
int 21h
cseg ends
end start
Програма-приймач:
title com_send
sseg segment stack
db 256 dup(?)
sseg ends
dseg segment
buf db 256 dup('$')
adres dw ?
dseg ends
cseg segment
assume ss:sseg,cs:cseg,ds:dseg
start: push ds ;початок
mov ax,dseg
mov ds,ax
mov ax,40h ;взяття адреси
mov es,ax
mov dx,es:[0]
mov adres,dx
add dx,3
mov al,10000000b ;для дільників
out dx,al
sub dx,2 ;старший дільник
mov al,0
out dx,al
dec dx ;молодший дільник
mov al,60h
out dx,al
add dx,3
mov al,00000011b ;для налаштувань лінії
out dx,al
sub dx,2 ;заборона переривань
mov al,0
out dx,al
mov dx,adres
add dx,5
b1: in al,dx ;перевірка готовності
test al,00000001b
jz b1
xor si,si ;отримання символів
sub dx,5
in al,dx
test al,al
jz exit
mov buf[si],al
inc si
jmp b1
exit: mov ah,9
mov dx,offset buf
int 21h
mov ax,4c00h ;вихід з програми
int 21h
cseg ends
end start
ВИСНОВКИ:
На цій лабораторній роботі я створив програмне забезпечення для передачі даних з використанням послідовного порту RS-232.