Бегущая строка на Intel 8051: How-To. Часть 1

Написал Vanger, в Статьи » Прочее.
ВВЕДЕНИЕ

В этой статье я расскажу вам о том, как надо вести процесс разработки программы из статьи о динамической индикации. Расскажу, как правильно выбирать архитектуру программы и грамотно расходовать имеющиеся в нашем распоряжении ресурсы. Разжую все настолько подробно, насколько смогу.

Программирование - наука о проектировании и алгоритмах. Прежде всего. А не о кодировании. В чем отличие программиста, разработчика от быдлокодера? Разработчик прежде всего продумывает, ЧТО должна делать программа, оценивает имеющиеся в его распоряжении ресурсы, выбирает наиболее оптимальную архитектуру программы. И только ПОСЛЕ этого он приступает к написанию исходного кода. Быдлокодер тупо пишет код, если что-то работает не так - переписывает или кладет хрен на оптимизацию и идет пить пиво))))).

Что нам нужно от программы?

Нужно, чтобы она выводила текст на LED индикаторы. Мы имеем 4 индикатора. Для того, чтобы подавать нужную информацию на индикатор, требуются все 8 выводов 1 порта. Совпадение: у нашего микроконтроллера как раз 4 порта)). Но расходовать все 4 порта MCS 51 только для того, чтобы адресовать 4 индикатора, невыгодно. Проблему можно решить за счет использования дешифраторов и регистров (регистр DD1, дешифратор DD2: см. схему), как и сделано в нашем устройстве. В нашем случае для того, чтобы адресовать 4 индикатора, нужен 1 порт, и еще один порт нужен для того, чтобы управлять дешифратором.

Бегущая строка на Intel 8051: How-To. Часть 1

Схема устройства


Благодаря использованию дешифратора можно с помощью 1 порта контроллера адресовать вообще бесконечное число индикаторов. Происходит это следующим образом: информация (текущая буква или цифра) передается одновременно на все индикаторы, но принимает эту информацию только один. У всех индикаторов есть порт AN (посмотрите еще раз на схеме), разрешающий прием данных. С помощью дешифратора мы по очереди разрешаем прием новых данных на индикаторах.

Таким образом, нам нужно запрограммировать работу 2 портов микроконтроллера.
Кроме этого, нам нужно настроить работу микроконтроллера так, чтобы он с определенной частотой (т.е. надо придумать, как он будет отсчитывать эту частоту) отправлял определенную информацию на индикаторы (значит, нужно эту информацию как-то хранить и обрабатывать).

АЛГОРИТМ РАБОТЫ ПРОГРАММЫ

Разделим всю программу на несколько частей. В составе программы должны быть алгоритм динамической индекации (работа с портами, с индикаторами) и алгоритм бегущей строки (хранение и обработка бегущей строки, посылаемой на индикаторы). Для того, чтобы строка «бежала» по индикаторам с определенной частотой, воспользуемся встроенными в микроконтроллер таймерами. Всего в MCS 51 их два. Итого нам понадобится еще алгоритм работы с таймерами.

Приступим:

Алгоритм динамической индикации

Нам нужно разработать алгоритм подпрограммы динамической индикации для дисплея из четырех семисегментных индикаторов.

Режим динамической индикации предполагает, что разряды индикатора работают по очереди. Переключение разрядов происходит с большой скоростью, чтобы сделать незаметным мерцание. Нам потребуется подпрограмма задержки, которая позволит производить динамическую индикацию со скоростью несколько сотен раз в секунду. Для этого воспользуемся таймером TC_0.

Для того, чтобы индикаторы работали поочередно, в схеме модуля индикации используются дешифратор DD2 и четыре транзисторных ключа VT1-VT4. На вход дешифратора поступают управляющие сигналы:
1) с выводов портов P3.2 и P3.5 – они отвечают за выбор разряда;
2) с вывода P3.4 – сигнал разрешения работы дешифратора.

Подпрограмма, обеспечивающая режим динамической индикации, должна работать в фоновом режиме, т.е. независимо от других подпрограмм постоянно перебирает разряды. Для этого лучше всего подходит режим прерываний по таймеру, который не использует АЛУ для своей работы.

Сначала микроконтроллер записывает код символа в регистр DD1. Асинхронно с установлением уровня логической «1» на вход загрузки С и уровнем логического «1» на вход разрешения, на выход Q подается параллельный восьмиразрядный код. Этот восьмиразрядный код идет на индикаторы, это и есть символы для отображения. Для фиксации значений на выход загрузки подается сигнал логического нуля «0».

После этого номер следующего разряда подается на выходы P3.2 и P3.5 микроконтроллера. При этом надо установить бит разрешения работы дешифратора в «1». Из регистра данные поступают непосредственно на индикатор. Следующий шаг - инкрементирование номера разряда и выход из подпрограммы. После того, как номер разряда станет равным четырем, производится сброс регистра и счет начинается сначала.

Алгоритм бегущей строки

Также в устройстве необходимо реализовать бегущую строку вида «ПС-476-08» со скоростью вывода 0,5 с/символ.
Нам потребуется подпрограмма задержки на 0,5 с. Данную задержку можно организовать настройкой второго таймера-счетчика TC_1.

Для того, чтобы было проще работать, разобьем строку на следующие друг за другом символы, которые можем записать в память как некие константы. Для вывода текста на экран будем последовательно считывать по четыре символа (по одному на каждый индикатор в каждый момент времени). Для бегущей строки необходимо через каждые 0,5 с. увеличивать смещение символов в строке, это можно организовать с помощью цикла (будет рассмотрено в далее).

Теперь расскажем, почему символы представлены в виде битовых последовательностей, и как из строк типа db 10011001b получаются нужные нам символы. Каждый символ из выводимой строки отображается в микроконтроллере как число размером в 1 байт. На рисунке изображен внешний вид семисегментного индикатора. Чтобы получить на нем нужный символ, надо зажечь определенные сегменты.

Бегущая строка на Intel 8051: How-To. Часть 1

Восьмисегментный индикатор


Будем использовать индикаторы с общим анодом, в которых зажигание сегментов происходит при подаче низкого уровня напряжения – логический «0». Т.е. для того, чтобы сегмент «горел», нужно подать на него 0. Хотим, чтобы горел верхний сегмент «а» - последняя цифра должна быть равна нулю (db 11111110b).
В таблице 1 представлены символы в двоичном коде, заданные для вывода на индикаторы.

Таблица 1. Символы в двоичном виде
Бегущая строка на Intel 8051: How-To. Часть 1

В итоге получаем следующую строку:

STROKA:; Строка для вывода на индикаторы

            db    11111111b; <пробел>
            db    11111111b; <пробел>
            db    11111111b; <пробел>
            db     11001000b; П
            db     11000110b; С
            db     10111111b; - = BFh
            db     10011001b; 4 = 99h
            db     11111000b; 7 =
            db     10000010b; 6 =
            db     10111111b; - = BFh
            db     11000000b; 0 =
            db     10010010b; 8 =
            db     11111111b; <пробел>
            db     11111111b; <пробел>
            db     11111111b; <пробел>

Расчет режима работы таймеров-счетчиков

Теперь рассчитаем необходимые нам задержки, для организации которых будем использовать два встроенных таймера-счетчика. Первый (ТС_0) задействуем для организации задержки на 0.5 с, а второй (ТС_1) для динамической индикации. Оба таймера-счетчика настроим в качестве шестнадцатиразрядных таймеров (режим работы 1 таймеров-счетчиков), для чего в регистр TMOD запишем значение #00010001b.

Для того чтобы при организации динамической индикации не было заметно мерцание, частоту смены кадров необходимо выбрать более 48 Гц. Пусть изображение меняется с частотой 100 Гц. Так как в модуле индикации используется 4 разряда, то частота переключения всех разрядов должна быть 100*4=400 Гц. С такой частотой таймеру-счетчику ТС_1 нужно формировать прерывания, то есть каждые 2,5 мс.

