Приведем пример реализации такого алгоритма работы программы. Для написания программы воспользуемся принципами структурного программирования, рассмотренными ранее. В этом случае для проверки правильности работы программы можно воспользоваться заглушками. Исходный текст программы, реализующей алгоритм программы-монитора, схема которого показана на рис. 7.10, приведен в листинге 7.22.
Как видно из приведенного текста, программа еще ничего не делает. Все будущие действия обозначены в именах подпрограмм-заглушек, однако эта программа уже может быть оттранслирована и запущена. В отладчике можно проверить, что при включении устройства мы действительно попадаем в подпрограмму инициализации, а затем последовательно вызываются подпрограммы сбора и обработки информации, а также подпрограмма обработки ошибок.
При использовании нескольких подпрограмм встает проблема обмена информацией между ними. Как уже рассматривалось ранее, информация в подпрограмму может быть передана через параметры или через глобальные переменные. При создании программы-монитора может потребоваться передавать одну и ту же информацию нескольким подпрограммам (что аналогично параллельному соединению аппаратных блоков), поэтому в мониторе информация обычно передается через глобальные переменные, которые последовательно подвергаются обработке всеми подпрограммами, включенными в бесконечный цикл.
Рассмотрим подробнее, как реализуется чтение информации с выводов микроконтроллера. Очень важно, чтобы сигналы со всех выводов вались одновременно, иначе можно получить комбинации битов, не соответствующие действительности. Иллюстрация такой ситуации приведена на рис. 7.11. В результате опроса сигналов в контроллер будет введен код 000, который никогда не присутствовал на выводах микросхемы!
Рис. 7.11.
К сожалению, микроконтроллер может опрашивать порты только последовательно. Тем не менее, благодаря его высокому быстродействию можно обеспечить почти одновременное считывание информации со всех выводов микросхемы, поэтому вероятность возникновения ситуации, представленной на рис. 7.11, невысока.
В качестве примера рассмотрим ввод информации с 16-кнопочной клавиатуры. Программа для микроконтроллера жестко зависит от принципиальной схемы разрабатываемого устройства. Невозможно написать программу для микроконтроллерного устройства, не имея перед глазами его принципиальной схемы. Схема подключения клавиатуры к микроконтроллеру приведена на рис. 7.12.
Рис. 7.12.
Рассмотрим только подпрограмму ввода информации, т. к. уже указывалось ранее, остальные части программы не должны зависеть от алгоритма опроса кнопок клавиатуры. Они лишь должны использовать информацию, сформированную подпрограммой ввода информации.
Объявим глобальную переменную skancode, в которой будем хранить значения электрических сигналов на выводах микроконтроллера, подключенных к контактам клавиатуры. Переменная используется для формирования управляющих сигналов и считывания состояний контактов. Код, хранящийся в этой переменной и отображающий значения электрических сигналов на выводах микроконтроллера, называется скан-кодом клавиатуры.
Теперь собственно о программе. Если бы речь шла не о клавиатуре, то ввод информации свелся бы к простому копированию сигналов с внешних выводов порта в переменную командой
MOV SkanCode, P1.
Но при вводе информации с клавиатуры необходимо осуществить ее сканирование, т. е. последовательный опрос колонок или столбцов клавиатуры (по вашему желанию возможен любой из двух вариантов).
Сначала определим, каким сигналом будем осуществлять сканирование. Для этого нужно вспомнить внутреннее устройство порта. Обратите внимание, что в качестве примера выбран микроконтроллер семейства MCS-51! При использовании других микроконтроллеров принципиальная схема и сигналы опроса могут оказаться другими! Путь протекания тока через замкнутую кнопку клавиатуры и элементы порта для микроконтроллеров семейства MCS-51 показан на эквивалентной схеме двух разрядов порта Р1 (рис. 7.13).
Рис. 7.13.
Из приведенной на рис. 7.13 эквивалентной схемы видно, что для опроса колонки кнопок необходимо открыть нижний транзистор порта, подключенного к выбранной колонке. При этом нужно обеспечить запирание транзисторов, подключенных к остальным колонкам кнопок. Это позволит исключить неоднозначность определения номера нажатой кнопки. Для открывания транзистора достаточно записать в соответствующий бит порта логический 0, а для запирания — логическую 1. В результате коды опроса клавиатуры для схемы, приведенной на рис. 7.12, будут выглядеть следующим образом: