Программирование микропроцессорных систем
Поменять напряжения на выходах Q и Q можно, если перевести движки переключателей S1 и S2 в положения В и Н соответственно (см. третью строку таблицы на рис. 1.2,б). Наконец, возможно четвертое состояние переключателей S1 и S2: оба их движка переводятся в состояние В. Такой входной сигнал RS-триггер зафиксировать не может. Действительно, в этом случае, когда S1 = S2 = B, на обоих выходах Q… Читать ещё >
Программирование микропроцессорных систем (реферат, курсовая, диплом, контрольная)
МЕТОДИЧЕСКИЕ УКАЗАНИЯ
к лабораторным работам
по дисциплине
«Программирование микропроцессорных систем»
Введение
Микропроцессор
1. Лабораторная № 1
1.1 Устройство и работа D-триггера
1.2 Параллельный регистр
1.3 Параллельный регистр с расширенными возможностями
1.4 Работа делителя частоты
1.5 Счетчики прямого счета
1.6 Счетчики с обратным отсчетом
1.7 Делители с переменным коэффициентом деления
1.8 Таймеры
1.9 Дешифраторы
2. Лабораторная № 2
2.1 Общие положения
2.2 Простейшая программа
2.3 Принципиальная электрическая схема
2.4 Алгоритм
2.5 Программа на Ассемблере
2.6 Директивы
2.7 Операторы
2.8 Описание программы
3. Лабораторная № 3
3.1 Переключающийся светодиод
3.2 Принципиальная схема
3.3 Алгоритм
4. Лабораторная № 4
4.1 Бегущие огни
4.2 Схема
4.3 Алгоритм
5. Лабораторная № 5
5.1 Использование таймера
5.2 Схема
5.3 Алгоритм
5.4 Использование прерываний по таймеру
5.5 Схема
6. Лабораторная № 6
6.1 Формирование звука
6.2 Схема
6.3 Алгоритм
7. Лабораторная № 7
7.1 Программная среда AVR Studio
7.2 Программный отладчик
Введение
Микропроцессор
В современной электронике микропроцессором называют специальную микросхему, которая предназначена для выполнения некоторого набора сложных функций по управлению тем либо иным электронным устройством. Микропроцессор — это сердце любого компьютера. Но не только. Те же технологии, которые применяются в компьютерах, с успехом применяются и в более простых электронных устройствах.
Микропроцессор незаметно завоевал весь мир. В последнее время на помощь человеку пришла целая армия электронных помощников. Мы привыкли к ним и часто даже не подозреваем, что во многих таких устройствах работает микропроцессор. Микропроцессорные технологии очень эффективны. Одно и то же устройство, которое раньше собиралось на традиционных элементах (схемы с «жесткой логикой»), будучи собрано с применением микропроцессора становится проще, не требует регулировки и меньше по размерам. Кроме того, с применением микропроцессоров появляются практически безграничные возможности по добавлению новых потребительских функций и возможностей.
Где же применяются микропроцессоры? Да просто везде! Посмотрите вокруг себя. У вас в квартире стоит современный телевизор? Не сомневайтесь: в нем есть, как минимум, один процессор. У вас есть на руке электронные часы? Современные часы строятся на основе специализированного микропроцессора. Ну, а мобильные телефоны — это вообще миниатюрные компьютеры!
Возможно, у вас есть игровая приставка, карманная электронная игра, современная микроволновая печь, стиральная машина, проигрыватель лазерных дисков, калькулятор. Во всех этих устройствах работает микропроцессор. Современный автомобиль нашпигован микропроцессорами, как фаршированная рыба. Не говоря уже о самолетах, пароходах, поездах и т. п. В общем, всего не перечесть.
Микропроцессор насчитывает достаточно долгую историю. До того, как изобрели микропроцессор (то есть процессор на одной микросхеме), существовали целые процессорные блоки в больших компьютерах. Теперь же интеграция пошла до фантастических пределов. Одна микросхема содержит не только сам процессор, но и сопутствующие ему элементы. Целый компьютер в одной микросхеме. Такая микросхема называется микроконтроллером.
Что же это за сопутствующие элементы? Это очень важные составные части микропроцессорной системы. Без них не может обходиться ни один микропроцессор. Итак, мы подходим к первому важному вопросу — составу типовой микропроцессорной системы. Любая микропроцессорная система (рис. 1) состоит из следующих основных элементов: процессор, модуль памяти, порты ввода-вывода. Рассмотрим каждую из этих составляющих подробнее.
Память. Это специальное электронное устройство, которое представляет собой набор ячеек, в каждой из которых может храниться одно число. Причем это не совсем то число, с которым мы с вами привыкли иметь дело. Это упрощенное компьютерное число. Обычно каждая ячейка памяти может хранить число, принимающее значения от нуля до 255.
Порты ввода—вывода. Это специальные микросхемы, при помощи которых микропроцессорная система может общаться с внешним миром. Причем можно говорить отдельно о портах ввода и портах вывода. Через порты ввода компьютерная система получает информацию извне, а посредством портов вывода она выдает результаты своей работы и управляет внешними устройствами. Только благодаря этим самым портам ввода—вывода к компьютеру подключаются такие устройства, как клавиатура, мышь, дисководы, CD-ROM и т. д.
Те читатели, которые знакомы с компьютерами, возможно, слышали термины «параллельный порт» (LPT) и «последовательный порт» (СОМ). Так вот в данном случае речь идет совсем о другом понятии. Это просто схожие термины. Параллельный, и тем более, последовательный порты компьютера — это целые, достаточно сложные схемы, которые, в свою очередь, управляются как раз таки при помощи портов ввода—вывода. Не нужно также думать, что клавиатура и мышь используют только порты ввода, а дисплей — порт вывода.
Для управления большинством устройств компьютера используются как порты ввода, так и порты вывода микропроцессорной системы. Возможно, вас удивляет, что я называю внешними устройствами и жесткий диск, и флоппи дисковод. Но когда мы начнем изучать типовую схему микропроцессорного устройства, вы убедитесь, что это именно так. Внутри компьютера скрыто еще много устройств, которые по отношению к микропроцессору являются внешними, хотя находятся зачастую не только внутри компьютера, но и непосредственно на материнской плате — главной плате компьютера.
Процессор — это самая главная часть, сердце всей системы. Он предназначен для того, что бы выполнять различные операции с числами. Последовательность этих операций называется программой. Каждая операция кодируется в виде числа и записывается в память. Те числа, с которыми процессор выполняет свои операции, называются данными. Данные также записаны в память. По сути дела, процессор — это цифровой автомат, способный выполнять определенный набор операций с числами. Но главной его особенностью является возможность запрограммировать любую последовательность его действий.
Все три части вычислительной системы связаны между собой, так называемыми шинами данных. По этим шинам передаются цифровые сигналы от процессора к модулю памяти, от процессора — к портам ввода—вывода.
А также и в обратном направлении: от портов ввода вывода и памяти к процессору.
Рис. 1 Основные составляющие компьютерной системы
Какие же операции может выполнять процессор? Во-первых, все простейшие операции, которые можно произвести над числом. Он может читать число из любой ячейки памяти, складывать, вычитать, сравнивать, иногда умножать и делить прочитанные числа. Результат вычислений процессор записывает обратно в память. Кроме арифметических действий, процессор может выполнять логические операции с числами (Булевы функции).
Набор операций, которые процессор способен выполнять с участием портов ввода—вывода, гораздо меньше, чем операций с ячейками памяти. В них также можно записывать и считывать информацию. Однако хранение чисел — это не главное назначение портов.
Определение. Порт ввода — это специальное электронное устройство, на которое извне поступают какие-либо электрические сигналы, предназначенные для управления микропроцессорным устройством. Например, сигналы, возникающие при нажатии клавиш на клавиатуре, сигналы, возникающие при срабатывании различных датчиков, и т. п.
Процессор считывает их в виде чисел и обрабатывает полученные числа в соответствии с алгоритмом управления.
Определение. Порт вывода выполняет обратную функцию. В них процессор записывает различные числа, которые затем поступают на внешние устройства в виде электрических сигналов.
Эти сигналы используются для управления. Управлять можно любым устройством, которое допускает электрическое управление, это: индикаторы; дисплеи; электромагнитные реле; электромоторы; электропневмоклапаны; электрические нагреватели и т. д.
Нужно только усилить управляющие сигналы до требуемой мощности. Кроме перечисленных выше команд в любой микропроцессор заложен набор специальных команд, специфических для задач управления процессом вычислений. В дальнейшем мы остановимся подробнее на всех типах команд микропроцессора.
1. Лабораторная № 1
Триггерные схемы
Триггер — логическое устройство, способное хранить 1 бит данных. (Название единицы информации 1 бит происходит от слов binary digit, т. е. двоичный разряд). К триггерам принято относить все устройства, имеющие два устойчивых состояния. В основе любого триггера находится кольцо из двух инверторов, показанное на рис. 1.1, а. Общепринято это кольцо изображать в виде так называемой защелки, которая показана на рис. 1.1,б. Принципиальная схема простейшего триггера-защелки, выполненного на двух инверторах резисторно-транзисторной логики, дана на рис. 1.1, в. Цепи входного управления у этой защелки нет.
После подачи на триггер напряжения питания состояния его транзисторов могут быть равновероятны: либо насыщен транзистор VT1, а VT2 находится в состоянии отсечки, либо наоборот. Эти состояния устойчивы. Защелка не может работать как мультивибратор. Пусть по каким-то причинам при включении питания на коллекторе одного из транзисторов, например VT1, коллекторное напряжение снижается, тем самым уменьшается базовый ток IБ2 транзистора VT2, следовательно, падает и сила его коллекторного тока IК2. Из-за этого на коллекторе VT2 напряжение Uи. п — I К2R К2 должно повыситься. Если это так, то должен еще быстрее возрастать базовый ток IБ1 транзистора VT1, ускоряя его переход к состоянию насыщения. Этот процесс идет быстро, лавинообразно. Он называется регенеративным. Процесс окончится, когда перестанет изменяться коллекторный ток транзистора VT1 и он перейдет в состояние насыщения. Транзистор VT2 окажется в состоянии отсечки.
Дальнейшее изменение токов IК1 и IК2 станет невозможным. Поскольку защелка симметрична, выключая и включая питание Uи. п можно получить один из двух вариантов устойчивого состояния транзисторов в защелке. Если считать, что напряжение низкого уровня соответствует логическому 0, обнаруживаем, что запись данных в защелку способом включения и выключения питания даст равновероятный, а поэтому неопределенный результат: 1,0 или 0,1. Однозначную запись 1 бита информации в защелку можно осуществить, если снабдить ее цепями управления и запуска.
В настоящее время существует много разновидностей триггерных схем. Все они появились как результат разработки новых цепей запуска. Для записи данных, т. е. переключения состояния триггера, могут использоваться: статический запуск уровнями напряжения, запуск только одним, положительным или отрицательным перепадом импульса, а также запуск полным тактовым импульсом, когда используются его фронт и срез. Известны триггеры с подачей запускающего перепада через конденсатор, т. е. импульсный запуск только по переменной составляющей тактовой последовательности.
Для формирования сигналов управления триггерами используются часто логические элементы со свойствами триггера Шмита.
На рис. 1.2, а показана принципиальная схема RS-триггера, которая содержит защелку (транзисторы VT1 и VT2), а также два раздельных статических входа управления (транзисторы VT3 и VT4). Эти входы управления называются R (reset — сброс) и S (set — установка). Иногда входы R и S называют по-другому: clear — очистка (сброс) и preset — предварительная установка соответственно. К входам раздельного статического запуска, триггера R и S присоединены управляющие переключатели S1 и S2. Поскольку от каждого из них на входы можно подать напряжение низкого Н или высокого В уровней, то имеется четыре комбинации этих управляющих сигналов.
Рис. 1.2. RS-триггер
Они перечислены в колонках R и S таблицы состояний RS-триггера (рис. 1.2,б). Если от S1 и S2 подать на оба входа R и S напряжение низкого уровня (Н, Н), то транзисторы VT3 и VT4 открывающих токов не получат, будут разомкнуты и поэтому не смогут повлиять на состояние транзисторов защелки VT1 и VT2. Напряжения на выходах триггера Q и Q останутся без изменения. Это значит, что в триггере осталась информация, записанная ранее.
Переведем движок переключателя S2 в положение В (высокое входное напряжение), оставив S1 в Н (низкое). Теперь транзистор VT4 будет насыщен, он замкнется и окажется низким напряжением на коллекторе присоединенного в параллель ему транзистора VT2. На входе Q будет также напряжение низкого уровня. Транзистор VT1 больше не получит от выхода Q открывающий базовый ток, поэтому он перейдет в состояние отсечки. По этой причине на выходе Q появляется напряжение высокого уровня (транзистор VT3 от переключателя S1 ток смещения не получает и на этот процесс в триггере не влияет). Данное состояние транзисторов VT1 и VT2 будет зафиксировано, защелкнуто.
Поменять напряжения на выходах Q и Q можно, если перевести движки переключателей S1 и S2 в положения В и Н соответственно (см. третью строку таблицы на рис. 1.2,б). Наконец, возможно четвертое состояние переключателей S1 и S2: оба их движка переводятся в состояние В. Такой входной сигнал RS-триггер зафиксировать не может. Действительно, в этом случае, когда S1 = S2 = B, на обоих выходах Q и Q должно появиться напряжение низкого уровня. Но если S1 и S2 строго одновременно отсоединить от входов, триггер переключится в неопределенное состояние. Иначе, после исчезновения входного состояния В, В защелка не переключается однозначно. Таким образом, два логических уровня В, В одновременно на входы R и S подавать нельзя.
На рис. 1.2, в показано функциональное обозначение RS-триггера, составленного из двух двухвходовых инверторов. Такой триггер можно строить на элементах И и на элементах ИЛИ. На рис. 1.2, г дана таблица логических состояний для RS-триггеров, построенных на элементах И и ИЛИ. Строки состояний «Без изменений» и «Неопределенность» здесь меняются местами в зависимости от выбранного соответствия 1 и 0 напряжениям высокого и низкого уровня.
Таким образом, RS-триггер имеет два раздельных статических входа управления, чтобы можно было записывать и хранить 1 бит информации. Вместе с тем, известно, что триггерные ячейки — это основа многих динамических устройств, главные из которых: делители частоты, счетчики и регистры. В этих устройствах записанную ранее информацию по специальному сигналу, называемому тактовым, следует передать на выход и переписать в следующую ячейку. Для осуществления такого режима RS-триггер необходимо снабдить тактовым входом С (clock).
Предварительно рассмотрим принципиальную схему так называемого Т-триггера (toggle — переключатель), выполняющего лишь одну функцию: он может делить частоту тактовой последовательности, подаваемой на вход С в 2 раза. Принципиальная схема Т-триггера, содержащего два инвертора DD1.1 и DD1.2 популярной в 50—60 годы резистивно-емкостной логики (РЕТЛ), показана на рис. 1.3, а. Схему тактового запуска здесь образуют два резисторно-диодных логических элемента И без инверсии (DD1.3 и DD1.4). Функциональная схема этого Т-триггера показана на рис. 1.3,б.
Для начала анализа работы Т-триггера положим, что в интервале времени от 0 до t1 (рис. 1.3, в) транзистор VT1 насыщен, его база получает избыточный ток от положительного полюса Uи. п через резисторы Rб1 и Rk2; транзистор VT2 разомкнут. Тогда на выходе Q напряжение низкого уровня не должно превышать 0,3 В. На выходе будет напряжение высокого уровня U = Uи.п. Следовательно, диод VD2 надежно закрыт, поскольку на его катоде присутствует большой положительный потенциал. Диод VD1 не закрыт. Обратим внимание также на то, что форсирующий конденсатор Сф1 заряжен до напряжения, существенно превышающего напряжение на втором таком же конденсаторе Сф2.
Таким образом, зная эти начальные условия, ждем прихода первого отрицательного перепада тактового импульса С в момент t1. Вызванный им отрицательный перепад тока выведет транзистор VT1 из состояния насыщения, поскольку скачок отрицательного (закрывающего) базового тока пройдет через незакрытый диод VD1 и конденсатор С1. Отметим, что через закрытый диод VD2 никакой скачок тока пройти не может. Поскольку скачок закрывающего базового тока транзистору VT1 был дан, должен уменьшиться и его коллекторный ток, что вызовет положительный перепад напряжения на коллекторе, т. е. на выходе Q. Далее, уже без влияния цепи запуска в RS-защелке происходит регенеративный процесс переброса, т. е. смены состояний транзисторов. Этот процесс идет однонаправлено и не останавливается с окончанием отрицательного перепада входного запускающего импульса С, что гарантируется неравенством начальных зарядов конденсаторов Сф1 и Сф2- Эти заряды мгновенно измениться не могут, поэтому конденсаторы Сф1 и Сф2 выполняют роль памяти предыдущего состояния. Но, как показал опыт, емкость форсирующих конденсаторов не должна превышать 30… 50 пФ, чтобы процесс не гасился избыточным током запуска.
Таким образом, по окончании регенерации в RS-защелке на выходе Q напряжение будет высоким, а на Q — низким (отрезок времени от t1 до t2). В этот период изменилось состояние диодов, распределяющих тактовые перепады: VD1 теперь заперт, a VD2 открыт, т. е. именно он готов передать RS-защелке очередной отрицательный перепад тактовой последовательности импульсов С. После прихода в момент t2 второго отрицательного перепада состояния выходов Q и Q вновь изменятся и закроется диод VD2, третий отрицательный перепад тактовой последовательности пройдет через диод VD1. Цикл работы Т-триггера на этом закончится.
Сигналы на выходах Q и Q имеют частоту повторения, в 2 раза меньшую, чем исходная тактовая последовательность С (сравните частоты повторения отрицательных фронтов на графиках UC, UQ и UQ (рис. 1.3, в). Таким образом, Т-триггер делит частоту входного сигнала в 2 раза, переключается отрицательным перепадом тактового импульса. Запуск отрицательным перепадом отмечен знаком инверсии С.
Рассмотренный Т-триггер несложно превратить в так называемый RST-триггер (рис. 1.4, а). Для этого разомкнем его внешние цепи обратных связей от выходов на цепь запуска Q — R и Q — S.
Ко входам R и S присоединим управляющие переключатели S1 и S2 (см. также рис. 1.3,б). Теперь еще до подачи перепада тактового импульса С в триггер можно записать две комбинации напряжений высоких и низких уровней, как и для RS-триггера (рис. 1.2,б). Записанная информация будет храниться в защелке до прихода тактового перепада С, и после прихода его триггер переключится. Полученный импульсный перепад выходных сигналов Q и Q будет однозначным. Бит информации в момент перепада появится на выходах RS-защелки. В данном случае его можно использовать для переключения последующего триггера.
Таблица состояний RST-триггера (рис. 1.4,б) показывает, что если на R и S входы поданы напряжения низких уровней, в триггере сохранится предыдущая информация. Она изменится на выходах на противоположное значение после прихода тактового импульса С. Подавать одновременно на статические входы два напряжения высоких уровней нельзя, поскольку аналогично RS-защелке выходной отклик окажется неопределенным. Этот основной недостаток RST-триггера послужил в свое время отправной точкой дальнейшего совершенствования методов запуска RS-защелки.
Заменим в схеме (рис. 1.4, а) элементы И (DD1.3 и DD1-.4) на двух-входовые инверторы. Получается принципиальная схема RST-триггера на элементах РТЛ (рис. 1.5, а). Функциональная схема его приведена на рис. 1.5,б, а таблица состояний на рис. 1.5, в. При напряжении высокого уровня на входе С (на входах R и S могут быть любые уровни) в промежуточных точках R' н S' появляются напряжения низкого уровня поскольку насыщаются транзисторы VT6 и VT7. На RS-защелку (элементы DD1.3 и DD1.4) прохождение управляющих сигналов R и S запрещено. В защелке хранится предыдущее ее состояние.
Если одновременно на входы R и S подать напряжение высокого уровня то в точках S' и R' будет напряжение низкого уровня, и действие тактового входа С будет запрещено. На выходах отобразится предыдущее состояние защелки. Когда на входах R и S зафиксировано напряжение низкого уровня и такое же напряжение поступит на вход С, в точках S' и R' появятся одновременно два напряжения высокого уровня. Такую логическую информацию RS-защелка не примет (неопределенность). Присутствующие на входах R и S взаимно противоположные уровни позволяют после прихода тактового импульса С установить на выходах Q и Q наперед заданную комбинацию уровней: Q=H, Q = B, и наоборот.
1.1 Устройство и работа D-триггера
На предыдущих занятиях мы узнали, что для хранения информации можно использовать даже простейший RS-триггер. В цифровой и вычислительной технике для этой цели чаще используются другие, более совершенные триггеры, из которых даже составляют целые регистры. Начнем с отдельных триггеров. Пожалуй, самый распространенный вид триггера — это так называемый D-триггер. Схемное обозначение D-триггера приведено на рис. 2.1
Главным атрибутом D-триггера являются два новых входа: D-вход и С-вход. Входы R и S имеют то же самое назначение, что и у RS-триггера (для сброса и установки). Как у любого другого триггера, у D-триггера имеются два выхода: прямой и инверсный. Следует заметить, что наличие RS-входов, так же как и инверсного выхода, необязательно. Рассмотрим логику работы D-триггера. Для начала разберемся с новыми для нас входами.
Вход D — это вход данных (от английского DATA). В процессе работы на этот вход подается логический уровень, который необходимо записать в D-триггер.
Вход С называется тактовым. На него поступает тактовый импульс, синхронизирующий запись данных.
Обратите внимание, что на условном обозначении триггера тактовый вход отмечен стрелкой в виде маленького треугольника. Такой треугольник означает, что данный вход импульсный. До сих пор мы имели дело с потенциальными входами. Потенциальный вход реагирует на потенциал поступающего на него сигнала. Про такой вход говорят: срабатывает при поступлении логической единицы. Или срабатывает от логического нуля.
Импульсный вход не чувствителен к уровню сигнала. Такой вход срабатывает в момент перехода от одного уровня к другому. Про такие входы говорят: срабатывает по переднему фронту (то есть при переходе с нуля на единицу) или срабатывает по заднему фронту (то есть при переходе от единицы к нулю). Иногда применяют другие технические термины для описания работы импульсного входа. В литературе можно прочитать: «вход срабатывает по фронту сигнала» или «вход срабатывает по спаду сигнала».
Теперь рассмотрим подробнее логику работы D-триггера. Для переключения триггера в нужное нам состояние сначала на вход D необходимо подать соответствующий логический сигнал. Для записи единицы на вход D подаем единицу, для записи нуля — ноль. Затем на вход С необходимо подать тактовый импульс. По спаду этого импульса триггер установится в нужное нам состояние (сигнал на D-входе запишется в триггер). Такая логика работы D-триггера делает его очень удобным устройством для хранения одного бита цифровой информации (одного разряда двоичного числа).
1.2 Параллельный регистр
Для хранения двоичного числа, состоящего из большего количества разрядов, используют несколько параллельно соединенных D-триггеров. На рис. 2.1 показана схема, предназначенная для хранения четырехразрядного двоичного числа.
Такая схема называется параллельным регистром. Для того, чтобы сохранить какое-либо число в таком регистре, нужно подать это число поразрядно на входы D0—D3. Затем на вход С схемы подается импульс записи. По заднему фронту этого импульса число записывается в регистр. Причем каждый разряд числа записывается в свой отдельный D-триггер. Записанное в регистр число можно считывать с выходов Q0—Q3.
В схеме, регистра присутствует также вход сброса R. Он объединяет входы R всех триггеров и используется для начальной установки всех разрядов регистра в нулевое состояние. В цифровой технике это называется «начальная установка».
В реальных микропроцессорных устройствах чаще используются восьмиразрядные параллельные регистры. На рис. 2.2 изображено схемное обозначение одного из таких регистров. Его внутренняя структура и назначение выводов аналогичны структуре и назначению выводов регистра, изображенного на рис. 2.1
1.3 Параллельный регистр с расширенными возможностями
Более сложный регистр изображен на рис. 1.4. Это регистр приспособлен для работы с параллельной шиной данных. Для этого в регистр введены два новых входа:
· вход выбора микросхемы (CS);
· вход перевода выходов в высокоимпедансное состояние (ОЕ).
Разберемся подробнее c этими новыми входами и режимами работы. Вход выбора микросхемы CS (Chip Select) предназначен для ее включения и выключения в разные моменты времени. Такие входы можно часто встретить у микросхем, предназначенных для микропроцессорной техники. Особенно в больших многофункциональных микросхемах. Наличие таких входов позволяет соединять несколько подобных микросхем параллельно по входам, но работать с каждой микросхемой по отдельности. В случае параллельного соединения одноименных входов данные будут записаны только в тот из регистров, на входе CS которого в момент записи будет присутствовать низкий логический уровень. Состояние остальных регистров останется неизменным.
Вход ОЕ, напротив, используется при параллельном объединении нескольких регистров по их выходам. Такое объединение возможно только в том случае, если в каждый момент времени будут работать выходы только одной из микросхем. Выходы остальных параллельно соединенных микросхем должны уметь автоматически отключаться от схемы. Для этой цели микросхема, изображенная на рис. 1.4. имеет специальный режим.
В этом режиме все выходы микросхемы отключаются и не влияют на работу остальной схемы. Такое состояние выходов называется высокоимпедансным. Импеданс — это полное сопротивление цепи. Если импеданс высокий, то можно считать, что соответствующий выход просто отключен. Микросхема переводит свои выходы в высокоимпедансное состояние при подаче логической единицы на вход ОЕ. Если же на вход ОЕ подать логический ноль, то выходы микросхемы перейдут обратно в рабочее состояние.
1.4 Работа делителя частоты
Счетчиками в цифровой технике называются специальные элементы, позволяющие подсчитывать число поступивших на вход импульсов. Понятие «счетчик импульсов» тесно связано с понятием «делитель частоты». По сути дела, это одно и то же устройство. Но рассмотрим все по порядку.
В качестве простейшего делителя частоты может JK-триггер. Для того, чтобы этот триггер работал как делитель, нужно на оба входа J и К подать высокий логический уровень. Теперь, если на вход С подать импульсный сигнал некоторой постоянной частоты, то по спаду каждого входного импульса триггер будет переключаться в противоположное состояние.
В результате на выходе 3.1. JK-триггера мы получим другой сигнал с частотой следования импульсов в два раза меньшей, чем частота импульсов на его входе. Этот процесс наглядно показан на рис. 3.1. Как видно из рисунка, период сигнала на выходе делителя ровно в два раза больше периода входного сигнала. А частота выходного сигнала, соответственно, в два раза ниже входного.
Второй вариант делителя частоты приведен на рис. 3.2. Он построен на основе D-триггера. Для того, чтобы перевести D-триггер в счетный режим, нужно соединить инверсный выход триггера Q с его D-входом так, как это показано на рис. 3.2. Теперь, если подать сигнал на вход С, такая схема тоже будет работать как делитель. Выходной сигнал такого делителя снимается с выхода Q триггера.
Рассмотрим подробнее работу этой схемы. Предположим, что после включения триггер установился в единичное состояние. Это означает, что на инверсном выходе триггера (Q) присутствует логический ноль. Этот ноль поступает на D-вход. Подадим на вход делителя некоторый цифровой сигнал, такой же, как мы подавали и в предыдущем случае (см. рис. 3.1.).
По спаду первого входного импульса D-триггер перейдет в нулевое состояние, так как на его D-входе сигнал логического нуля. После этого на инверсном выходе триггера устанавливается логическая единица. Поэтому по спаду следующего входного импульса триггер переключится в единичное состояние. И так далее. Результат работы делителя на D-триггере точно такой же, как и делителя на JK-триггере, и выходной сигнал нового варианта так же полностью соответствует рис. 3.1. Следует заметить, что в настоящее время JK-триггеры применяются довольно редко. Гораздо большее распространение благодаря своей простоте и универсальности получили D-триггеры.
Делители широко используются в цифровой технике. Цепочка последовательно соединенных D-триггеров позволяет получить сигналы требуемой частоты путем деления импульсов задающего генератора.
Пример. Соединенные последовательно два делителя позволят получить сигнал с частотой в четыре раза меньшей, чем входная. Трехкаскадный делитель (три последовательно соединенных D-триггера) дадут деление на восемь. Четыре каскада будут делить на шестнадцать. И так далее.
На рис. 3.3. изображена схема четырехкаскадного делителя частоты на D-триггерах. Импульсы тактового генератора поступают на вход первого каскада деления. Если частота сигнала на входе равна f, то на выходах делителя мы получим сигналы со следующими частотами:
Рис. 3.3. Четырехкаскадный делитель частоты.
1.5 Счетчики прямого счета
Приведенную на рис. 3.3. схему можно использовать не только в качестве делителя частоты, но и в качестве счетчика входных импульсов. Представьте, что выходы Q0—Q3 — это разряды некоторого двоичного числа. Выход Q0 — это младший разряд, а выход Q3 — самый старший.
Предположим, что перед началом счета все четыре триггера установлены в нулевое состояние. На вход схемы поступает некоторое количество импульсов. Входящие в схему триггеры будут переключаться согласно описанному выше алгоритму. Состояние триггеров в процессе счета показано в табл. 4.1. Как видно из таблицы, после прихода первого входного импульса триггер DO переходит в единичное состояние. После прихода второго импульса DO возвращается в ноль, зато в единичное состояние переходит D1.
Дальнейшее поведение всех четырех триггеров хорошо видно из таблицы. А теперь внимательно посмотрите, что у нас получилось. Если воспринимать совокупность цифровых сигналов на выходах счетчика как четырехразрядное двоичное число, то мы видим перед собой последовательность чисел от 0000 до 1111. Десятичный эквивалент этих чисел показан в правой крайней колонке таблицы.
Итак, перед началом счета на выходе делителя — ноль. После прохождения первого импульса на выходе — единица, после второго — два, и так далее. Каждый входной импульс увеличивает значение двоичного числа на выходе счетчика на одну единицу. Поэтому в любой момент времени счетчик содержит число, равное количеству импульсов, пришедших к этому моменту на его вход.
Таблица 4.1.
Максимальное число импульсов, которое может посчитать счетчик, схема которого изображена на рис. 3.3., — это 16. После прихода шестнадцатого импульса счетчик вернется в нулевое состояние. Счетчики широко применяются в цифровой технике в том случае, когда необходимо подсчитать количество каких-либо импульсов. Причем совсем необязательно, чтобы входные импульсы поступали равномерно с постоянным периодом. Это могут быть одиночные импульсы. Например, импульсы с какого-нибудь датчика, кнопки и т. п.
1.6 Счетчики с обратным отсчетом
Кроме счетчиков прямого отсчета, к которым относится схема, изображенная на рис. 3.3., существуют счетчики с обратным отсчетом (иногда такой счетчик называют инверсным). В таком счетчике при поступлении каждого входного импульса содержимое уменьшается на единицу. Кроме того, бывают задачи, для которых требуются универсальные счетчики, которые могут считать как в прямом, так и в инверсном направлении. Если задаваться задачей построения таких счетчиков на отдельных триггерах и логических элементах, то мы получим довольно сложную схему. На практике используют специальные микросхемы — счетчики импульсов. Современная промышленность предлагает большой ассортимент таких микросхем. На рис. 5.1 изображена микросхема К555ИЕ7. Это одна из микросхем 555 серии, которая широко выпускалась в свое время в СССР, и сейчас ее можно свободно найти в продаже на радиорынках стран СНГ.
Микросхема 555ИЕ7 — это реверсивный четырехразрядный счетчик/делитель с возможностью предустановки. Он имеет два счетных входа, обозначенных как «+ 1» и «-1». По спаду каждого импульса на входе «+1» содержимое счетчика увеличивается на единицу. По спаду каждого импульса на входе «-1» содержимое счетчика уменьшается на единицу. Счетчик имеет прямые выходы всех своих разрядов: Q0—Q3. Вход сброса R служит для установки всех разрядов счетчика в нулевое состояние.
Еще одно полезное свойство описываемого счетчика — это наличие режима предустановки. Используя этот режим, можно в любой момент записать во все разряды счетчика любое четырехразрядное двоичное число. Для этого счетчик имеет несколько дополнительных входов. Во-первых, это входы данных D0—D3. А, во вторых, это вход предустановки РЕ. Предустановка счетчика осуществляется следующим образом. Сначала на входы D0 — D3 подается код, который требуется записать в разряды счетчика. Затем на вход РЕ подается сигнал низкого логического уровня. По этому сигналу код, установленный на входах D0—DЗ, запишется в счетчик и тут же появится на его выходах Q0 — Q3. Дальнейший счет импульсов будет производиться уже от этого нового значения.
Выходы «>15» и «<0» — это выходы переполнения. Они используются при последовательном соединении нескольких таких счетчиков. В процессе счета уровень сигнала на обоих этих выходах равен единице. На выходе «>15» логический ноль появляется в том случае, если в процессе прямого счета содержимое счетчика достигнет своего максимального значения 11 112, и на вход"+1″ поступит очередной счетный импульс. Выход «<0» работает аналогично, но при обратном счете. Сигнал логического нуля появляется на этом выходе в тот момент, когда счетчик досчитает до своего нижнего предела — 2, и на вход «-1» поступит очередной счетный импульс. При последовательном соединении двух счетчиков выходы «>15» и «<0» первого счетчика соединяется соответственно с входами «+1» и «-1» второго. В результате, соединив последовательно два таких счетчика, мы получим восьмиразрядный реверсивный счетчик, который также будет иметь возможность предустановки. Таким способом можно соединять последовательно любое количество счетчиков 555ИЕ7.
Одно из применений микросхемы 555ИЕ7 — построение делителей с переменным коэффициентом деления. Простой делитель частоты, рассмотренный в начале этой главы, дает фиксированный набор коэффициентов деления, который к тому же можно выбирать лишь из ограниченного ряда значений, являющихся степенью числа 2.
1.7 Делители с переменным коэффициентом деления
В цифровой и микропроцессорной технике часто требуются делители с произвольным коэффициентом деления. При этом желательно, чтобы коэффициент деления можно было оперативно менять. На рис. 1.24 изображена схема делителя с программируемым коэффициентом деления на основе реверсивного счетчика К555ИЕ7. Для хранения-коэффициента деления используется специальный четырехразрядный параллельный регистр, обозначенный на схеме как DD1. Коэффициент деления такого делителя может изменяться от 1 до 15.
Работа счетчика начинается с установки всех его разрядов в ноль при помощи входа R. Обратите внимание на то, что в микросхеме К555ИЕ7 используется прямой, а не инверсный вход сброса. Поэтому сброс происходит при подаче на этот вход сигнала логической единицы. После того, как счетчик сброшен, для нормальной работы счетчика на вход R должен быть подан нулевой уровень.
Входной сигнал поступает на вход «-1». Поэтому счетчик работает в режиме обратного счета. Поэтому первый же входной импульс после сброса счетчика вызовет сигнал переполнения на выходе «<0». Этот импульс поступит на вход РЕ. В результате в счетчик будет записано двоичное число с выхода регистра DD1. Это число соответствует выбранному коэффициенту деления. Допустим, что в регистр DD1 мы записали число 10 (10 102). Тогда именно это число будет записано в разряды счетчика DD2.
Каждый последующий входной импульс будет уменьшать содержимое счетчика на единицу. Так будет продолжаться до тех пор, пока содержимое счетчика снова не уменьшится до нуля. Для этого потребуется как раз 10 тактовых импульсов. По приходу одиннадцатого импульса на выходе «<0» снова появится сигнал переполнения, и в счетчик будет опять записано число десять из регистра DD1.
Описанный процесс будет повторяться все время, пока приходят входные импульсы. Период следования импульсов на выходе «<0», а, значит, и на выходе всей схемы в нашем случае будет в 11 раз больше периода входных сигналов. А частота выходных импульсов будет, соответственно, в 11 раз меньше. То есть наш счетчик будет делить на 11. Записывая в регистр DD1 различные значения, можно легко менять коэффициент деления описанной схемы. Забегая вперед скажу, что запись числа в регистр коэффициента деления может производить микропроцессор. В этом случае мы можем создать делитель, управляемый от микропроцессора.
1.8 Таймеры
Подобную схему можно использовать также для формирования различных интервалов времени. Если на вход «-1» подавать тактовые импульсы фиксированной частоты, а в качестве управляющего входа использовать вход R, то на выходе мы можем получать импульс заданной длительности. И эту длительность можно программировать, записывая в регистр D1 различные коэффициенты.
Схемы, предназначенные для формирования различных интервалов времени, называются таймерами. Обычно одни и те же цифровые элементы при определенном способе включения могут с успехом выступать в любой из трех описанных выше ролей: либо как делители, либо как счетчики, либо как таймеры.
Существуют и специализированные микросхемы-таймеры. Например, микросхема К580ВИ53 — это универсальный программируемый трехканальный счетчик-таймер. Такая микросхема имеет множество режимов работы, которые должны выбираться программным путем при помощи микропроцессора.
Современные микроконтроллеры, или, как их еще называют, однокристальные микроЭВМ, обычно всегда содержат в своем составе один или несколько встроенных таймеров-счетчиков.
Пример. Микроконтроллеры серии AVR имеют от одного (в микросхеме AT90S1200) до четырех (в микросхеме ATmegal28) встроенных таймеров/счетчиков. Это позволяет при формировании временных интервалов обойтись без внешних таймеров.
1.9 Дешифраторы
Устройство и принцип действия дешифратора
Еще один элемент, без которого не обойтись при изучении микропроцессорной техники, — это дешифратор цифровых сигналов. Существует много разных типов дешифраторов. В общем случае дешифратор — это устройство, преобразующее цифровой сигнал, представленный в какой-либо одной из кодировок, в другую, незакодированную форму. Нас в данном случае будет интересовать классический линейный дешифратор. Схемное обозначение одного из вариантов такого дешифратора приведено на рис. 8.1. Описываемый дешифратор имеет три входа данных DO, D1 и D2, вход выбора микросхемы CS, а также восемь выходов, обозначенных цифрами от 0 до 7.
Логика работы микросхемы такова: на входы данных микросхемы подается цифровой код. В данном случае — это любое трехразрядное двоичное число. Смысл работы такого дешифратора — выдать активный сигнал только на одном из своих выходов. На том выходе, номер которого соответствует двоичному коду, присутствующему на его входах D0—D2.
В большинстве современных дешифраторов активным сигналом на выходе считается низкий логический уровень. Это значит, что при поступлении на входы D0—D1 сигнала 0002, на выходе «0» будет логический ноль, а на всех остальных выходах — единица.
2. Лабораторная № 2
2.1 Общие положения
Главная задача этой дисциплины — научиться создавать программы для микроконтроллеров. Как можно узнать из предыдущих занятий, программа для микроконтроллера — это набор кодов, который записывается в его специальную программную память. Программу должен написать программист, который разрабатывает ту или иную конкретную микропроцессорную систему.
Однако программист никогда не имеет дело с кодами. Часто программист даже и не задумывается о том, какой код соответствует той или иной команде. Дело в том, что для человека программирование в кодах очень неудобно. Человек же не компьютер.
Для человека удобнее оперировать с командами, каждая из которых имеет свое осмысленное название. Поэтому для написания программ человек использует языки программирования.
Определение. Язык программирования — это специально разработанный язык, служащий посредником между машиной и человеком. Как и обычный человеческий язык, любой язык программирования имеет свой словарь (набор слов) и правила их написания.
В качестве слов в языке программирования выступают:
· команды (операторы);
· специальные управляющие слова;
· названия регистров;
· числовые выражения.
Главная задача языка — однозначно описать последовательность действий, которую должен выполнить ваш микроконтроллер. В то же время язык должен быть удобен и понятен человеку.
В процессе создания программы программист просто пишет ее текст на компьютере точно так же, как он пишет любой другой текст. Затем программист запускает специальную программу — транслятор.
Определение. Транслятор — это специальная программа, которая переводит текст, написанный программистом, в машинные коды, то есть в форму, понятную для микроконтроллера.
Написанный программистом текст программы называется исходным или объектным кодом. Код, полученный в результате трансляции, называется результирующим или машинным кодом. Именно этот код записывается в программную память микроконтроллера. Для записи результирующего кода в программную память применяются специальные устройства — программаторы.
Все языки программирования делятся на две группы: языки низкого уровня (машиноориентированные); языки высокого уровня.
Типичным примером машиноориентированного языка программирования является язык Ассемблер. Этот язык максимально приближен к системе команд микроконтроллера. Каждый оператор этого языка — это, по сути, словесное название какой-либо конкретной команды.
В процессе трансляции такая команда просто заменяется кодом операции. Составляя программу на языке Ассемблер, программист должен оперировать теми же видами данных, что и сам процессор, то есть байтами и битами.
Специфика языка Ассемблер состоит еще и в том, что набор операторов для этого языка напрямую зависит от системы команд конкретного микроконтроллера. Поэтому, если два микроконтроллера имеют разную систему команд, то и язык Ассемблер для каждого такого микроконтроллера будет свой. В данной книге мы будем изучать одну конкретную версию языка Ассемблер. А именно Ассемблер для микроконтроллеров AVR.
В недавнем прошлом язык Ассемблер был единственным языком программирования для микроконтроллеров. Только он позволял эффективно использовать скудные ресурсы самых первых микросхем. Однако в настоящее время, когда возможности современных микроконтроллеров значительно возросли, для составления программ все чаще используются языки высокого уровня, такие как Бейсик, СИ и т. п.
Эти языки в свое время были разработаны для больших настоящих компьютеров. Но сейчас широко используются также и для микроконтроллеров. Языки высокого уровня отличаются тем, что они гораздо больше ориентированы на человека. Большинство команд языков высокого уровня не связаны с конкретными командами микроконтроллера.
Такие языки оперируют уже не с байтами, а с привычными нам десятичными числами, а также с переменными, константами и другими элементами, знакомыми нам из математики. Константы и переменные могут принимать привычные для нас значения.
Например, положительные, отрицательные значения, вещественные значения (десятичные дроби) и т. п. Со всеми переменными и константами можно выполнять знакомые нам арифметические операции и даже алгебраические функции.
Транслятор с языка высокого уровня производит более сложные преобразования, чем транслятор с Ассемблера. Но в результате тоже получается программа в машинных кодах. При этом транслятор использует все ресурсы микроконтроллера по своему усмотрению. В каких именно регистрах или ячейках памяти она будет хранить значения описанных вами переменных, по каким алгоритмам она будет вычислять математические функции, программист обычно не задумывается.
Программа-транслятор выбирает все это сама. Поэтому задача эффективности алгоритма полученной в результате трансляции программы целиком ложится на программу-транслятор. В целом, программы, написанные на языках высокого уровня, занимают в памяти микроконтроллера объем на 30—40% больший, чем аналогичные программы, написанные на языке Ассемблер.
Однако если микроконтроллер имеет достаточно памяти и запас по быстродействию, то это увеличение программы — не проблема. Преимуществом же языков высокого уровня является существенное ускорение процесса разработки программы. Из всех языков высокого уровня самым эффективным, пожалуй, является язык СИ. Поэтому для иллюстрации языков высокого уровня мы выберем именно его.
Изучение приемов программирования мы будем осуществлять на ряде конкретных примеров:
· каждый пример будет начинаться с постановки задачи;
· затем мы научимся выбирать схемное решение;
· лишь после этого будут представлены примеры программ.
Для каждой задачи в книге приводятся два варианта программы. Одна на языке Ассемблер, вторая на языке СИ. В результате вы сможете не только научиться азам программирования на двух языках, но и понять все достоинства и недостатки каждого из языков программирования.
2.2 Простейшая программа
Постановка задачи
Самая простая задача, которую можно придумать для микроконтроллера, может звучать следующим образом:
«Разработать устройство управления одним светодиодным индикатором при помощи одной кнопки. При нажатии кнопки светодиод должен зажечься, при отпускании — погаснуть».
С практической точки зрения это совершенно бессмысленная задача, так как для ее решения проще обойтись без микропроцессора. Но в качестве примера для обучения подойдет прекрасно.
2.3 Принципиальная электрическая схема
Попробуем разработать принципиальную электрическую схему, способную выполнять описанную выше задачу. Итак, к микроконтроллеру нам нужно подключить светодиод и кнопку управления. Как мы уже говорили, для подключения к микроконтроллеру AVR любых внешних устройств используются порты ввода—вывода. Причем каждый такой порт способен работать либо на ввод, либо и на вывод.
Удобнее всего светодиод подключить к одному из портов, а кнопку — к другому. В этом случае управляющая программа должна будет настроить порт, к которому подключен светодиод, на вывод, а порт, к которому подключена кнопка, на ввод. Других специальных требований к микроконтроллеру не имеется. Поэтому выберем микроконтроллер.
Очевидно, что нам нужен микроконтроллер, который имеет не менее двух портов. Данным условиям удовлетворяют многие микроконтроллеры AVR. Я предлагаю остановить свой выбор на довольно интересной микросхеме ATtiny2313. Эта микросхема, хотя и относится к семейству «Ttiny», на самом деле занимает некое промежуточное место между семейством «Ttiny» и семейством «Mega». Она не так перегружена внутренней периферией и не столь сложна, как микросхемы семейства «Mega». Но и не настолько примитивна, как все остальные контроллеры семейства «Ttiny».
Эта микросхема содержит два основных и один дополнительный порт ввода-вывода, имеет не только восьмиразрядный, но и шестнадцатиразрядный таймер/счетчик. Имеет оптимальные размеры (20-выводной корпус). И идеально подходит в качестве примера для изучения основ программирования
Итак, если не считать порта А, который включается только в особом режиме, который мы пока рассматривать не будем, микроконтроллер имеет два основных порта ввода—вывода (порт В и порт D). Договоримся, что для управления светодиодом мы будем использовать младший разряд порта В (линия РВ.0), а для считывания информации с кнопки управления используем младший разряд порта D (линия PD.0). Полная схема устройства, позволяющего решить поставленную выше задачу, приведена на рис. 2.1.
Для подключения кнопки S1 использована классическая схема. В исходном состоянии контакты кнопки разомкнуты. Через резистор R1 на вход PD.0 микроконтроллера подается «плюс» напряжения питания, что соответствует сигналу логической единицы.
При замыкании кнопки напряжение падает до нуля, что соответствует логическому нулю. Таким образом, считывая значение сигнала на соответствующем выводе порта, программа может определять момент нажатия кнопки. Несмотря на простоту данной схемы, микроконтроллер AVR позволяет ее упростить. А именно, предлагаю исключить резистор R1, заменив его внутренним нагрузочным резистором микроконтроллера. Как уже говорилось выше, микроконтроллеры серии AVR имеют встроенные нагрузочные резисторы для каждого разряда порта. Главное при написании программы не забыть включить программным путем соответствующий резистор.
Подключение светодиода также выполнено по классической схеме. Это непосредственное подключение к выходу порта. Каждый выход микроконтроллера рассчитан на непосредственное управление светодиодом среднего размера с током потребления до 20 мА. В цепь светодиода включен токоограничивающий резистор R3.
Для того, чтобы зажечь светодиод, микроконтроллер должен подать на вывод РВ.0 сигнал логического нуля. В этом случае напряжение, приложенное к цепочке R2, VD1, окажется равным напряжению питания, что вызовет ток через светодиод, и он загорится. Если же на вывод PD.0 подать сигнал логической единицы, падение напряжения на светодиоде и резисторе окажется равным нулю, и светодиод погаснет.
Кроме цепи подключения кнопки и цепи управления светодиодом, на схеме вы можете видеть еще несколько цепей. Это стандартные цепи, обеспечивающие нормальную работу микроконтроллера. Кварцевый резонатор Q1 обеспечивает работу встроенного тактового генератора. Конденсаторы С2 и СЗ — это цепи согласования кварцевого резонатора.