Т.к. один машинный такт Intel 8051 занимает 12 временных тактов, на вход таймеров счетчиков будут поступать импульсы с частотой:

f = fтакт / 12 = (11.0592 * 10^6) / 12 = 0.9216 МГц,
где fтакт = 11.0592 МГц – частота процессора.

Так как таймеры-счетчики настроены как 16-тиразрядные таймеры, то максимальное значение в них равно 65535, что соответствует максимальному времени:

tmax = 65536 / (0.9216 * 10^6) = 71.11 мс

Данный интервал не соответствует ни требуемым 2,5 мс, ни 0,5 с. Значит необходимо осуществить подгонку. Для того, чтобы уменьшить интервал надо вместо нулевого начального значения взять какое-то определенное. Рассчитаем, какое начальное значение необходимо поместить в таймер-счетчик ТС_1, чтобы он обнулялся каждые 2.5 мс. Так как частота смены кадров должна быть 400 Гц, а таймер считает с частотой 0,9216 МГц, то прежде чем обнулится он должен отсчитать [ (0.9216 * 10^6) / 400 = 2304 ] раз, то есть начальное значение, заносимое в этот таймер-счетчик должно быть равно 65535-2304=63231 или 0F6FFh в шестнадцатеричной системе. Для организации данного цикла будем использовать итерационную переменную R3.

Теперь для создания бегущей строки (циклический сдвиг строки) создадим ещё один цикл. Здесь интервал надо увеличить. Один машинный цикл включает в себя 12 циклов синхронизации. Для того, чтобы организовать прерывание, равное 0.5 с, необходимо использовать не все 12 циклов, будет достаточно 7. Получим время, равное 71.11*7=497.778 мс, что практически равно 0.5 с. Для счета количества прерываний используем регистр R0. Когда 7 циклов прерываний пройдут, необходимо увеличивать смещение в строке символов на единицу, и обнулять регистр R0. Для организации цикла смещения будем использовать итерационную переменную R2.

Смотрим код:

        MOV    R0,#0h; Инициализация итерационной переменной R0
                                ; 7 прерываний = 0,5с.
;-------Описание работы таймеров
            MOV    TH0,#0h; Установка времени срабатывания таймера 0 на
            MOV    TL0,#0h; максимально возможное значение (71 мс)

            MOV    TH1,#0F6h; Установка времени срабатывания
            MOV    TL1,#0FFh; таймера 1 на 2,5 мс (400 Гц)

            MOV    TMOD,#00010001b; Определяем таймеры/счетчики в качестве таймеров
            MOV    IP,#00000010b; Устанавливаем приоритет T/C_0=1, T/C_1 = 0
            MOV    IE,#10001010b; Разрешаем прерывания
            MOV    TCON,#01010000b; Включение таймеров

Отлично. Рассчитали. Теперь нужно прератить это в программу.
#1 прохожий |  

а разве двоичное обозначение цифры 8 не 10000000b ?
а то тут обозначена не 8ка, а 5ка)
Дата публикации: 6 ноября 2009 21:14 | ICQ: --
цитировать
#2 мята |  

а в какой программе собиралась схема, скажите пожалуйста??!!!!
Дата публикации: 15 ноября 2009 10:05 | ICQ: --
цитировать
#3 Vanger |  

прохожий, ты прав ))) перепутал, поправлю

мята, схема собиралась не мной, и тестировали программу не на компьютерной схеме, а "вживую", на физической. в какой проге можно смоделировать схему - не знаю
Дата публикации: 15 ноября 2009 10:41 | ICQ: --
цитировать
#4 1 |  

В Proteuse можно, наверное
Дата публикации: 21 февраля 2010 14:20 | ICQ: --
цитировать

Добавить комментарий


Включите эту картинку для отображения кода безопасности
обновить код



 

Лучшие новости

Наш опрос

Мы в интернете