6.1.1 Регістри портів
Звертання до портів відбувається через регістри введення/виведення. В адресному просторі введення/виведення для кожного порту відведено по 3 регістри:
DDRx - напрямку роботи (передавач/приймач) ;
PORTx – вихідних даних;
PINx – вхідних даних.
Наприклад, для порта А - DDRA, PORTA, PINA.
Розряди цих регістрів мають назви:
DDx7… DDx0 – для регістрів DDRx;
Рх7…Рх0 – для регістрів PORTx;
PINx7… PINx0 – для регістрів PINx.
Регістри PINx дозволяють здійснити доступ до фізичних значень сигналів на виводах порта. Відповідно вони доступні лише для читання. Регістри PORTx та DDRx доступні як для читання, так і для запису. Після рестарту мікроконтролера в регістри PORTx та DDRx записуються початкові нулеві значення. Це відповідає режиму приймача.
Запис у порт означає запис необхідного стану для кожного виведення порту у відповідний регістр даних порту PORTx. А читання стану порта виконується читанням або регістра даних порту PORTx, або регістра виводів порту PINx. При читанні регістра виводів порту PINx відбувається зчитування логічних рівнів сигналів, що присутні на виводах порту. А при читанні регістра даних порту відбувається зчитування даних, що знаходяться у регістрі PORTx .
Регістри портів розташовані у сегменті регістрів введення/виведення (32 регістри на початку сегменту), для якого можливі бітові маніпуляції. Це суттєво спрощує роботу з окремими лініями портів. Можливе виконання команд бітових маніпуляцій SBI, CBI, та розгалуження SBIS, SBIC.
6.1.2 Конфігурування портів
Порти мають дві можливості для конфігурування:
завдання напрямку передачі даних через лінії портів (вхід або вихід);
підключення/відключення внутрішнього підтягуючого резистора.
Напрямок передачі даних визначається вмістом регістра передачі даних DDRx. Якщо розряд DDxn цього регістра встановлено в «1», відповідний n-вивід порта є виходом. У протилежному випадку (встановлено «0»), відповідний n-вивід порта є входом.
Керування підтягуючим резистором здійснюється за допомогою регістра даних PORTx. Якщо розряд Pxn регістра PORTx встановлено в «1» і відповідний вивід порту є входом, між цим виводом та шиною живлення підключається підтягуючий резистор. Для того щоб відключити підтягуючий резистор, необхідно або скинути відповідний розряд регістра PORTx, або зробити вивід порта виходом.
6.1.3 Приклад ініціалізації порту
Початкова ініціалізація портів є надзвичайно важливою процедурою. Ініціалізація повинна проводитися одразу після рестарту мікроконтролера. Затримка з її проведенням у деяких випадках може привести до виникнення аварійної ситуації у об’єкті керування.
Визначення типів ліній портів та їх початкового стану проводиться на підставі аналізу електричної принципової схеми пристрою. Нижче приведено приклад ініціалізації порту А.
Використано конфігурацію ліній порту, що наведено у табл.. 3.2.
Таблиця 3.2
Лінії порту |
PA7 |
PA6 |
PA5 |
PA4 |
PA3 |
PA2 |
PA1 |
PA0 |
Передавач |
* |
* |
* |
* |
|
|
|
|
Вихідний рівень |
1 |
1 |
0 |
0 |
|
|
|
|
Приймач |
|
|
|
|
* |
* |
* |
* |
Підтяжка |
|
|
|
|
|
|
* |
* |
У відповідності з цією таблицею визначаються константи ініціалізації ini_DDRA та ini_PORTA.
Для маніпуляцій з лініями портів доцільно використовувати символічні описи. Це суттєво спрощує модифікацію програми під час її адаптації до розробленої печатної плати. Для введення символічного опису використовують директиву “.equ”.
Приклад 1
;------------------------------------------------------------------
.def TMP=R16 ;символічне ім`я регістру R16
.equ LED2 =7 ;символічне ім`я 7-го біту (порт визначається додатково)
.equ ini_DDRA =0b11110000 ;1-передача, 0-прийом
.equ ini_PORTA =0b01000011 ;початковий стан порту PА
;------------------------------------------------------------------
ldi TMP, ini_DDRA ;визначення типу ліній порту PA - прийом/передача
out DDRA,TMP
ldi TMP, ini_PORTA ;визначення початкового стану ліній порту
out PORTA,TMP
sbi PORTA,LED2 ;встановлення «1» на 7-ії лінії порту PORTA
;------------------------------------------------------------------
6.2 Вивід цифрових сигналів
6.2.1 Вивід статичних цифрових сигналів
Для виведення цифрових сигналів необхідно налаштувати відповідні лінії портів на режим передавача (п.7.1.3). Операції виведення проводять з регістрами PORTx (PORTA, PORTB…).
Для встановлення лінії портів у “1”, або скидання у “0” – стан використовуються команди ассемблера
sbi PORTx, bit, cbi PORTx, bit,
де: “PORTx” – вихідний порт; “bit” – біт призначення.
Якщо увесь порт використовується у режимі передавача, та одночасно змінюється декілька біт, то доцільно використовувати команди завантаження байтів
out PORTx, Rr,
де: “ Rr ” – один з файлових регістрів.
Не допускається виконання логічних та арифметичних операцій безпосередньо на регістрах PORTx. Такі операції можливі лише з файловими регістрами.
У першому прикладі проілюстрована можливість використання команд виведення.
6.2.2 Вивід імпульсних сигналів
Розрізняють наступні типи імпульсних сигналів:
Одиночні сигнали;
Одиночна послідовність ряду імпульсів (пакет імпульсів);
Періодичні сигнали із установленими періодом та тривалістю імпульсів;
Періодична послідовність пакетів імпульсів.
Для формування імпульсних сигналів можливе використання як програмних засобів, так і можливостей таймерів-рахівників мікроконтролера.
6.2.2.1 Вивід імпульсних сигналів з використанням програмних засобів
Такий тип виведення використовується у випадках, коли відсутні суттєві обмеження по часу виконання процедури, або при необхідності створення драйверів зовнішніх мікросхем з жорсткими вимогами до тривалості та періоду повторення імпульсів керування.
Загальний алгоритм виведення передбачає реалізацію виведення на порт певного логічного стану та необхідної програмної затримки до моменту виведення наступного стану.
У другому прикладі забезпечується формування на лінії порту LED2 періодичної послідовності двох позитивних імпульсів з наступними параметрами:
Тривалість першого та другого імпульсів – 1мкс;
Затримка між першим та другим імпульсами – 2мкс;
Період повторення пачки імпульсів – 100мкс.
У другому прикладі використані фрагменти ініціалізації з першого прикладу.
Приклад 2
;------------------------------------------------------------------
MAIN:
rcall PAKET ;формування пакету імпульсів
rcall DELAY_100mcs ;формування періоду повторення пакету
rjmp MAIN
;------------------------------------------------------------------
;------------------------------------------------------------------
;Підпрограми
;------------------------------------------------------------------
PAKET:
sbi PORTA,LED2 ;Формування першого імпульсу пакету
rcall DELAY_1mcs ;тривалість першого імпульсу пакету
cbi PORTA,LED2
;-----------
rcall DELAY_1mcs ; формування затримки між імпульсами в пакеті
rcall DELAY_1mcs
;-----------
sbi PORTA,LED2 ;Формування другого імпульсу пакету
rcall DELAY_1mcs ;тривалість другого імпульсу пакету
cbi PORTA,LED2
;-----------
ret
;------------------------------------------------------------------
;------------------------------------------------------------------
;Підпрограма затримки на 1мкс. Частота 10МГц
DELAY_1mcs:
ldi TMP,4
DEL_1mcs_1:
dec TMP
brne DEL_1mcs_1
;-----------
ret
;------------------------------------------------------------------
.def TMP1=R17 ;символічне ім`я регістру R17
;------------------------------------------------------------------
;Підпрограма затримки на 100мкс. Частота 10МГц
DELAY_100mcs:
ldi TMP1,100
DEL_100mcs_1:
rcall DELAY_1mcs
dec TMP1
brne DEL_100mcs_1
;-----------
ret
;------------------------------------------------------------------
6.2.3 Ввід статичних цифрових сигналів
У AVR- мікроконтролерів відсутні команди бітового обміну між файловими регістрами та регістрами введення/виведення. Для читання портів використовують команди завантаження байтів
in Rd, PINx,
де: “ Rd ” – один з файлових регістрів.
Не допускається виконання логічних та арифметичних операцій безпосередньо на регістрах PINx. Такі операції можливі лише з файловими регістрами.
Разом з тим існує можливість реалізації програмних розгалужень на підставі аналізу стану окремих ліній портів PINx, за рахунок використання команд пропуску
sbic PINx,bit, sbis PINx,bit .
6.2.4 Ввід цифрових сигналів, що формуються контактною парою
Для введення сигналів, що формуються контактною парою, часто використовують наступний алгоритм:
Проводиться первинний опит стану порту. У разі виявлення замкненого стану контактів формується затримка, час якої перевищує час тремтіння контактів;
Проводиться вторинний опит стану порту на підставі якого приймається рішення про стан контактної пари.
Нижче приведено приклад програми, де вводиться цифровий сигнал від кнопки з тривалістю тремтіння контактів < 2 мс. Замкненому у стану контактів відповідає “0” , а розімкненому “1” рівень на лінії порту UP (PB3). Програма виконана без використання системи переривань. У прикладі не описані підпрограми затримки «DELAY_2ms» , та реакції на натиснення кнопки «KEY_REACTION». Перша підпрограма може бути побудована з використанням матеріалів другого прикладу. Реалізація другої підпрограми залежить від конкретних вимог до реакції на натиснення кнопки.
Приклад 5
;------------------------------------------------------------------
;Файл lab2.asm
;Процесор ATmega16-16PI, частота 10 МГц
;------------------------------------------------------------------
.include "m16def.inc" ;Файл опису процесора
;------------------------------------------------------------------
.equ ini_DDRB = 0 ;усі лінії налаштовані на прийом
.equ ini_PORTB = 0 ;відсутні внутрішні резистори-підтяжки
.equ KEY1 = (1<PB3) ;опис символічного імені кнопки
;------------------------------------------------------------------
.def TMP = R16 ;символічне ім`я регістру R16
;------------------------------------------------------------------
;------------------------------------------------------------------
;Програма
;------------------------------------------------------------------
.CSEG
.ORG 0
;-----------------------
init:
ldi TMP,ini_DDRB ;ініціалізація ліній порту "В" - прийом/передача
out DDRB,TMP
ldi TMP,ini_PORTB ;ініціалізація резисторів-підтяжок порту "В"
out PORTB,TMP
;------------------------------------------------------------------
;Основна програма
;------------------------------------------------------------------
MAIN:
rcall KEY ;підпрограма роботи з кнопкою
rjmp MAIN
;------------------------------------------------------------------
;------------------------------------------------------------------
;Підпрограма роботи із кнопкою
KEY:
KEY_1:
sbis PINB,KEY1 ;первинний опит стану кнопки
rjmp KEY_END
KEY_DELAY:
call DELAY_2ms ;затримка на час тремтіння контактів кнопки
KEY_KEY_2:
sbis PINB,KEY1 ;вторинний опит стану кнопки
rjmp KEY_END
KEY_WORK:
call KEY_REACTION ;виклик підпрограми реакції на натиснення кнопки
KEY_END:
ret
;------------------------------------------------------------------
.exit