В роботі приведемо лише ті АТ команди, які необхідні для коректної роботи комплексу:
Позначення команди | Результат виконання команди |
ATD#######; | Набрати номер ####### |
ATA | Підняти трубку |
ATZ | Завантажити заводську конфігурацію трубки |
При використанні розширених АТ команд більшість команд має три режими виконання:
“команда”=? – видає список параметрів, якщо мобільний телефон підтримує дану команду. У протилежному випадку видає повідомлення про невірно введену команду;
“команда”=<n1>[,<n2>,<n3>] – задає значення для параметрів які передбачені даною командою. Для деяких команд неможливе виконання команди у цьому режимі;
“команда”? – виводить в СОМ порт значення параметрів команди
При реалізації комплексу були задіяні натсупні розширені команди:
Позначення команди | Результат виконання команди |
AT+CLIP = 1 | пересилає номер телефону на СОМ порт |
AT+CHUP | Завершення телефонної розмови |
AT+CPAS? | Статус телефонної розмови:0 – розмова завершилася3 – встановлення зв’язку4 – розмова ведеться |
AT+CCLK? | Прочитати поточний час у форматі: YY.MM.DD,HH:MM:SS |
Після обробки команди мобільний телефон обов’язково повертає код виконання команди:
Код помилки | Позначення помилки | Пояснення |
0 | OK | Команда виконалася успішно |
2 | RING | З мережі GSM надійшов дзвінок |
3 | NO CARRIER | Немає несучої |
4 | ERROR | Невизначена помилка. Для детального визначення помилки необхідно задати команду АТ+СМЕЕ=<n> [4] |
6 | NO DIALTONE | Станція у відповідь на дзвінок не видає сигнал |
7 | BUSY | Віддалена станція перевантажена і не може обробити запит |
2.3 Специфіка програмування апаратних переривань на прикладі переривання від СОМ порта
Ініціалізація COM-порта
СОМ портом управляє мікросхема UART. Тому спочатку проведемо ініціалізацію UART. Cкидуємо регістри стану лінії, стану модему і даних. Це досягається простим зчитуванням значень цих регістрів:
; скидаємо регістр стану лінії
mov dx,LSR; LSR - адреса регістра стану лінії
in al,dx
jmp $+2; затримка
; скидаємо регістр стану модему
mov dx,MSR; де MSR - адреса регістра стану модему
in al,dx
jmp $+2; затримка
; скидаємо регістр даних
mov dx,DAT; де DAT - адреса регістра даних
in al,dx
jmp $+2; затримка
Ці регістри необхідно скинути для того, щоб надалі не заважали старі значення, які могли залишитися від роботи інших програм.
Після того як ми скинули регістри UART, можна приступити власне до ініціалізації COM-порту. Під час ініціалізації задається формат даних - довжина слова, кількість стопових бітів, наявність контролю по парності і швидкість обміну.
Для задання швидкості обміну даними треба перевести регістр даних і регістр керування перериваннями в режим уведення значення дільника частоти тактового генератора. Цей режим встановлюється записом одиниці в старший біт регістра керування лінією (LCR):
// переводимо регістр даних і регістр
// керування перериваннями у режим уведення
// значення дільника частоти тактового генератора
ctl = inp(LCR); // LCR - адреса регістра керування
// установлюємо старший біт регістра
outp(LCR_N, ctl | 0x80);
// обчислюємо значення для дільника частоти
//(змінна baud визначає швидкість обміну,
// яку ми хочемо установити)
switch(baud) {
case 110: div = 1040; break;
case 150: div = 768; break;
case 300: div = 384; break;
case 600: div = 192; break;
case 1200: div = 96; break;
case 2400: div = 48; break;
case 4800: div = 24; break;
case 9600: div = 12; break;
case 19200: div = 6; break;
case 38400: div = 3; break;
case 57600: div = 2; break;
case 115200: div =1; break;
default: return(-1); break;
}
// записуємо значення дільника частоти,
// молодший байт у регістр даних, старший –
// у регістр керування перериваннями
// ICR - адреса регістра керування перериваннями
outp(ICR, (div >> 8) & 0x00ff);
// DAT - адреса регістра даних
outp(DAT, div & 0x00ff);
// переводимо регістр даних і регістр
// керування перериваннями назад у звичайний
// для них режим
ctl = inp(LCR); // LCR - адреса регістра керування
//скидаємо старший біт регістра
outp(LCR, ctl & 0x7f);
Потім треба визначити формат даних. Для цього запишемо нове керуюче слово в регістр LCR:
// записуємо нове керуюче слово
outp(LCR, 00000011B);
// керуюче слово 00000011B встановлює довжину
// слова 8 біт, один стоповий біт, скасовує перевірку
// на парність і скасовує режим фіксації парності
Останнім кроком в ініціалізації регістрів UART є ініціалізація регістра керування перериваннями. Ми повинні спеціально вказати послідовному адаптеру, коли він повинен генерувати переривання.
Створення процедури обробки переривання для СОМ порта
Послідовний асинхронний адаптер можна запрограмувати таким чином, що кожний раз, коли він прийме чи передасть черговий байт, буде згенероване відповідне переривання. Переривання можуть генеруватися асинхронним адаптером у таких випадках:
змінився стан лінії приймача: відбулося переповнення приймача, відбулася помилка парності чи синхронізації, лінія перейшла в стан BREAK (розрив);
дані прийняті і доступні для читання через регістр даних;
регістр передавача порожній;
змінився стан модему: змінився стан ліній CTS, RI, DCD, DSR.
Існує можливість окремо забороняти чи дозволяти певний тип переривання. Для цього необхідно встановити відповідні біти в регістрі керування перериваннями.
Кожному COM-порту відповідає, крім базової адреси його регістрів, лінія IRQ [3]. Стандартний розподіл апаратних переривань такий:
COM-порт | IRQ | Номер переривання |
COM1 | IRQ4 | INT 0Ch |
COM2 | IRQ3 | INT 0Bh |
COM3 | IRQ4 | INT 0Ch |
COM4 | IRQ3 | INT 0Bh |
Для встановлення власного оброблювача переривання від СОМ порту необхідно замінити процедуру обробки переривання, яка встановлена операційною системою або БІОСом на власну процедуру обробки переривання. Після цього дозволити переривання, яке було встановлено.
При реалізації процедури обробки переривання необхідно керуватися таким алгоритмом:
1. Визначити причину переривання
Для цього потрібно проаналізувати стан бітів D1 D2, які визначають причину переривання:
Біти D2 D1 | Причина переривання |
00 | переривання по лінії стану; |
01 | буфер передавача порожній; |
10 | дані прийняті; |
11 | змінився стан модему. |
У залежності від того, яке відбулося переривання, його треба відповідним чином обробити.
Алгоритм роботи для кожного типу переривання від СОМ порта:
Відбулося переривання по лінії стану
Прочитати регістр стану лінії і конкретизувати причину переривання (дане переривання скидається після читання регістра стану лінії). Якщо це необхідно, подати основній програмі сигнал про помилку, що відбулася, з метою її усунення. Наприклад, у випадку розриву лінії (BREAK) (віддалений модем повісив трубку), можна було б спробувати відновити зв'язок.
Переривання по прийому даних
Черговий символ прийнятий, і його можна прочитати через регістр даних. Переривання скидається після читання регістра даних. Прийнятий байт необхідно записати в прийомний буфер програми, з якого згодом його прочитає основна програма. Буфер приймача зручно організувати у виді черги.
Буфер передавача порожній
Переривання відбувається у випадку, якщо буфер передавача порожній і можна передати COM-порту черговий символ. Можна організувати буфер передавача програми, у який програма буде записувати дані, призначені для відправки через COM-порт. У цьому випадку, коли прийде переривання, треба прочитати черговий символ з програмного буфера і записати його в регістр даних. Переривання скидається після запису чергового символу в регістр даних UART. Якщо немає даних для передачі (програмний буфер передавача порожній), можна заборонити це переривання через регістр керування перериваннями.
Змінився стан модему
Переривання відбувається при зміні стану вхідних ліній CTS, RI, DCD, DSR. Стан цих ліній можна визначити, прочитавши регістр стану модему MSR. Це переривання використовується для виявлення сигналу RING на телефонній лінії. Переривання автоматично скидається після читання регістра стану модему.
За час який переривання оброблялося може наступити нове переривання по ліній IRQ, тому необхідно проаналізувати біт D0. У випадку коли переривання знову згенероване (біт D0 регістра ідентифікації переривань дорівнює одиниці). Тоді перед завершенням обробки переривання необхідно обробити наступне переривання відповідно до стану бітів D1, D2. Так варто робити до тих пір, поки не будуть оброблені всі переривання (біт D0 не буде рівний нулю).
Виконавши всі вищевказані застереження та вимоги для виходу з процедури обробки переривання необхідно передати контролеру переривань команду обробки кінця переривання. Для цього посилається в порт з адресою 20h команда кінця переривання і здійснюється вихід з процедури обробки переривання:
mov al,20h
out 20h,al
iret
Установка оброблювача переривань
Необхідно установити оброблювач переривань, змінивши відповідний елемент таблиці векторів переривань. Адреса старого оброблювача зберігається в глобальних змінних.
Останнім кроком в ініціалізації регістрів UART є установка регістра керування перериваннями, у який записується занчення причин при настанні яких генеруються переривання. Наприклад, щоб дозволити генерацію переривань при надходженні чергового символу, треба записати значення для бітів D1,D2 відповідно 0 та 1 у регістрі керування перериваннями: