Микроконтроллеры. Управление цифровыми портами AVR. Методические указания к лабораторным и практическим занятиям
.pdf
11
При относительной адресации памяти программ выполнение про-
граммы продолжается с адреса (PC + k + 1), где PC – содержимое программного счётчика; k – указанный в команде относительный адрес, который может принимать значения от –2048 до 2047. Относительная адресация памяти программ используется в командах RJMP и RCALL.
При адресации константы адрес байта константы содержится в регистре Z. Адресация константы в памяти программ используется в командах LPM (Load Program Memory), которая загружает адресованный регистром Z байт в указанный в команде регистр. Если регистр-приёмник не указан (команда используется без операндов), байт загружается в регистр R0. Команда ELPM (Extended Load Program Memory) служит для загрузки константы из памяти программ объёмом более 64К слов. При этом для расширения реги- стра-указателя Z используется регистр RAMPZ, связанный с регистром Z.
Задать данные в память программ позволяет директива .db (define bytes). Для того, чтобы на заданные ячейки памяти можно было ссылаться, директиве должна предшествовать метка. Параметры директивы – последовательность выражений, разделённых запятыми; каждое выражение должно быть числом в диапазоне –128…255 или в результате вычисления давать результат в этом же диапазоне, в противном случае число усекается до байта. Директива .db размещается в программном сегменте и может использоваться совместно с директивой .org. Задавать положение данных в памяти программ следует таким образом, чтобы была исключена возможность непреднамеренного перехода к выполнению их как команд микроконтроллера.
При адресации константы в памяти программ с постинкрементом
адрес байта константы содержится в регистре Z и формируется так же, как и при адресации константы. Адресованный регистром Z байт загружается в указанный регистр; после выполнения команды содержимое регистра Z инкрементируется. Адресация константы в памяти программ с постинкрементом используется в командах LPM и ELPM.
3.1.3.Программная модель цифровых портов AVR ATmega328
ВAVR-микроконтроллерах в зависимости от типа имеется от двух до шести универсальных двунаправленных портов ввода-вывода (порты A…F), содержащих семь или восемь сигнальных линий, которые соединены с соответствующими выводами БИС микроконтроллера. В микроконтроллере ATmega328 имеется три порта B, C и D. Сигнальные линии порта B обозначаются РB0…РB7, порта C – РC0…РC7 и т. д. Для МКК ATmega328 форматы параллельных портов показаны на рис.3.5.
С каждым портом связаны три регистра ввода-вывода:
- регистр направления передачи
данных DDRx (Data Direction Register - |
Рис.3.5. Форматы регистров |
|
|
|
ATmega328 |
12
регистр направления данных). Он задает направление передачи данных по каждой сигнальной линии порта (0 – разряд используется для ввода данных,
1– для вывода данных);
-регистр данных порта PORTx (Port - порт, канал). Он позволяет задавать состояние сигнальных линий порта при выводе информации;
-регистр выводов порта PINx (Pin - штырь, контакт). Он позволяет считывать состояние сигнальных линий порта при вводе информации.
Для МКК ATmega328 имена и адреса таких портов следующие (в скобках указаны адреса портов при обращении с помощью команд обмена с памятью):
PORTB=$05 ($25) |
PORTC=$08 ($28) |
PORTD=$0B ($2B) |
DDRB=$04 ($24) |
DDRC=$07 ($27) |
DDRD=$0A ($2A) |
PINB=$03 ($29) |
PINC=$06 ($26) |
PIND=$09 ($29) |
С помощью указанных регистров реализуется требуемый протокол обмена данными. Здесь под словом протокол понимается совокупность правил передачи или прима кодированной информации. Основными процедурами при реализации некоторого протокола являются операции инициализации порта, вывода данных в порт, ввода данных из порта, а также формирования временных задержек.
Для обращения к отдельным разрядам портов зарезервированы имена этих разрядов (х - это одно из имен портов: B, C, D):
-для регистра PINx: PINx0 ... PINx7;
-для регистра DDRx: DDx0 ... DDx7;
-для регистра PORTx: PORTx0 ... PORTx7 или Px0 ... Px7.
3.1.4. Инициализация цифрового порта и работа с ним
Инициализация порта состоит в назначении направления обмена данными по сигнальным линиям порта. Например, если сигнальные линии PB0, PB2, порта B служат для вывода данных, а сигнальные линии PB1 – для ввода данных, инициализация порта на языке ассемблера может быть произведена следующим образом:
ldi |
R16, 0b00000101 ;Присвоить константу регистру R16 |
|
out |
DDRB, R16 |
;Отправить константу в порт DDRB |
R16 - имя одного из РОН МКК старшей половины адресов. Именно старшие адреса РОН используются для записи константы.
13
Аналогичные действия на языке С:
DDRB=0x05 ;Присвоить константу 0b00000101 DDRB
Язык С двоичные константы не предусматривает, поэтому используется H-формат. Для использования двоичных чисел и переносимости файлов требуется заголовочный файл bit.h.
Вывод данных в порт производится путём записи значений в регистр PORTx. Например, на ассемблере:
ldi |
R16, 0b10011101 ;Запись выводимого байта в R16 |
out |
PORTB, R16 ; вывод содержимого регистра R16 |
|
;в порт B. |
Аналогичное действие на С:
PORTB=0x9D; //вывести константу 0b10011101 в DDRB
Для изменения состояния только одного разряда порта ввода-вывода удобно использовать команды установки SBI (Set Bit in I/O Register) и сброса CBI (Clear Bit in I/O Register) бита в регистре ввода-вывода. Например, на ассемблере:
sbi |
PORTD, PD4 |
; записать в 4-й бит порта D лог.1 |
cbi |
PORTD, PD4 |
; сброс 4-го бита порта D |
Для установки и гашения отдельных битов на языке С используются логические операции конъюнкции и дизъюнкции.
Установка 1 в разряд PD0:
PORTD = 0x1C; //Начальное значение 0b00011100 PORTD = PORTD | (1<<5); //Побитовая операция ИЛИ
PORTD |= 1<<5; //Аналог предыдущей строки
PORTD |= (2^5); //Еще один аналог
//Результат операции PORTD == 0x3С==0b00111100
Операция битового сдвига (1<<5) выполняет сдвиг 8-разрядного десятичного числа 1=0b00000001 на 5 разрядов влево. Она позволяет установить единицу в позицию нужного для установки разряда в диапазоне 0 -7. Важно, что такая процедура с указанной константой не изменяет состояние остальных разрядов порта PORTD.
14
Аналогичный результат получится, если исходное значение PORTD логически складывать с заранее подготовленной маской 0b00100000, но читаемость программы при этом ухудшается:
PORTD = PORTD | 0x20; //Побитовая операция ИЛИ
Еще один вариант решения этой задачи сводится к использованию функции побитового сдвига _BV(). Но функция не является стандартной и может быть непереносимой:
PORTD |= _BV(PD5); //Установка "1" на PD5
Сброс разряда выполняется на основе операции конъюнкции с маской, имеющей нуль в требуемом разряде. Нуль получается инвертированием маски, которая получена в предыдущих примерах. Для 5 разряда регистра D:
PORTD = 0x3C; //Начальное значение 0b00111100 PORTD = PORTD & (~ (1<<5)); //Побитовая операция И
PORTD &= ~ (1<<PD5);//Аналог предыдущей строки
PORTD &= ~(2^5); //Еще один аналог PORTD &= ~_BV(PD5); //С помощью функции
//Результат операции PORTD == 0x1С==0b00011100
Ввод данных из порта производится путём чтения содержимого регистра PINx выводов порта. Этот регистр контролирует состояние выводов порта непрерывно и независимо от режима ввода или вывода. Например, для чтение порта PINB на ассемблере:
in |
R16, PINB |
; считывание состояния порта B |
|
|
;в регистр R16 |
Аналогичное действие на языке С:
R16 = PINB; //Чтение порта В всех 8 разрядов
Для анализа отдельных бит конкретного порта следует использовать ранее рассмотренные поразрядные операции.
Регистр данных PORTx в зависимости от режима работы порта выполняет различные функции:
- если порт запрограммирован на вывод, то в нем хранятся выдаваемые данные;
15
- если порт запрограммирован на ввод, то 1 - подключает подтягивающий резистор;
0 - отключает подтягивающий резистор.
Варианты конфигурирования портов AVR можно свести в таблицу 3.1.
Таблица 3.1 Состояние элементов портов в различных режимах
Направление |
Данные |
|
Подключен. R |
|
Rподтяг |
Вывод |
||
DDRB |
PORTB |
|
PUD |
|
||||
|
|
|
|
|
||||
1 = вых |
D |
* |
|
|
Откл |
Вых = D |
||
0 = вход |
1 |
|
0=вкл |
|
Подключен |
Ист. тока |
||
|
|
|
1=откл |
|
|
Откл |
|
Z-состояние |
|
0 |
* |
|
|
Откл |
Z-состояние |
||
По умолчанию разряд PUD (Pull Up Disable) равен 0 (R – подтягивающий резистор подключен). PUD – 4-й разряд регистра MCUCR=$35 (MCU Control Register) - Общий регистр управления микроконтроллера.
3.1.5. Исходное состояние цифровых портов по умолчанию
После формирования команды RESTART исходное положение аппаратуры следующее:
-устройства выключены;
-порты запрограммированы на ввод (DDRx=0);
-подтягивающие резисторы подключены;
-значения разрядов обнулены.
3.1.6. Преимущества и недостатки прямого управления портами
Недостатки прямого управления портами:
1.Код более сложен для отладки и поддержки, низкая читабельность;
2.Может иметь проблемы при переносимости, т.к. контроллеры имеют особенности в структуре РВВ;
3.Возможны случайные изменения состояния выводов, выполняющих другие функции.
Однако применение прямого программирования портов обосновано при следующих обстоятельствах:
1.При ограничениях в объеме памяти и невозможности последовательного управления контактами одного регистра;
2.Необходимости изменять несколько выводов одновременно;
3.Высоких требованиях к скорости переключения контактов.
16
3.1.7. Цифровые порты ARDUINO
Цифровые порты МКК ATmega328 B,C и D позволяют считывать цифровые значения и устанавливать цифровой сигнал на выводе. Состояний только два. Высокое состояние (константа HIGH) соответствует напряжению на выходе порядка 5 В (реально более 3 В), низкое состояние (константа LOW) – 0 В (менее 1,5 В). Выход допускает подключение нагрузки с током до 40 мА.
Закрепление выводов цифровых портов МКК по контактам ARDUINO показаны на рис.3.6.
Из всех контактов трех портов отдельные из них используются для специальных задач:
-PD0 и PD1 используются для прошивки микроконтроллерах на плате
Arduino через USB;
-PC6 – используется для перезагрузки контроллера входным сигналом
RESET;
-PB6 и PB7 - задействованы для подключается внешнего кварцевого резонатора.
Остальные биты регистров можно использовать, если они не задействованы для активизации других устройств и их режимов. В цифровом режиме можно использовать контакты цифровой группы 2-13.
Задание 3.2. Выполнить этапы проектирования устройства на языке С
Основная цель этого задания заключается в практическом освоении всех этапов проектирования устройства, опираясь на готовый пример.
Необходимо разработать устройство управления одним светодиодом при помощи одной кнопки. При нажатии кнопки светодиод должен зажечься, при отпускании - погаснуть. Изменение состояния незадействованных выводов портов запрещается.
В отчете представить:
1.Схему подключения кнопки и светодиода;
2.Программу на языке С с необходимыми пояснениями;
3.Объем занятой программой памяти.
17
Рис.3.6. Закрепление выводов цифровых портов ATmega328 на плате ARDUINO
Этапы разработки:
1.Проектирование и сборка электрической схемы,
2.Разработка схемы алгоритма,
3.Создание и ввод программы,
4.Компиляция программы,
5.Отладка программы.
Последовательно в таком порядке необходимо выполнить все эти эта-
пы.
1. Проектирование и сборка электрической схемы
Разработка алгоритма управления опирается на конкретную схему аппаратных средств. Поэтому решение должно начинаться с разработки схемы. Предлагается создать схему, представленную на рис.3.7. Для этого задания достаточно будет кнопки SB1. Вторая кнопка потребуется для последующих заданий, пока ее можно не устанавливать.
18
Управление светодиодом и работа с кнопкой осуществляется с помощью портов. Светодиод подключается к порту PB4, настроенному на вывод, а кнопка SB1 к порту PD2, настроенному на ввод (см. рис.3.6).
Светодиод HL1 включен через токоограничивающий резистор R и зажигается при наличии единицы на выходе контакта PB.4. При появлении на этом выводе логической единицы потенциалы на светодиоде выравниваются, и он не светится. При необходимости зажигать светодиод низким потенциалом, его следовало подключить к положительному потенциалу питания.
Резистор рассчитывается по формуле:
Рис.3.7. Схема подключения кнопок и светодиода
I = (Uвыхода – Uпадения на светодиоде) / R.
Uвыхода = 5 В, Uпадения на светодиоде можно принять равным 1,5 В (точно указывается в справочнике). При R около 330 Ом ток через светодиод должен быть приблизительно 10 мА, что не превышает допустимого 40 мА.
В исходном состоянии контакты кнопки SB1 разомкнуты и через подключенный внутренний подтягивающий резистор на вход PD.2 подается плюс источника питания, что соответствует логической единице. При нажатии кнопки потенциал контакта падает до нуля, что соответствует логическому нулю. Это классическое подключение кнопки.
Вариант сборки схемы на монтажной плате показан на рис.3.8. Для этого задания кнопка SB2 не требуется. Внешние подтягивающие резисторы также следует не использовать, т.к. задействованы будут внутренние подтягивающие резисторы.
Шины "+" и "-" подключены от платы Arduino: контакты 5V и GND.
19
Рис.3.8. Задание 3.2 на макетной плате
2. Разработка схемы алгоритма управления светодиодом
Алгоритм работы контроллера по структуре типовой: выполнить операции начальной настройки. Далее в непрерывном цикле опрашивать кнопку и по ее состоянию управлять светодиодом.
Операции начальной настройки: 1. Настроить выход PВ4 на вывод;
2. Подать на выход РВ.4 нуль (потушить светодиод); 3. Сконфигурировать вывод PD2 на ввод;
4. Подключить к PD4 подтягивающий резистор.
Операции тела цикла:
5. Прочитать состояние кнопки: разряда PD.2;
6. Если состояние разряда равно единице (кнопка не нажата), выключить светодиод;
7. Если значение разряда PD.2 равно нулю (кнопка нажата), включить светодиод;
9. Перейти на начало цикла.
20
3. Создание и ввод программы
Структура программы управления светодиодом на языке С может иметь следующий вид.
//Программа включения и отключения (PD2) светодиода (PB4)
//Файлы описаний
//Блок инициализации
void setup() // начало основной программы
{ |
|
|
DDRB = DDRB | (1<<4); |
//PB4 на выход |
|
PORTB &= |
(1<<PB4); |
//0 на PB4 (выключить HL1) |
DDRD &= ~ (1<<PD2); |
//PD2 настроить на ввод |
|
PORTD |= 1<<PD2; |
// вкл подтягивающий R |
|
void loop() |
//Открывается бесконечный цикл |
|
{ if (! (PIND & (1<<PD2))) |
// Если PD2=0 (SB1 нажата) |
|
PORTB |= 1<<PB4; |
//PB4=1 (HL1 включен) } |
|
else PORTB &= ~(1<<PB4); |
//PB4=0 (HL1 выключен) |
|
_delay_ms(30); |
//Ожидание 30 мс для |
|
|
|
//исключения дребезга |
} |
|
|
После присоединения файла описаний размещается описание глобальных переменных.
Настройка системы по умолчанию производится автоматически после системного сброса. Однако включение команд начальной настройки обеспечивает правильную работу программы в случае ошибки программы и передачи управления на начало программы, а также при срабатывании сторожевого таймера. Однако такая работа обеспечивается при настройке таблицы векторов.
Далее задается непрерывный цикл. Это обязательный элемент программы любого микроконтроллера. Он работает до выключения МКК.
Для ввода программы следует подключить плату к компьютеру с интернетом через USB-кабель. Распознавание источника питания происходит автоматически (USB либо внешний источник). Должен загореться зеленый светодиод (с маркировкой ON), показывающий, что на плату поступает питание.
