В.Т. Рябов - Устройство и программирование однокристальных микроконтроллеров (1054006), страница 17
Текст из файла (страница 17)
Затонированы зоны системных переменных диспетчера. Программист должен использовать их в соответствии с предписанными диспетчером правилами.Остальные программист волен использовать по своему усмотрению.54Таблица 5.4.Распределение резидентной памяти микроконтроллера под диспетчер задачАдресСодержимое ячейки памятиR0 … R7 пользователя00h..07hR0..R7 таймера – задержки 0-го..7-го кванта в тиках08h..0Fh15 свободных байтов пользователя (второй и третий банки регистров)10…1Fh20h Статусы квантов SPR7SPR6SPR5SPR4SPR3SPR2SPR1SPR021h Флаги квантовFPR7 FPR6 FPR5 FPR4 FPR3 FPR2 FPR1 FPR022h Размерность заR_PR7 R_PR6 R_PR5 R_PR4 R_PR3 R_PR2 R_PR1 R_PR0держек квантов23h24h25h26h24h..63h64h..7FhСчетный регистр числа малых тиковРегистр значения старшего байта TH0 счетчика ТС0Регистр значения младшего байта TL0 счетчика ТС0Регистр типа очереди квантовБайты пользователяСтек системы и пользователяЗапускаются синхрокванты из пультовой петли диспетчера, куда и передают управление после своего завершения.
В синхрокванте пользователь должен декларировать необходимость следующего запуска, устанавливая бит статуса запуска SPR0…SPR7 для каждого из восьми синхроквантов. Если квант перезапускать во времени не нужно, пользователь должен очистить соответствующий бит статуса.Задержка на перезапуск синхрокванта задается пользователем как число быстрыхили медленных тиков в пределах от 1 до 255 в переменных ожидания wait0…wait7.В первом банке регистров МК будем хранить задержки квантов. Задержка устанавливается пользователем и затем уменьшается с каждым тиком таймером. Использование набора регистров первого банка позволит использовать подразумеваемую адресациюи сократить время анализа состояния задержек, т.е. время работы подпрограммы обработки прерываний таймера Т/C0.08h (R0) – задержка времени нулевого кванта (wait0).09h (R1) – задержка времени первого кванта (wait1).0Ah (R2) – задержка времени второго кванта (wait2).0Bh (R3) – задержка времени третьего кванта (wait3).0Ch (R4) – задержка времени четвертого кванта (wait4).0Dh (R5) – задержка времени пятого кванта (wait5).0Eh (R6) – задержка времени кванта (wait6).0Fh (R7) – задержка времени кванта (wait7).Программно-аппаратный таймер диспетчера уменьшает в соответствии с реальнымвременем переменные wait, и, как только они обнулятся, устанавливает соответствующийфлаг запуска квантов FPR0…FPR7.
Запускаться синхрокванты будут из пультовой петлидиспетчера.Разработка текста программыПосле распределения переменных приступим к написанию текста программы диспетчера. Исходный текст программы на языке Ассемблер имеет определенный формат. Каждаякоманда представляет собой строку четырехзвенной конструкции:МЕТКА - ОПЕРАЦИЯ - ОПЕРАНДЫ – КОММЕНТАРИЙ.МЕТКА. В поле метки размещается имя ячейки памяти, в которой хранится отмеченная команда или операнд.
Метка представляет собой буквенно-цифровую комбинацию, начинающуюся с буквы латинского алфавита. Длина метки не должна превышать шести символов. Метка всегда завершается двоеточием. В качестве символических имен и меток нельзяиспользовать мнемокоды команд псевдокоманды и операторы ассемблера, а также мнемонические обозначения регистров и других внутренних блоков МК.55ОПЕРАЦИЯ. В поле операции записывается мнемоническое обозначение командыМК или псевдокоманды ассемблера, которое является сокращением полного английского наименования выполняемого действия.ОПЕРАНДЫ.
В этом поле определяются операнды, участвующие в операции.Звенья разделены между собой произвольным числом пробелов.Команды языка Ассемблер могут быть без операндов, одно или двухоперандными.Операнды разделяются запятой. Операнд может быть задан непосредственно или в виде егоадреса (прямого или косвенного). Непосредственный операнд представляет собой число илисимволическое имя с обязательным указанием префикса непосредственного операнда (#).Прямой адрес операнда может быть задан мнемоническим обозначением, числом или символическим именем. Указанием на косвенную адресацию служит префикс @.Используемые в качестве операндов символические адреса и метки должны быть определены, а числа представлены с указанием системы счисления.
Для этого применяют суффикс - букву, стоящую после числа: В - для двоичной, Q - восьмеричной, Н - шестнадцатеричной, D – для десятичной систем счисления. Если суффикс не указан, принимается десятичная система счисления.КОММЕНТАРИЙ. Поле комментария используется для текстового или символического пояснения логической организации прикладной программы. Поле комментария полностьюигнорируется транслятором, поэтому в нем допустимо использовать любые символы. По правилам языка Ассемблер поле комментария начинается после точки с запятой.Транслятор языка Ассемблер преобразует исходную программу в объектные коды.Для более точной трансляции необходимо указать некоторые дополнительные параметры.Всю эту информацию программист вставляет в исходный текст прикладной программы в виде псевдокоманд языка Ассемблер или директив, которые управляют процессом трансляциии не преобразуются в объектные коды программы.Например, псевдокоманда ORG 10Н задает транслятору адрес ячейки памяти 10Н, вкоторой расположена следующая за ней команда прикладной программы.
Ниже приведен начальный фрагмент программы диспетчера. По нулевому адресу установлена команда перехода к стартовой ячейке диспетчера, по адресу 0Вh (адресу вектора прерываний таймера Т/C0)– команда перехода к подпрограмме обработки его прерывания.ORG 0LJMP 2Bh; переход к входу в программу диспетчераORG 0ВhLJMP TIMER; переход к подпрограмме обработки прерывания таймера Т/C0ORG 2Вh; вход в диспетчер и системная настройка МКMOV SP,#64h; установка указателя на стек диспетчераMOV 24h,#0FCh ; установка значения старшего байта для регистра таймераMOV 25h,#82h; установка значения младшего байта для регистра таймераMOV TH0,24h; запись значения в старший байт регистра таймераMOV TL0,25h; запись значения в младший байт регистра таймераMOV TMOD,#11h ; установка 1-го режима Т/C0MOV TCON,#10h ; запуск таймера Т/C0MOV IE,#82h; разрешение прерываний от таймера счетчикаCLR A; очистка аккумулятораMOV 20h,A; очистка ячейки статусов квантовMOV 21h,A; очистка ячейки флагов квантовMOV 26h,A; очистка ячейки управления очередью квантовLCALL 0162h; переход к начальной настройке пользователяДля повышения точности отсчета времени с учетом разброса частоты тактового резонатора МК, значения младшего и старшего байта для регистра таймера следует откорректировать индивидуально.
Здесь задана длительность тика в 1 мкс для резонатора с частотой 11МГц. После сброса МК все его порты установлены в состояние единицы и все прерывания56запрещены. В системной настройке мы разрешили только прерывания от нулевого таймерасчетчика. В подпрограмме начальной настройки пользователя, которая должна размещаться садреса 162h, можно провести установку выводов портов в состояние, адекватно определяющее начальное состояние объекта управления, определить начальное состояние квантов пользователя и используемых в них переменных, разрешить нужные прерывания и их приоритеты, настроить приемо-передатчик и т.п.Далее за начальной настройкой следует так называемая «пультовая петля» диспетчерапроцессов.
Она ведет очередь квантов с жестким или круговым приоритетом. При жестком приоритете, при одновременном выполнении условий запуска ((FPR)*(SPR)=1), предпочтение отдается кванту с минимальным номером. При круговом приоритете предпочтение отдается кванту, следующему за только что выполненным, и далее по кругу пультовой петли. Обычно круговой приоритет выбирают в случаях, когда есть опасность постоянного захвата процессорного времени каким либо из квантов. Начальный фрагмент пультовой петли приведен ниже.ORG 4Fh; анализ состояния нулевого квантаPR0:JNB 21h.0h,PR1; если флаг нулевого кванта не установлен, переход к PR1JNB 20h.0h,PR1; если статус нулевого кванта не установлен, переход к PR1CLR 21h.0h; иначе очистить флаг квантаLCALL 149h; запустить нулевой квантJNB 26h.0h,PR0; если очередь квантов на круговая, переход в начало петлиPR1:JNB 21h.1h,PR2; анализ состояния первого кванта и так далееПодобным образом анализируется состояние всех восьми квантов.
Заканчиваетсяпультовая петля безусловным переходом на метку PR0.Обсудим, как запускать квант? Где он будет находится в памяти, диспетчер знать неможет, ведь кванты пользователя «накладываются» на готовый отлаженный универсальныйдиспетчер, который хранится в неизменяемой части памяти программ. В то же время, команда вызова подпрограммы кванта пользователя LCALL требует указания конкретного адреса ее начала.Для вызова подпрограмм с изменяемым адресом начала используют таблицу привязки, схожую по организации с таблицей векторов прерываний.
Эту таблицу размещаютв изменяемой части памяти программ. Состоит она из 8-и триад байтов. В триаду для каждого кванта после его создания вписывается переход на уже известный адрес его начала,как это показано для первого кванта. При совместной трансляции квантов пользователя сдиспетчером процессов в таблицу привязки могут быть вписаны символические адреса(названия) квантов пользователя.;------------------------векторы пользователя-------------------------ORG 149hLJMP NAME0;-------имя кванта0--------------ORG 14ChLJMP NAME1;-------имя кванта1------------------------------------------------------------------------------------------------------ORG 15EhLJMP NAME7;------- имя кванта7-------------ORG 162hLJMP USERSTART ;-------имя начальной настройки пользователя---Приступим к разработке программы прерываний таймера-счетчика. Она запускается с каждым тиком таймера и должна анализировать, не окончилась ли задержка каждогоиз восьми квантов.
Задержка для квантов может отсчитываться в малых или больших тиках в зависимости от состояния соответствующих битов регистра размерности задержек,расположенного в ячейке памяти с адресом 22h. Большой тик содержит 256 малых.Подпрограмма прерывания состоит из четырех основных частей. Первая, вводная57часть запрещает все другие прерывания на время ее выполнения. Затем, сохраняет в стекесостояние основной программы, чтобы в нее можно было без проблем вернуться и определяет, не окончился ли вместе с малым и большой тик:TIMER: CLR EA; запретить прерыванияPUSH PSW; сохранить в стеке слово состояния процессораPUSH ACC; сохранить в стеке аккумуляторSETB RS0; задать первый банк регистров МКMOV TH0,24h; восстановить в счетном регистре таймераMOV TL0,25h; начальные значенияDJNZ 23h,FL0; если счетный регистр малых тиков не ноль, переход к FL0.Именно последняя команда этого фрагмента определяет, какой тик произошел,большой или малый.