Для проверки правильности воздействия прошивки на периферийные устройства удобно использовать программу Proteus. В окне эмулятора Proteus (рис. 2.3) показана эмуляция стенда с ЖКИ, матричной клавиатурой, светодиодами, подключенными к PortG, и светодиодным 7-сегментным дисплеем. Данный инструмент позволяет создавать различные электронные схемы для симуляции.
2.3. Директивы в Assembler
1.Исходные коды
Компилятор работает с исходными файлами, содержащими инструкции, метки и директивы. Инструкции и директивы, как правило, имеют один или несколько операндов.
Строка кода не должна быть длиннее 120 символов.
Рис. 2.3. Окно эмулятора Proteus
Любая строка может начинаться с метки, которая является набором символов, заканчивающимся двоеточием. Метки используются для указания места, в которое передается управление при переходах, а также для задания имен переменных.
Входная строка может иметь одну из четырех форм:
- [метка:] директива [операнды] [Комментарий]
- [метка:] инструкция [операнды] [Комментарий]
- Комментарий
- Пустая строка
Комментарий имеет следующую форму:
; [Текст]
Позиции в квадратных скобках необязательны. Текст после точки с запятой (;) и до конца строки игнорируется компилятором. Метки, инструкции и директивы более детально описываются ниже.
label:.EQU var1=100 | ; Устанавливает var1 равным 100 (директива) |
.EQU var2=200 | ; Устанавливает var2 равным 200 |
; Строка с одним только комментарием |
Компилятор не требует, чтобы метки, директивы, комментарии или инструкции находились в определенной колонке строки.
2. Резервирование байтов в ОЗУ
Директива BYTE резервирует байты в ОЗУ. Если вы хотите иметь возможность ссылаться на выделенную область памяти, то директива BYTE должна быть предварена меткой. Директива принимает один обязательный параметр, который указывает количество выделяемых байт. Эта директива может использоваться только в сегменте данных (см. директивы CSEG и DSEG). Выделенные байты не инициализируются.
Синтаксис:
МЕТКА:.BYTE выражение
Пример:
.DSEG | |
var1:.BYTE 1 | ; Резервирует 1 байт для var1 |
table:.BYTE tab_size | ; Резервирует tab_size байт |
.CSEG | |
ldi r30,low(var1) | ; Загружает младший байт регистра Z |
ldi r31,high(var1) | ; Загружает старший байт регистра Z |
ld r1,Z | ; Загружает VAR1 в регистр 1 |
3. Программный сегмент
Директива CSEG определяет начало программного сегмента. Исходный файл может состоять из нескольких программных сегментов, которые объединяются в один программный сегмент при компиляции. Программный сегмент является сегментом по умолчанию. Программные сегменты имеют свои собственные счетчики положения, которые считают не побайтно, а пословно. Директива ORG может быть использована для размещения кода и констант в необходимом месте сегмента. Директива CSEG не имеет параметров.
Синтаксис:
.CSEG
Пример:
.DSEG | |
vartab:.BYTE 4 | ; Резервирует 4 байта в ОЗУ |
.CSEG | ; Начало кодового сегмента |
const:.DW 2 | ; Разместить константу 0x0002 в памяти; программ |
mov r1,r0 | ; Выполнить действия |
4. Назначение регистру символического имени
Директива DEF позволяет ссылаться на регистр через некоторое символическое имя. Назначенное имя может использоваться во всей нижеследующей части программы для обращений к данному регистру. Регистр может иметь несколько различных имен. Символическое имя может быть переназначено позднее в программе.
Синтаксис:
.DEF Символическое_имя = Регистр
Пример:
.DEF temp=R16 | |
.DEF ior=R0 | |
.CSEG | |
ldi temp,0xf0 | ; Загрузить 0xf0 в регистр temp (R16) |
in ior,0x3f | ; Прочитать SREG в регистр ior (R0) |
eortemp,ior | ; Регистры temp и ior складываются по ; исключающему ИЛИ |
5. Сегмент данных
Директива DSEG определяет начало сегмента данных. Исходный файл может состоять из нескольких сегментов данных, которые объединяются в один сегмент при компиляции. Сегмент данных обычно состоит только из директив BYTE и меток. Сегменты данных имеют свои собственные побайтные счетчики положения. Директива ORG может быть использована для размещения переменных в необходимом месте ОЗУ. Директива не имеет параметров.
Синтаксис:
.DSEG
Пример:
.DSEG | ; Начало сегмента данных |
var1:.BYTE 1 | ; зарезервировать 1 байт для var1 |
table:.BYTE tab_size | ; зарезервировать tab_size байт. |
.CSEG | |
ldi r30,low(var1) | ; Загрузить младший байт регистра Z |
ldi r31,high(var1) | ; Загрузить старший байт регистра Z |
ld r1,Z | ; Загрузить var1 в регистр r1 |
6. Установка постоянного выражения
Директива EQU присваивает метке значение. Эта метка может позднее использоваться в выражениях. Метка, которой присвоено значение данной директивой, не может быть переназначена и ее значение не может быть изменено.
Синтаксис:
.EQU метка = выражение
Пример:
.EQU io_offset = 0x23
.EQU porta = io_offset + 2
.СSEG | ; Начало сегмента данных |
clr r2 | ; Очистить регистр r2 |
out porta,r2 | ; Записать в порт A |
7. Вложение файла
Встретив директиву INCLUDE, компилятор открывает указанный в ней файл, компилирует его, пока файл не закончится или не встретится директива EXIT, после этого продолжает компиляцию начального файла со строки, следующей за директивой INCLUDE. Вложенный файл может также содержать директивы INCLUDE.
Синтаксис:
.INCLUDE "имя_файла"
Пример:
; Файл iodefs.asm:
.EQU sreg = 0x3f; Регистр статуса
.EQU sphigh = 0x3e; Старший байт указателя стека
.EQU splow = 0x3d; Младший байт указателя стека
; Файл incdemo.asm
.INCLUDE iodefs.asm; Вложить определения портов
in r0,sreg; Прочитать регистр статуса
Практическая часть
2.4. Контрольные вопросы
1. Сколько команд включает система команд микроконтроллера?
2. На какие группы разделены эти команды?
3. Как длительность машинного цикла микроконтроллера соотносится с его тактовой частотой?
4. С какими типами данных может оперировать микроконтроллер?
5. Укажите назначение флагов регистра SREG.
6. Может ли порт одновременно являться источником операнда и приемником результата операции?
7. Какие способы адресации используются в микроконтроллере?
8. Приведите примеры логических и арифметических команд.
9. Как инвертировать отдельные биты портов?
10. Какие переходы возможны в командах управления?
11. Поясните отличия длинного, абсолютного и относительного переходов в программах.
12. Как организовать процедуру ожидания с помощью одной команды?
13. Какие команды используются при организации подпрограмм?
2.5. Варианты заданий
1. Загрузить в регистр R16 число 15, сложить его с 25 и результат поместить на вершину стека. Поместить по адресу 020h внутренней памяти данных младшую десятичную цифру результата, а по адресу 021h – старшую.
2. Найти разницу чисел 4836 и 232. Младший байт результата поделить на 2. Поместить по адресу 025h внутренней памяти данных младший байт, а по адресу 030h старший байт результата.
3. Найти адрес ячейки памяти данных путем перемножения двух чисел 0Сh и 0Eh. В эту ячейку записать результат логической операции «исключающее ИЛИ» между текущим содержимым регистра R0 и числа 09h.
4. Найти частное чисел 236 и 59. Результат умножить на 23, используя операции сдвига. По вычисленному таким образом адресу ячейки внутренней памяти данных разместить результат двойного декремента полученного числа.
5. В младшую тетраду порта PORTB вывести число десятков от числа 044h. Старшую тетраду необходимо оставить без изменений.
6. Загрузить регистр R17 числом 023h. Найти сумму R17+SREG. В ячейку внутренней памяти данных, расположенную по вычисленному таким образом адресу, загрузить число десятичных единиц результата сложения.
7. Найти сумму чисел 9701 и 32. Младший байт результата умножить на 4. Поместить старший байт в порт PORTC. Сбросить младшую тетраду байта порта.
8. Вычислить значение выражения (81+64)*(112–25) OR 10011010b, сохраняя промежуточные результаты в стеке.
9. Загрузить в регистр R18 число 112, вычесть из него число 18 и результат поместит на вершину стека. Поместить по адресу 020h внутренней памяти данных младшую десятичную цифру результата, а по адресу 021h – старшую.
10. Найти разницу чисел 4801 и 209. Число десятичных единиц старшего байта результата поместить в старшую тераду порта PORTD. Младшую тетраду оставить без изменений.
11. Загрузить регистр R19 числом 0Аh. Найти произведение 8*R19. Результат разделить на 4, используя операции сдвига. В две ячейки внутренней памяти данных, начиная с ячейки, расположенной по вычисленному таким образом адресу, загрузить число 023Е8h.
12. В ячейки внутренней памяти данных 128h, 129h, 12ah занести число сотен, десятков, единиц числа 080h.
13. Вычислить младший байт адреса ячейки внутренней памяти данных 7ХХh как произведение 0А1h и 7, поместить по этому адресу значение выражения NOT (0101001b OR 74).
14. Вычислить значение выражения (72+56)*(122–15) XOR 01010011b, сохраняя промежуточные результаты в стеке.
15. Найти среднее арифметическое чисел 012h, 033h, 0Ah. Результат умножить на 22, используя операции сдвига. Младшую тераду полученного числа разместить в старшей тетраде порта Р1, а старшую – в младшей.
Содержание отчета по лабораторной работе: цель работы, задание, листинг программы, вывод.
ЛАБОРАТОРНАЯ РАБОТА №3
ИСПОЛЬЗОВАНИЕ ПОДПРОГРАММ И ВЕКТОРОВ ПРЕРЫВАНИЙ, СБРОС И ОБРАБОТКА ПРЕРЫВАНИЙ
Цель работы. Ознакомиться с использованием подпрограмм, порядком обработки прерываний, разрешением и запретом прерываний, изучить размещение прерываний.
В ходе выполнения работы необходимо:
– изучить понятия прерываний и подпрограмм;
– разработать программу в соответствии с индивидуальным заданием;
– отладить программу в среде Atmel«AVRStudio»;
– загрузить программу в учебный стенд НТЦ-31.100;
– исследовать адресацию при обработке прерываний и использовании подпрограмм;
– оформить отчет по лабораторной работе.
Теоретическая часть
3.1. Подпрограммы
Когда один и тот же участок кода часто повторяется, то разумно как-то его вынести и использовать многократно. Это дает колоссальный выигрыш по объему кода и удобству программирования.
Вот, например, кусок кода, передающий в регистр UDR байты с некоторой выдержкой, выдержка делается за счет вращения бесконечного цикла:
.CSEG Start: M1: M2: M3: | LDI R16,Low(RAMEND) OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 .equ Byte = 50 .equ Delay = 20 LDI R16,Byte OUT UDR,R16 LDI R17,Delay DECR17 NOP BRNEM1 OUTUDR,R16 LDI R17,Delay DEC R17 NOP BRNE M2 OUT UDR,R16 LDI R17,Delay DEC R17 NOP BRNEM3 RJMP Start | ; Инициализация стека ; Загрузили значение ; Выдали его в порт ; Загрузили длитель-; ность задержки ; Уменьшили на 1 ; Пустая операция ; Длительность не ; равна 0? ; Переход если не 0 ; Выдали значение; в порт ; Аналогично ; Зациклим программу |
Сразу напрашивается повторяющийся участок кода вынести за скобки.
M2: | LDI R17,Delay DEC R17 NOP BRNE M2 |
Для этих целей есть группа команд перехода к подпрограмме CALL (ICALL, RCALL, CALL) и команда возврата из подпрограммы RET.
В результате получается следующий код:
.CSEG Start: Wait: M1: | LDI R16,Low(RAMEND) OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 .equ Byte = 50 .equ Delay = 20 LDI R16,Byte OUT UDR,R16 RCALL Wait OUT UDR,R16 RCALL Wait OUT UDR,R16 RCALL Wait OUT UDR,R16 RCALL Wait RJMP Start LDI R17,Delay DEC R17 NOP BRNE M1 RET | ; Инициализация стека ; Загрузили значение ; Выдали его в порт ; Зациклим программу |
Как видно, программа значительно сократилась в размерах. Чем больше количество повторений, тем более явным становится очевидное преимущество такой замены.
Если речь идет о повторении малого участка кода, то, вероятно, более оптимальным вариантом написания кода будет использование макросов.
3.2. Вектора сброса и прерываний
Наименьшие адреса в памяти программ по умолчанию определены как вектора сброса и прерываний. Полный перечень векторов приведен в табл. 3.1. В перечне также определяется уровень приоритетов различных прерываний. Меньшие адреса обладают более высоким уровнем, приоритетом.
Сброс (RESET) имеет наивысший приоритет, за ним следует INT0 запрос на внешнее прерывание по входу INT0. Векторы прерывания могут быть перемещены в начало загрузочного сектора FLASH-памяти установкой бита IVSEL в регистре управления микроконтроллером (MCUCR). Вектор сброса может быть также перемещен в начало загрузочного сектора флэш-памяти путем программирования конфигурационного бита BOOTRST.
После возникновения прерывания бит I общего разрешения прерываний сбрасывается, и все прерывания запрещаются. Пользователь может программно записать логическую «1» в бит I для разрешения вложенных прерываний. В этом случае все разрешенные прерывания могут прервать текущую процедуру обработки прерываний. Бит I автоматически устанавливается после выполнения инструкции выхода из прерывания RETI.
Имеются два основных типа прерываний. Первый тип прерываний активизируется событием, которое приводит к установке флага прерываний. Для данных прерываний программный счетчик изменяется на соответствующий вектор прерывания для выполнения процедуры его обработки и затем аппаратно очищает флаг прерывания. Флаги прерывания также сбрасываются путем записи логической «1» в соответствующий разряд. Если возникает условие прерывания, но данное прерывание запрещено, то флаг устанавливается и запоминается до разрешения этого прерывания или сбрасывается программно.
Аналогично, если возникает одно и более условий прерываний при сброшенном флаге общего разрешения прерываний, то соответствующий флаг устанавливается и запоминается до возобновления работы прерываний, а затем прерывания будут выполнены в соответствии с приоритетом.
Второй тип прерываний активизируется сразу после выполнения условия прерывания. Данные прерывания не обязательно имеют флаги прерываний. Если условие прерывания исчезает до его разрешения, то данный запрос игнорируется. После выхода из прерывания AVR-микроконтроллер возвращается к выполнению основной программы и выполняет еще одну инструкцию до обслуживания любого из отложенных прерываний.
Необходимо обратить внимание, что регистр статуса автоматически не запоминается при вызове процедуры обработки прерывания и не восстанавливается при выходе из этой процедуры. Данные действия необходимо выполнить программно.
При выполнении инструкции CLI все прерывания запрещаются. Запрос на прерывание не будет отработан после выполнения инструкции CLI, даже если оно возникает одновременно с выполнением команды CLI.
Таблица 3.1
Векторы сброса и прерываний
Номер вектора | Адрес памяти программ | Источник | Условие возникновения прерывания |
$0000 | RESET | Внешний сброс, сброс при подаче питания, сброс при недопустимом снижении питания, сброс сторожевым таймером и сброс через JTAG-интерфейс | |
$0002 | INT0 | Запрос на внешнее прерывание 0 | |
$0004 | INT1 | Запрос на внешнее прерывание 1 | |
$0006 | INT2 | Запрос на внешнее прерывание 2 | |
$0008 | INT3 | Запрос на внешнее прерывание 3 | |
$000A | INT4 | Запрос на внешнее прерывание 4 | |
$000C | INT5 | Запрос на внешнее прерывание 5 | |
$000E | INT6 | Запрос на внешнее прерывание 6 | |
$0010 | INT7 | Запрос на внешнее прерывание 7 | |
$0012 | TIMER2 COMP | Срабатывание компаратора таймера-счетчика 2 | |
$0014 | TIMER2 OVF | Переполнение таймера-счетчика 2 | |
$0016 | TIMER1 CAPT | Захват фронта таймером-счетчиком 1 | |
$0018 | TIMER1 COMPA | Срабатывание компаратора А таймера-счетчика 1 | |
$001A | TIMER1 COMPB | Срабатывание компаратора В таймера-счетчика 1 | |
$001C | TIMER1 OVF | Переполнение таймера-счетчика 1 | |
$001E | TIMER0 COMP | Срабатывание компаратора таймера-счетчика 0 |
Окончание табл. 3.1
$0020 | TIMER0 OVF | Переполнение таймера-счетчика 0 | |
$0022 | SPI, STC | Завершение последовательной передачи интерфейсом SPI | |
$0024 | USART0, RX | Завершение приема УСАПП 0 | |
$0026 | USART0, UDRE | Регистр данных УСАПП 0 свободен | |
$0028 | USART0, TX | Завершение передачи УСАПП 0 | |
$002A | ADC | Завершение преобразования АЦП | |
$002C | EE READY | Готовность ЭСППЗУ | |
$002E | ANALOG COMP | Аналоговый компаратор | |
$0030 | TIMER1 COMPC | Срабатывание компаратора С таймера-счетчика 1 | |
$0032 | TIMER3 CAPT | Захват фронта таймером счетчиком 3 | |
$0034 | TIMER3 COMPA | Срабатывание компаратора А таймера-счетчика 3 | |
$0036 | TIMER3 COMPB | Срабатывание компаратора В таймера-счетчика 3 | |
$0038 | TIMER3 COMPC | Срабатывание компаратора С таймера-счетчика 3 | |
$003A | TIMER3 OVF | Переполнение таймера счетчика 3 | |
$003C | USART1, RX | Завершение приема УСАПП 1 | |
$003E | USART1, UDRE | Регистр данных УСАПП 1 свободен | |
$0040 | USART1, TX | Завершение передачи УСАПП 1 | |
$0042 | TWI | 2-проводной последовательный интерфейс | |
$0044 | SPM READY | Готовность записи в память программ |
3.3. Время реакции на прерывание
Реакция на отработку запроса на прерывание длится минимум 4 машинных цикла. По истечении этого времени программа продолжает свое выполнение с вектора соответствующего прерывания. В течение 4 машинных циклов состояние программного счетчика помещается в стек. Как правило, по адресу вектора прерываний хранится команда перехода на процедуру обработки прерываний, а на данный переход затрачивается еще 3 машинных цикла. Если запрос на прерывание возникает в процессе исполнения инструкции, требующей более 1 машинного цикла на выполнение, то прерывание будет обработано только после выполнения этой инструкции. Если прерывание возникает во время нахождения микроконтроллера в режиме сна, то реакция на прерывание увеличится еще на 4 цикла. Данная задержка связана со временем старта из выбранного режима сна.
Выход из процедуры обработки прерывания требует 4 машинных цикла. В течение этого времени 2-байтный программный счетчик извлекается из стека, указатель стека дважды инкрементируется и устанавливается бит I в регистре статуса SREG.
3.4. Пример написания программы
Рассмотрим программу, выполняющую запись единиц в регистры R16, R17, R18 при падающем фронте на входе PE6 (INT6). Регистры, используемые в программе, и принципы задания условий генерации запроса на прерывание представлены в табл. 3.2–3.5.
Таблица 3.2
Регистр маски прерывания EIMSK
Разряд | ||||||||
Имя | INT7 | INT6 | INT5 | INT4 | INT3 | INT2 | INT1 | INT0 |
Чтение/запись | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп |
Исходное значение |
Если в биты INT0–INT7 и в бит I регистра статуса SREG записать логическую «1», то разрешается работа внешнего прерывания по соответствующему выводу. Биты выбора условия генерации прерывания в регистрах управления внешними прерываниями EICRA и EICRB определяют, по какому условию генерируется прерывание: по нарастающему фронту, по падающему фронту или по уровню. Любой из данных выводов сохраняет активность, даже если он настроен на вывод. Данная особенность может использоваться для программной генерации прерывания.
Таблица 3.3
Расширенный регистр маски прерывания EТIMSK
Разряд | ||||||||
Имя | – | – | TICIE3 | OCIE3A | OCIE3B | TOIE3 | OCIE3C | TOIE3C |
Чтение/запись | Чт | Чт | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп |
Исходное значение |
Таблица 3.4
Расширенный регистр маски прерывания таймера-счетчика EICRB
Разряд | ||||||||
Имя | ICS71 | ICS70 | ICS61 | ICS60 | ICS51 | ICS50 | ICS41 | ICS40 |
Чтение/запись | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп | Чт/Зп |
Исходное значение |
Внешние прерывания 7–4 активизируются через внешние выводы INT7–INT4, если установлены флаг I в регистре статуса SREG и соответствующая маска прерывания в регистре EIMSK. Условие, по которому генерируется прерывание, выбирается исходя из данных табл. 3.5. Для определения фронтов на выводах INT7–INT4 осуществляется выборка их состояний. Если выбрано прерывание по фронту или изменению уровня, то прерывание будет сгенерировано, при условии, что на входе появляется импульс, длительность которого больше одного периода синхронизации. При действии на входе более коротких импульсов генерация прерывания не гарантируется. Необходимо обратить внимание, что частота синхронизации ЦПУ может быть ниже, чем частота XTAL, если разрешена работа делителя частоты XTAL. Если выбрано прерывание по низкому уровню, то прерывание генерируется, при условии, что до момента окончания выполнения текущей инструкции на входе по прежнему присутствует низкий уровень. Если разрешено прерывание по уровню, то оно будет генерироваться непрерывно до тех пор, пока на входе присутствует низкий уровень.
Таблица 3.5
Задание условия генерации запроса на прерывание
ISCN1 | ISCN0 | Описание |
Низкий уровень на INTn генерирует запрос на прерывание | ||
Любое изменение логического состояния на INTn генерирует запрос на прерывание | ||
Падающий фронт, выявленный по двум выборкам на INTn, генерирует запрос на прерывание | ||
Нарастающий фронт, выявленный по двум выборкам на INTn, генерирует запрос на прерывание |
Листинг программы
.include "m128def.inc"
.dseg
.org $0100
.cseg
.org $0000
jmp Init
.org $000e ;Вектор прерываний по входу PE6 (INT6)
jmp int_666
Init:
ldi r16,low(ramend)
out spl,r16
ldi r16,high(ramend)
out sph,r16
; Установка условия генерации прерывания по заднему фронту
ldi r16,0b00100000
out EICRB,r16
ldi r16,0b01000000 ;Регистр маски внешних прерываний
out EIMSK,r16
clr r16
cbi ddre,6
sei
gogogo:
nop
nop
nop
nop
nop
jmp gogogo
int_666:
ldi r16,1
ldi r17,1
ldi r18,1
reti
При пошаговом выполнении для генерации прерывания необходимо установить и сбросить 6-й бит PINE (рис. 3.1).
Рис. 3.1. Окно I/O View
Практическая часть
3.5. Контрольные вопросы
1. Назовите примеры применения подпрограмм.
2. Опишите синтаксис написания подпрограммы и укажите, какие команды в ней используются?
3. Назначение стека при работе с подпрограммой и порядок его инициализации.
4. Назовите отличия команды CALL от RCALL.
5. Как определяется приоритет при обработке прерываний, и как он влияет на работу микроконтроллера?
6. Перечислите основные векторы сброса и прерываний.
7. Какие действия производит микроконтроллер непосредственно перед обработкой прерывания?
8. Назовите примеры применения прерываний в программировании микроконтроллера.
3.6. Варианты заданий
1.Загрузить в регистр R16 число 73521. Вычислить результат от деления содержимого регистра на 3. Для оптимизации пользоваться подпрограммами.
2. Загрузить в регистр R18 число 48411. Вычислить результат от деления содержимого регистра на 3. Для оптимизации пользоваться подпрограммами.
3. Загрузить в регистр R20 число 76758. Вычислить результат от деления содержимого регистра на 6. Для оптимизации пользоваться подпрограммами.
4. Загрузить в регистр R22 число 4716. Вычислить результат от деления содержимого регистра на 6. Для оптимизации пользоваться подпрограммами.
5. Загрузить в регистр R17 число 95123. Вычислить результат от деления содержимого регистра на 7. Для оптимизации пользоваться подпрограммами.
6. При появлении положительного фронта на порте ввода-вывода PE4 найти произведение чисел 24 и 41, при отрицательном фронте на входе – вычесть из результата 100.
7. При появлении положительного фронта на порте ввода-вывода PE4 найти произведение чисел 27 и 38, при отрицательном фронте на входе – вычесть из результата 56.
8. При высоком уровне сигнала на входе PE6 инкрементировать R17, при низком – уменьшить значение на 2.
9. При высоком уровне сигнала на входе PD1 инкрементировать R18, при низком – уменьшить значение на 2.
10. При переполнении таймера-счетчика 0 записать 100 в регистр R16.
11. При переполнении таймера-счетчика 0 записать 255 в регистр R21.
12. При появлении положительного фронта на входе PE5 запустить таймер-счетчик 0.
13. При появлении положительного фронта на входе PD3 запустить таймер-счетчик 0.
14. При появлении отрицательного фронта на входе PE7 увеличивать значение в стеке на 1.
15.При появлении отрицательного фронта на входе PD0 увеличивать значение в стеке на 1.
Содержание отчета по лабораторной работе: цель работы, задание, листинг программы, вывод.
ЛАБОРАТОРНАЯ РАБОТА №4
ИССЛЕДОВАНИЕ УСТРОЙСТВА ДИНАМИЧЕСКОЙ ИНДИКАЦИИ
Цель работы. Ознакомиться с документацией на устройство динамической индикации, изучить схему сопряжения микроконтроллера с устройством динамической индикации, разработать и отладить программу вывода информации на устройство динамической индикации.
Перед началом выполнения лабораторной работы необходимо изучить следующие вопросы:
– способы построения цифровой индикации;
– устройства динамической индикации;
– устройства статической индикации.
В ходе выполнения работы необходимо:
– изучить электрическую принципиальную схему к лабораторной работе;
– разработать программу в соответствии с индивидуальным заданием;
– отладить программу в среде Atmel «AVRStudio»;
– загрузить программу в учебный стенд НТЦ-31.100;
– исследовать работу динамической индикации в соответствии с индивидуальным заданием;
– оформить отчет.
После выполнения лабораторной работы необходимо ответить на контрольные вопросы.
Теоретическая часть
4.1. Устройства цифровой индикации
Для отображения цифровой индикации наиболее распространены светодиодные 7-сегментнтые индикаторы (рис. 4.1).
Рис. 4.1. 7-сегментный символьный индикатор
Сегменты индикатора расположены в виде восьмерки. Иногда добавляют еще один восьмой сегмент – десятичную запятую. Засвечивая группы сегментов, можно получить все цифры и некоторые символы. Конструктивно индикаторы оформляются в виде светодиодных модулей с общим катодом или с общим анодом, как в учебном стенде НТЦ-31.100 (рис. 4.2).
Рис. 4.2. Электрические принципиальные схемы 7-сегментных индикаторов:
а – с общим анодом; б – с общим катодом
При построении систем отображения информации различают два подхода: статическая и динамическая индикация.
Статическая индикация состоит в постоянной засветке каждого индикатора от одного источника информации (рис. 4.3). В такой системе каждый индикатор подключен через свой дешифратор и регистр-защелку (R1–R3) к шине данных. Каждый регистр адресуется с помощью устройства дешифрации адреса (DC1–DC2). Такая схема предполагает значительные аппаратные затраты, так как на каждый индикатор необходим по крайней мере один регистр.
Рис. 4.3. Устройство статической индикации
Сущность динамической индикации заключается в поочередном циклическом подключении каждого индикатора к источнику данных (RD) (рис. 4.4). При использовании такой схемы включения значительно сокращаются аппаратные затраты. Но при этом необходимо обеспечить достаточное время свечения для того, чтобы не уменьшалась яркость свечения индикаторов. С другой стороны, необходимо обеспечить достаточно быстрое переключение индикаторов, чтобы не было заметно мерцания. В обоих случаях 7-егментные дешифраторы из схемы индикации можно исключить, а функцию дешифрации переложить на микроконтроллер, что, с одной стороны, несколько усложнит программную реализацию индикации, но при этом можно выводить на индикацию не только цифры, но и другие символы.
Рис. 4.4. Устройство динамической индикации
4.2. Электрическая принципиальная схема
В приложении 2 изображена электрическая принципиальная схема к данной лабораторной работе.
В схеме использован параллельный регистр DD2 1594ИР37 (74ACT574) для подключения к микроконтроллеру сегментов символьного светодиодного индикатора. Для организации параллельной шины данных используется 8‑битный порт PA микроконтроллера. Для защелкивания информации в регистре используется порт PC.3. Для переключения разрядов индикаторов ССИ используются транзисторные ключи VT1–VT8, управляемые выходами микросхемы DD3 дешифратора HC138. Для управления дешифратором используются выходы порта микроконтроллера PC.0 – PC.2.
В стенде НТЦ-31.100 организована последовательная шина. Для выбора конкретного устройства на шине используется набор сигналов CS0–CS7. Эти сигналы формируются на выходах дешифратора DD4 74HC138 (К1564ИД7). Для формирования кода выбираемого устройства используются порты PB.0, PB.4 и PB.5. Для защелкивания информации из сдвигового регистра в выходной регистр-защелку в 74HC595 применяется сигнал LC (где активный фронт – передний), а для формирования этого сигнала – сигнал CS2. Для ввода информации с дискретных источников (тумблеров SW1–SW8) используется микросхема DD13 сдвигового регистра с параллельной загрузкой HCT165 (К5564ИР9). Порт PB.3 применяется для приема информации в последовательной форме из микроконтроллера, а порт PB.1 – для тактирования сдвигового регистра.
4.3. Пример программы «бегущая» строка
.include "m128def.inc"
.equ Sgm_A = 0b01111111
.equ Sgm_B = 0b10111111
.equ Sgm_D = 0b11011111
.equ Sgm_E = 0b11101111
.equ Sgm_F = 0b11110111
.equ Sgm_C = 0b11111011
.equ Sgm_H = 0b11111101
.equ Sgm_G = 0b11111110
.cseg
.org 0
jmp INIT
.equ SymbolB = (Sgm_A&Sgm_C&Sgm_D&Sgm_E&Sgm_F&Sgm_G)
.equ SymbolS = (Sgm_A&Sgm_E&Sgm_F)
.equ SymbolU = (Sgm_B&Sgm_C&Sgm_D&Sgm_F&Sgm_G)
.equ SymbolI = (Sgm_B&Sgm_C&Sgm_D&Sgm_E&Sgm_F)
.equ SymbolR = (Sgm_A&Sgm_B&Sgm_E&Sgm_F&Sgm_G)
String:.DB ;Отображаемый на дисплее текст
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,SymbolR,SymbolI,SymbolU,SymbolS,SymbolB,0xFF,0xFF,0xff,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xff,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xff,0xFF,0xFF,0xFF,0xFF,0xFF
INIT: ldi R16,0xFF out ddrA,R16 | ;Настройка порта А на передачу |
ldi R16,0b00001111
out ddrC,R16 ;Настройка младшей тетрады порта С на передачу
;Предварительный сброс вспомогательных регистров и регистров-счетчиков
clr R17
clr R18
clr r19
clr r20
clr r25
clr r24
clr r23
clr r22
clr r21
ldi R28,low(String) ;Инициализируется массив
ldi R29,high(String)
lsl R28
rol R29
ldi r20,0x1f ;Перемещаем указатель массива в его конец
add r28,r20
Start:
out portC,R17 ;Задаем номер сегмента
mov R30,R28 ;Копируем адрес элемента массива в регистр Z
mov R31,R29
add R30,R17
adc R31,R18
lpm R2,Z ;Копируем элемент массива с адресом Z в регистр R2
out portA,R2 ;Задаем элемент массива в сегмент
cbi portC,3 ;Задаем отрицательный фронт на синхровходе
;дешифратора для зажигания диодов
sbi portC,3
dec R19 ;Создаем задержку
brne PC-1
ldi R16,0xFF ;Гасим сегмент
out portA,R16
cbi portC,3
sbi portC,3
inc R17 ;Увеличиваем номер сегмента
andi R17,7 ;Ограничиваем номер (не более семи)
dec r25 ;Создаем задержку движения строки
brne pc-1
dec r24
brne pc-1
dec r23
brne pc-1
dec r22
brne pc-1
dec r21
brne start
dec r28 ;Уменьшаем адрес на единицу
dec r20 ;Уменьшаем счетчик адреса на единицу
brne start ;Пока счетчик адреса не обнулится – возвращаться на
;старт
ldi r20,0x1f ;Задаем верхнее значение счетчика
add r28,r20 ;Возвращаем указатель на конец массива
jmp start ;Возвращаемся на старт
Вид исполняемой программы в симуляторе Proteus показан на рис. 4.5.
Рис. 4.5. Окно симулятора Proteus
Практическая часть
4.4. Контрольные вопросы
1. Каков принцип построения светодиодных индикаторов?
2. Поясните сущность статической индикации.
3. Поясните сущность динамической индикации.
4. Каков порядок инициализации микроконтроллера для работы с 7‑сегментным дисплеем в стенде НТЦ 31.100?
5. Приведите пример последовательности вывода символов на 7‑сегментный дисплей?
6. Каково назначение дешифратора в схеме вывода информации на 7‑сегментный дисплей?
7. Как реализуется «бегущая» строка?
4.5. Варианты заданий
Разработать программу для учебного стенда НТЦ-31.100, выводящую на светодиодный 7-сегментный индикатор бегущую строку, содержащую следующую информацию:
1. Последовательность цифр от 0h до Fh с пробегом строки справа-налево.
2. Последовательность цифр от Fh до 0h с пробегом строки справа-налево.
3. Последовательность цифр от 0h до Fh с пробегом строки слева-направо.
4. Последовательность цифр от Fh до 0h с пробегом строки слева-направо.
5. «BSUIR-xxxxxx», где xxxxxx – номер вашей группы с пробегом строки справа-налево.
6. «BSUIR-xxxxxx», где xxxxxx – номер вашей группы с пробегом строки слева-направо.
7. «BSUIR-xxxxxx», где xxxxxx – текущая дата в формате ДД.ММ.ГГГГ с пробегом строки слева-направо.
8. «BSUIR-xxxxxx», где xxxxxx – текущая дата в формате ГГГГ.ММ.ДД с пробегом строки справа-налево.
9. Число π с точностью до десятого знака с пробегом строки справа-налево.
10. Число е с точностью до десятого знака с пробегом строки справа-налево.
11. Квадратный корень числа 2 с точностью до 5-го знака с пробегом строки справа-налево.
12. Последовательность чисел, разделяемых пробелом и являющихся степенями числа 2 от первой до пятой с пробегом строки справа-налево.
13. Последовательность чисел, разделяемых пробелом и являющихся степенями числа 2 от первой до пятой с пробегом строки слева-направо.
14. Значение счетчика числа пробегов строки с обнулением на 10 и пробегом слева-направо.
15. Значение счетчика числа пробегов строки с обнулением на 10 и пробегом слева-направо.
Содержание отчета по лабораторной работе: цель работы, задание, листинг программы, вывод.
ЛАБОРАТОРНАЯ РАБОТА №5
ИССЛЕДОВАНИЕ УСТРОЙСТВА МАТРИЧНОЙ
ЖИДКОКРИСТАЛЛИЧЕСКОЙ ИНДИКАЦИИ
Цель работы. Ознакомиться с документацией устройства матричной жидкокристаллической индикации (ЖКИ), изучить схему сопряжения микроконтроллера с устройством матричной индикации, разработать и отладить программу вывода информации в устройство матричной ЖКИ.
Теоретические сведения
5.1. Теоретические основы и принципы работы ЖКИ
Жидкокристаллические индикаторы управляют отражением и пропусканием света для создания изображений цифр, букв, символов и т. д. В отличие от светодиодов, жидкокристаллические индикаторы не излучают свет. Основу ЖКИ составляют жидкие кристаллы (ЖК), молекулы которых упорядочены послойно определенным образом между двумя стеклянными пластинами. В каждом слое сигарообразные молекулы ЖК выстраиваются в одном направлении, их оси становятся параллельными (рис. 5.1).
Рис. 5.1. Один слой молекул ЖК
Стеклянные пластины имеют специальное покрытие, такое, что направленность молекул в двух крайних слоях перпендикулярна. Ориентация каждого слоя ЖК плавно изменяется от верхнего к нижнему, формируя спираль (рис. 5.2). Эта спираль «скручивает» поляризацию света по мере его прохождения через дисплей.
Рис. 5.2. Несколько слоев молекул ЖК
Под действием электрического поля молекулы ЖК переориентируются параллельно полю. Этот процесс называется твистнематическим полевым эффектом. При такой ориентации поляризация света не скручивается при прохождении через слой ЖК (рис. 5.3). Если передний поляризатор ориентирован перпендикулярно заднему, свет пройдет через включенный дисплей, но заблокируется задним поляризатором. В этом случае ЖКИ действует как заслонка свету. Отображение различных символов достигается избирательным травлением проводящей поверхности, предварительно созданной на стекле. Не вытравленные области становятся символами, а вытравленные – фоном дисплея.
Рис. 5.3. «Включенное» состояние ЖКИ
Символы создаются из одного или нескольких сегментов. Каждый сегмент может быть адресован (запитан) индивидуально, чтобы создать отдельное электрическое поле. Таким образом, прохождение света управляется электрически, включая и отключая необходимые сегменты. В неактивной части дисплея направленность молекул остается спиральной, формируя фон. Запитанные сегменты составляют символы, контрастирующие с фоном. В зависимости от ориентации поляризатора, ЖКИ может отображать позитивное или негативное изображение. В дисплее с позитивным изображением передний и задний поляризаторы перпендикулярны друг другу так, что незапитанные сегменты и фон пропускают свет с измененной поляризацией, а запитанные препятствуют прохождению света. Результат – темные символы на светлом фоне. В дисплее с негативным изображением поляризаторы параллельны, т.е. находятся «в фазе», друг с другом и препятствуют прохождению света с повернутой поляризацией так, что незапитанные символы и фон темные, а запитанные – светлые.
Рефлективный ЖКИ имеет отражатель (рефлектор) за задним поляризатором, который отражает свет, прошедший через незапитанные сегменты и фон. В негативных рефлективных дисплеях свет отражается через запитанные, «включенные» сегменты. Трансмиссивные дисплеи используют те же принципы, но фон или сегменты становятся ярче за счет использования задней подсветки.
5.2. Рефлективные индикаторы
Обычно рефлективные ЖКИ (работающие на отражение) используют режим отображения с темными символами на светлом фоне (так называемое позитивное изображение). В индикаторе с позитивным изображением передний и задний поляризаторы находятся в противофазе, или перекрестно поляризованы на 90°. Если сегмент «выключен», внешний свет идет по следующему пути: проходит через вертикальный поляризатор, через прозрачный электрод сегмента, через ЖК молекулы, которые скручивают его на 90°, через прозрачный общий электрод, через горизонтальный поляризатор, а затем попадает на рефлектор, который посылает свет обратно по тому же пути (рис. 5.4).
Рис. 5.4. Рефлективный индикатор в выключенном состоянии
Если сегмент «включен», внешний свет не изменяет своей поляризации при проходе через слой жидких кристаллов. Таким образом, поляризация света противоположна заднему поляризатору, что не дает свету пройти к отражателю. Так как свет не отражается, получается темный сегмент (рис. 5.5).
Рис. 5.5. Рефлективный индикатор во включенном состоянии
Рефлективные индикаторы очень яркие, с отличным контрастом и имеют широкий угол обзора. Они требуют хорошего внешнего освещения и не используют искусственную заднюю подсветку (хотя в некоторых моделях применяют подсветку сверху). Благодаря малым токам потребления рефлективные индикаторы часто используются в устройствах с питанием от батареек.
5.3. Трансмиссивные индикаторы
Трансмиссивные ЖКИ (работающие на пропускание) не отражают свет. Напротив, они создают изображение, управляя светом искусственного источника освещения, расположенного позади индикатора. В трансмиссивных индикаторах передний и задний поляризаторы находятся «в фазе» друг с другом (параллельны). Во выключенном сегменте поляризованный свет подсветки скручивается на 90° молекулами ЖК и оказывается в противофазе с передним поляризатором. Поляризатор блокирует свет, создавая темный сегмент.
Если сегмент включен, свет не скручивается, оказываясь «в фазе» с передним поляризатором, и проходит через него, создавая световой рисунок. Таким образом трансмиссивный дисплей создает светлое изображение на темном фоне (негативное изображение).
Трансмиссивные индикаторы должны иметь заднюю подсветку, чтобы гарантировать равномерное свечение сегментов. Они хороши для использования в условиях приглушенного или слабого освещения. В условиях прямого солнечного света подсветка не может преодолеть солнечных лучей и изображение не заметно.
5.4. Трансрефлективные индикаторы
Трансрефлективные (работающие на пропускание и отражение) индикаторы используют белый или серебряный полупрозрачный материал, который отражает часть внешнего света, а также пропускает свет задней подсветки. Поскольку эти индикаторы как отражают, так и пропускают свет, они могут использоваться в широком диапазоне яркостей освещения.
Примером могут служить индикаторы мобильных телефонов. Они читаемы как при ярком свете, так и в полной темноте. Трансфлективные дисплеи имеют более низкую контрастность по сравнению с рефлективными, так как часть света проходит сквозь отражатель.
5.5. Сегменты ЖКИ
Части ЖКИ, работающие как заслонки, включаясь и выключаясь для формирования изображений, называются сегментами. Сегменты создаются прозрачными электродами из оксидов индия и олова, нанесенными на стекло ЖКИ. Цифры от 0 до 9 и некоторые буквы могут быть отображены на семисегментном индикаторе. 16-сегментный индикатор может отобразить цифры, все латинские и почти все русские буквы (кроме Й, Ц, Щ). Для того чтобы символы были менее угловатыми и более натуральными, используют матричные индикаторы. С их помощью можно также отображать небольшие изображения. Количество сегментов индикатора (рис. 5.6) влияет на метод управления им.
а б в
Рис. 5.6. Дисплей:
а – 7-сегментный; б – 16-сегментный; в – матричный 5×7
ЖКИ обычно имеет время срабатывания 50 мс при 20 °C, а лучшие модели – до 10 мс. Стандартный ЖКИ может отображать сигнал до 10 Гц, если это требуется. Невооруженным глазом тяжело отследить данные с такой частотой.
5.6. Жидкокристаллический индикатор SC-1602 BULT
Микросхема SC-1602 BULT представляет собой жидкокристаллический матричный индикатор (ЖКИ) 2 строки по 16 символов со встроенным контроллером. Условное обозначение микросхемы приведено на рис. 5.7, а назначение выводов – в табл. 5.1.
Рис. 5.7. Условное обозначение ЖКИ SC-1602 BULT
Таблица 5.1
Назначение выводов микросхемы SC-1602 BULT
Обозначение выводов | Номер вывода | Назначение |
VCC | Питание | |
GND | Земля | |
Contrast | Регулировка контраста | |
RS | Выбор регистра ("1" – регистр данных, "0" – регистр команд) |
Окончание табл. 5.1
R/W | Выбор регистра ("1" – чтение данных, "0" – запись данных) | |
E | Сигнал разрешения чтения/записи | |
DB0–DB7 | 7…14 | 0 – 7 биты данных |
Основные параметры ЖКИ SC-1602 BULT:
– размер символов 5×7 точек;
– встроенный контроллер HD44780 или совместимый с ним;
– напряжение питания 5 В.
Структура индикатора приведена на рис. 5.8, таблица символов для шрифта кириллицы – на рис. 5.9.
Рис. 5.8. Структура ЖКИ SC-1602 BULT
ЖКИ состоит из следующих структурных элементов:
– регистр данных;
– регистр команд (РК);
– ПЗУ генератора символов (ГС) (ПЗУ содержит таблицу символов. Каждый символ имеет 8-битный код. Всего в ПЗУ содержится 192 символа);
– ОЗУ генератора символов (ОЗУ содержит символы пользователя);
– счетчик адреса;
– ОЗУ данных дисплея (ДД) (ОЗУ содержит информацию для вывода на дисплей);
– схема формирования курсора и мигания.
Рис. 5.9. Таблица символов для шрифта кириллицы
Буфер ввода/вывода может работать в 4-битном и в 8-битном режиме. В 4-битном режиме данные в индикатор передаются тетрадами. Перед началом работы с индикатором он должен быть проинициализирован. Последовательность инициализации при работе в 4-битном режиме приведена на рис. 5.10. Таблица команд работы с индикатором приведена на рис. 5.11.
Рис. 5.10. Последовательность инициализации
Рис. 5.11. Таблица команд
5.7. Электрическая принципиальная схема
В электрической принципиальной схеме стенда НТЦ-31.100 (рис. 5.12) организована последовательная шина. Для выбора конкретного устройства на шине используется набор сигналов CS0–CS7. Эти сигналы формируются на выходах дешифратора DD4 74HC138 (К1564ИД7). Для формирования кода выбираемого устройства используются порты PB.0, PB.4 и PB.5.
Рис. 5.12. Электрическая принципиальная схема к лабораторной работе
Для ввода информации с дискретных источников (тумблеров SW1–SW8) используется микросхема DD13 сдвигового регистра с параллельной загрузкой HCT165 (К5564ИР9). Порт PB.3 служит для приема информации в последовательной форме из микроконтроллера, порт PB.1 – для тактирования сдвигового регистра.
Для управления жидкокристаллическим индикатором используются линии PF.0–PF.3, PE.2, PD.5 и PD.7 микроконтроллера.
Практическая часть
5.8. Контрольные вопросы
1. Каков физический принцип работы ЖК индикаторов?
2. Поясните принцип работы рефлективных ЖК индикаторов.
3. Поясните принцип работы трансмиссивных ЖК индикаторов.
4. Поясните принцип работы трансрефлективных ЖК индикаторов.
5. Какое условное графическое обозначение и назначение выводов ЖК дисплея SC-1602 BULT применяется в настоящее время?
6. Опишите последовательность инициализации ЖК дисплея SC-1602 BULT при работе в 4-битном режиме.
7. Из чего состоит схема подключения ЖК дисплея к портам ввода/вывода микроконтроллера?
8. Каков алгоритм вывода символов на ЖК дисплей?
5.9. Варианты заданий
Разработать программу для учебного стенда НТЦ-31.100, выводящую на матричный жидкокристаллический индикатор (МЖКИ) свою фамилию и номер варианта на первой строке и следующую информацию на второй:
1. Результат операции логического «И» между регистром R20, равным 15h, и R21, равным AFh.
2. Результат операции логического «ИЛИ» между регистром R20, равным EBh, и R21, равным 3Fh.
3. Результат операции логического «ИЛИ-НЕ» между регистром R20, равным D0h, и R21, равным AAh.
4. Результат операции логического «И-НЕ» между регистром R20, равным 56h, и R21, равным 6Dh.
5. Побитовую инверсию числа AFh, представленную в двоичном виде.
6. Инверсию числа 231, представленную в двоичном виде.
7. Число 01111011b, представленное в 16-ричном виде.
8. Число 11110001b, представленное в 16-ричном виде.
9. Бегущую строку, содержащую информацию о текущей дате и номере вашей группы.
10. Бегущую строку, содержащую информацию о текущем дне недели и номере вашей группы.
11. Бегущую строку, содержащую информацию о текущем месяце и номере вашей группы.
12. Бегущую строку, содержащую символы №20, №4F, №23 и №FF с последовательным полным заполнением строки каждым из них.
13. Бегущую строку, содержащую символы №20, №2D, №2B и №2A с последовательным полным заполнением строки каждым из них.
14. Бегущую строку, содержащую расшифровку аббревиатуры названия изучаемой дисциплины.
15. Бегущую строку, содержащую счетчик числа циклов пробега строк.
5.10. Пример выполнения лабораторной работы
Задача
Разработать программу для учебного стенда НТЦ-31.100, позволяющую отобразить на МЖКИ строки «БГУИР – ПИКС» и «2014» в центре верхней и нижней строки соответственно.
Решение
Программа для решения этой задачи будет состоять из блока инициализации работы МЖКИ и блока вывода информации. Процедуру вывода символа на дисплей, а также установки курсора в начало первой и второй строки вынесем в отдельные подпрограммы lcd_print_symbol, lcd_1st_line и lcd_2nd_line соответственно.
Текст программы
include "m128def.inc"
.cseg
.org 0000
jmp Init
Init:
ldi R16,0x00 ;Формируем стек, начиная с ячейки памяти 0х400
out SPL,R16 ;Младший байт
ldi R17,0x04
out SPH,R17 ;Старший байт
;Инициализируем дисплей
sbi DDRD,5 ;Устанавливаем на вывод линию R/W
sbi DDRD,7 ;Устанавливаем на вывод линию RS
sbi DDRE,2 ;Устанавливаем на вывод линию E
ldi R16,0b00001111 ;Устанавливаем на вывод линии DB7…DB4
sts DDRF,R16
cbi PortD,5; R/W = 0 режим записи в ЖК дисплей (Write)
;Задержка
clr r13
clr r14
dec R13
brne PC-1
dec R14
brne PC-3
cbi PortD,7 ;RS = 0 – установка дисплея на прием команд
ldi R16,0b0011 ;Загружаем DB7 = 0, DB6 = 0, DB5 = 1, DB4 = 1
sts PortF,R16 ;Отправляем это на ЖК дисплей
sbi PortE,2 ;Включаем режим приема
clr r13 ;Очищаем используемый регистр
dec r13 ;Уменьшаем на единицу
brne pc-1
cbi PortE,2 ;Выключаем режим приема
;Задержка
dec R13
brne PC-1
dec R14
brne PC-3
ldi R16,0b0011 ;Отправляем DB7=0,DB6=0,DB5=1.DB4=1
sts PortF,R16
sbi PortE,2 ;Включаем прием
;Задержка
call delay
cbi PortE,2 ;Выключаем прием
call delay
ldi R16,0b0011 ;Отправляем DB7 = 0,DB6 = 0,DB 5= 1, DB4=1
sts PortF,R16
sbi PortE,2
;Задержка
call delay
cbi PortE,2
ldi R16,0b0010 ;Установка 4-битного интерфейса:
;DB7 = 0, DB6 = 0, DB5 = 1, DB4 = 0
sts PortF,R16 ;Отправляем
sbi PortE,2 ;Включаем прием
;Задержка
call delay
cbi PortE,2 ;Выключаем прием
ldi R16,0b0010 ;Подтверждение 4-х битного интерфейса
;DB7 = 0, DB6 = 0, DB5 = 1, DB4 = 0
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
;Установка символьной матрицы 5 х 7 пикселей
ldi R16,0b1000 ;N = 1, F = 0
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
;Гашение дисплея
ldi R16,0b0000 ;DB7 = 0, DB6 = 0, DB5 = 0, DB4 =0
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
ldi R16,0b1000 ;Отправляем D = 0, C = 0, B = 0
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
;Установка режима ввода
ldi R16,0b0000
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
ldi R16,0b0110 ;Отправляем I/D = 1, S = 0
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
;Включение индикатора
ldi R16,0b0000
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
ldi R16,0b1111 ;Отправляем D = 1, C = 1, B = 1
sts PortF,R16
sbi PortE,2
call delay
cbi PortE,2
;Конец инициализации
start:
call lcd_1st_line ;Установка курсора в левом верхнем углу
ldi r20,0x20
call lcd_print_symbol ;Запись символа " " 0x20
ldi r20,0x20 ;Запись символа " " 0x20
call lcd_print_symbol
ldi r20,0xA0 ;Запись символа "Б" 0xA0
call lcd_print_symbol
ldi r20,0xA1 ;Запись символа "Г" 0xA1
call lcd_print_symbol
ldi r20,0xA9 ;Запись символа "У" 0xA9
call lcd_print_symbol
ldi r20,0xA5 ;Запись символа "И" 0xA5
call lcd_print_symbol
ldi r20,0x50 ;Запись символа "Р" 0x50
call lcd_print_symbol
ldi r20,0x20 ;Запись символа " " 0x20
call lcd_print_symbol
ldi r20,0x2D ;Запись символа "-" 0x 2D
call lcd_print_symbol
ldi r20,0x20 ;Запись символа " " 0x20
call lcd_print_symbol
ldi r20,0xA8 ;Запись символа "П" 0xA8
call lcd_print_symbol
ldi r20,0xA5 ;Запись символа "И" 0xA5
call lcd_print_symbol
ldi r20,0x4B ;Запись символа "К" 0