Справочник по программированию «Bascom-AVR» (М.Л. Кулиш)
.pdf===================================== Справочник по программированию «Bascom-AVR» ==
Создание микропроцессорной системы
Теория
На первом этапе создания микропроцессорной системы до начала программирования необходимо решить несколько важных задач:
а) разработать план использования ресурсов процессора, определив: какие задачи решаются программными средствами, а какие с помощью внутренних аппаратных средств микроконтроллера. Определив необходимый и достаточный состав внутренних устройств микроконтроллера, производится выбор внешних устройств, с которыми будет работать микроконтроллер. Все это, этап разработки электрической схемы микропроцессорного устройства. Именно на этом этапе происходит изучение документации на все применяемые компоненты, определение достаточности их нормируемых и функциональных возможностей для решения поставленной задачи. В круг изучаемых устройств входит и процессор, даже при условии, что используемый компилятор обеспечивает «слепую» работу с его периферией;
б) выбрать модель процессора, обеспечивающий внутренними ресурсами, разработанный план действий. Кажется, что первая и вторая задачи едины, но тут надо вспомнить о дополнительных требованиях к разрабатываемому устройству, которые могут стать приоритетными – экономичность, напряжение питания, способ программирования (записи программы), возможность перепрограммирования, поддержка компилятором и т.п. Здесь необходимо заложить некоторую избыточность производительности и, особенно, размеров памяти, обусловленную не стопроцентной эффективностью компилированного кода;
в) выбрать средство аппаратной отладки, отвечающее задаче, решаемой отлаживаемой программой и ее параметрам. Если устройство отладки забирает у системы какие-либо аппаратные или программные ресурсы, то нужно попытаться обойтись без них, или, по крайней мере, использовать их наименьшей степени и в последнюю очередь. Например, порты микроконтроллера, используемые для последовательного программирования, не нужно без крайней необходимости использовать в схеме разрабатываемого устройства;
г) провести предварительное моделирование и проверку самых важных алгоритмов обработки данных или управления физическими объектами с использование специализированных программ: “Micro-Cap”, “Mathcad”, “Quick-Basic” и т.п.;
д) определить значения требуемой производительности систем ввода-вывода, вычислений, преобразований, реагирования на внешние события. Оценить возможность решения этих задач с необходимой скоростью, например, путем написания и запуска (даже в отладчике) тестовых программ с интересующими фрагментами;
е) программы, управляющие реальными устройствами, особенно вновь применяемыми написать отдельно в виде эскизов. Эскизы включить в состав тестовых программ, проверить и отладить на реальных объектах
Время исполнения некоторых типовых операций микроконтроллера AVR на частоте генератора 8 МГц указано в таблице. Приведенные числовые значения приблизительны, так как время исполнения операций во многом зависит от значения операнда.
Действие |
Время исполнение, мкс |
Сложение и вычитание чисел в формате с плавающей точкой (Single/Double) |
20/50 |
Умножение чисел в формате с плавающей точкой (Single/Double) |
50/150 |
Деление чисел в формате с плавающей точкой (Single/Double) |
200/800 |
Вычисление математической функции в формате (Single/Double) |
1000/5000 |
Считывание (загрузка) 12-16 разр. АЦП (ЦАП) с программ. послед. интерфейсом |
20 |
Считывание (загрузка) 12-16 разр. АЦП (ЦАП) с аппаратным послед. интерф. |
10 |
Считывание (загрузка) 12-16 разр. АЦП (ЦАП) с параллельным интерфейсом. |
1 - 2 |
Опрос клавиатуры в 16 кнопок |
50-100 |
Запись байта (знака) в символьный модуль (4-битном/8-битной режиме) |
50/50 |
Запись символа (изображения или фигуры) в графический модуль |
5(200 – 1000) |
Вывод сообщения длиной 10 символов со скоростью 9.6 Кбод |
13 мс (1.1 мс на символ) |
Формирование и преобразование текстовых строк |
10-20 мкс на символ |
Преобразование числа в формате с плавающей точкой (Single/Double) в строку |
200/1000 |
Тоже в форматированную строку |
500/10000 |
Запись (считывание) четырехбайтового числа в EEPROM с интерфейсом I2C |
10000(500) |
Запись (считывание) четырехбайтового числа в внутреннее EEPROM |
20000(10) |
Измерение напряжения с помощью внутреннего АЦП |
100 - 200 |
Измерение частоты с разрешающей способностью не менее 10-4 |
10-500 мс |
При успешном решении перечисленных задач можно переходить к составлению полной схемы устройства, управляемого микроконтроллером, и разработке рабочей программы.
Если окажется, что производительность процессора недостаточна или задача слишком сложна, то следует разделить ее между несколькими процессорами или применить внешние устройства или решит ее иначе, например, используя микроконтроллер из семейства с более высокой производительностью.
============================================================================= 1
===================================== Справочник по программированию «Bascom-AVR» ==
Порядок подключения внешних устройства (приемников и источников управляющих сигналов и данных) к линиям микроконтроллера не имеет значения, если не используются уникальные свойства портов (альтернативные функции). Наличие альтернативных функций портов микроконтроллера, напротив, требует однозначной привязки внешних устройств к конкретным выводам процессора. Существует много вариантов использования и внутренних аппаратных средств. Ниже в таблице предлагается перечень аппаратных ресурсов микроконтроллера, которые предлагается для решения некоторых стандартных задач.
Задача микро- |
Рекомендуемые порты |
Используемые ресурсы |
|||||
контроллера |
|
|
|
|
|
||
Формирование |
Только порты с функцией вы- |
Таймеры 0, 1 или 2 (имеющийся в используемой модели |
|||||
частоты (вари- |
хода по совпадению: |
|
микроконтроллера) в режиме самозагрузки. Достоинства: |
||||
ант 1) |
|
|
OC0A, OC0B (Timer0), |
широкий диапазон частот и чистый сигнал. Процессор неза- |
|||
|
|
|
OC1A, OC1B (Timer1), |
гружен. |
|||
|
|
|
OC2A, OC2B (Timer2) |
|
|
||
Формирование |
Любой |
|
|
|
Любой таймер, запрограммированный вызывать прерывание |
||
частоты (вари- |
|
|
|
|
каждые полпериода, генерируемой частоты. В прерывании |
||
ант 2) |
|
|
|
|
|
|
производится инверсия порта. Невозможно формировать час- |
|
|
|
|
|
|
|
тоту выше десятков килогерц. Имеется шум периода. Загруз- |
|
|
|
|
|
|
|
ка процессора незначительная. |
Формирование |
Любой |
|
|
|
С помощью программ задержки формировать длительности |
||
частоты (вари- |
|
|
|
|
импульса и паузы выходного сигнала. Полная загрузка про- |
||
ант 3) |
|
|
|
|
|
|
цессора. Этот способ используется в операторе “Sound” |
|
|
|
|
|
|
|
Bascom. Недостаток – прерывания портят форму выходного |
|
|
|
|
|
|
|
сигнала. |
Измерение |
|
Только порты с функцией входа |
Два таймера: один формирует базу времени (интервал счета |
||||
частоты (вари- |
таймера: T0, T1, T2, T3 |
периодов измеряемой частоты); второй – счетчик числа пе- |
|||||
ант 1) |
|
|
|
|
|
|
риодов. В прерывании первого запускается и останавливается |
|
|
|
|
|
|
|
второй таймер. В прерывании второго таймера считается |
|
|
|
|
|
|
|
число переполнений в программном счетчике. |
Измерение |
|
Только порты с функцией пре- |
Любой таймер запускается или останавливается по спаду |
||||
периода |
|
рывания по фронту или спаду: |
измеряемого сигнала. Частота заполнения таймера от Fкв. |
||||
(вариант 1) |
|
INT0, INT1, ICP |
|
|
Производится подсчет длительности любого числа полупе- |
||
|
|
|
|
|
|
|
риодов. |
Измерение |
|
Только порты с функцией входа |
Два таймера: один предварительный делитель частоты. Вто- |
||||
периода |
|
таймера: T0, T1, T2, T3 |
рой счетчик длительности, который запускается или останав- |
||||
(вариант 2) |
|
|
|
|
|
ливается по переполнению таймера 2. Частота заполнения |
|
|
|
|
|
|
|
|
второго таймера от Fкв. |
Клавиатура |
из |
Любой. 8 или 10 линий для 16 |
Организовать в виде матрицы 4 на 4, 8 на 2 или 8 на 4. Для |
||||
замыкающих |
кнопок, 12 линий для 32 кнопок |
экономии портов возможно использование шины данных |
|||||
кнопок |
|
|
|
|
|
|
индикатора для опроса клавиатуры. |
Аналоговая |
|
Только порты с функцией входа |
Организовать в виде схемы резистивной матрицы, в которой |
||||
клавиатура |
из |
АЦП: ADC0…ADC7 |
|
замыкание каждой кнопка вызывает появление на входе АЦП |
|||
замыкающих |
|
|
|
|
уникального уровня напряжения. Пригодно для малокнопоч- |
||
кнопок |
|
|
|
|
|
|
ных клавиатур (не более 16 на каждый вход) |
АЦП с |
после- |
Любые. При наличии сигнала |
Программный интерфейс SPI или Micro-Wire. Наличие у |
||||
довательным |
готовности |
порт |
с |
функцией |
АЦП сигнала готовности позволяет организовать считывание |
||
интерфейсом |
прерывания по уровню INT |
по прерыванию. Могут потребоваться еще какие-то линии. |
|||||
АЦП |
с |
SPI |
Только порты |
с |
функцией |
Аппаратный интерфейс SPI. Порт SS при этом желательно не |
|
интерфейсом |
MOSI, MISO, SCK |
|
|
использовать (установить «1») |
|||
ЦАП с |
после- |
Любые или порты с функцией |
Соответственно для программного или аппаратного интер- |
||||
довательным |
MOSI, MISO, SCK |
|
|
фейса. В некоторых случаях удается использовать USART, |
|||
интерфейсом |
|
|
|
|
если он не используется по основному назначению |
||
Светодиодный |
Любые – 8(16) линий данные, |
В прерывании с частотой 300 – 1000 Гц производится про- |
|||||
7(14) - сег- |
|
остальные |
для |
кодирования |
граммой вывод данных в мультиплексном режиме из внут- |
||
ментный ин- |
знакоместа |
(соответственно |
реннего буфера, в котором формируется код всех сегментов |
||||
дикатор |
|
|
двоичного или позиционного) |
индикатора. |
|||
Символьный |
Любой – 6 линий. Рекомендует- |
Индикатор используется в режиме управления по 4-разр. |
|||||
индикатор |
|
ся использовать 4-разрядный |
Шине с побитным управлением портами, подключенными к |
||||
|
|
|
режим и линии Portc |
|
индикатору. |
||
Графический |
Два порта: рекомендуется Porta |
Данные пересылаются побайтно, а управление осуществляет- |
|||||
индикатор |
|
– шина данных, Portc – порт |
ся побитно. |
||||
|
|
|
управления |
|
|
|
|
============================================================================= 2
===================================== Справочник по программированию «Bascom-AVR» ==
Практика
Проведем разработку микропроцессорной системы поэтапно с подробным комментированием. Кроме вопросов программирования с помощью “Bascom-AVR” рассматриваются технические и организационные вопросы создания программного проекта. В качестве объекта разработки, например, выберем многофункциональные электронные часы со светодиодным индикатором.
Этап 1. «Техническое задание». Задача этапа – определение и выработка исходных данных, необходимых для создания программы.
Определим главные функциональные характеристики проекта:
-основной режим с отображением времени в формате ЧЧММ с мигающей секундной точкой;
-установка времени с клавиатуры в режиме редактирования;
-сопровождение нажатий клавиатуры звуковым сигналом.
Дополнительные функциональные режимы;
-режим будильника с остановкой времени срабатывания и звуковым сигналом (желательно мелодичным);
-режим таймера (секундомера) с отображением времени в формате ММСС;
-цифровая коррекция погрешности хода (цифровая калибровка задающего генератора);
-потенциальная возможность измерения и отображения параметров окружающей среды (температуры, влажности, давления), автоматизации обслуживания аккумулятора, регулирование яркости индикатора в зависимости от освещенности автоматически. Имеется в виду, что базовые технические и программные решения основных функций не должны препятствовать расширению системы добавлением аппаратных и программных модулей.
Основные требования к аппаратному исполнению изделия, определяемые, в том числе, функциональными характеристиками:
-минимальное число компонентов;
-четырехразрядный семисегментный индикатор. Для упрощения конструкции целесообразно использовать стандартный модуль с мультиплексным управлением. Желательно наличие единичного индикатора секунд;
-клавиатура, содержащая не менее четырех замыкающих кнопок;
-звуковой индикатор;
-система сетевого и автономного питания.
Настоящий этап заканчивается, когда определены, данные, необходимые для создания программы. Отсутствующие данные при этом вырабатываются и согласовываются. Результатом данного этапа также является, хотя бы, структурная схема подключения внешних устройств к микроконтроллеру и план распределения ресурсов, который желательно сразу оформлять в виде полей комментариев к программе.
На рисунке 1 изображена принципиальная схема разрабатываемой системы, а в заголовке последующего примера программы расписан план использования ресурсов системы. Схема разработана именно с учетом максимального использования внутренней периферии микроконтроллера и возможности расширения. Выбор модели микроконтроллера (ATmega8), в первую очередь, обусловлен двумя факторами:
-необходимостью в трех таймерах для обслуживания задач подсчета часового времени с тактированием от специального часового кварцевого резонатора (асинхронный режим), формирования временных интервалов сканирования клавиатуры и мультиплексного индикатора и формирования звуковых тонов.
-наличием аппаратно и программно совместимых старших моделей (ATmega168, ATmega16, ATmega32), позволяющих без труда расширять систему.
Этап 2. «Построение скелета программы». Задача этапа – создание драйверов внутренних и внешних устройств и на их основе общей структуры программы микропроцессорной системы.
Необходимость начать разработку программы с ее скелета обусловлено последовательным характером работы над программой, то есть, когда последовательно решаются одна задача за другой. Последовательный характер работы подразумевает и последовательную отладку программы. Ведь очевидно, что ошибки будут устраняться быстрее, если каждый вновь созданный программный модуль тут же проверять. Технология написания программ от скелета и является начальным элементов последовательного программирования. Скелет программы, должен обеспечивать функционирование всех устройств и систем, по крайней мере, той части, которые необходимы на начальном этапе разработки программы. Отлаженный скелет программы обеспечивает ввод данных, например, с клавиатуры и вывод данных, например, на индикатор. Он позволяет без применения внешних средств проверять работу вновь добавленных модулей.
Следующий далее текст демонстрационной программы, выделен шрифтом Courier. Кроме собственных комментариев в текст добавлены замечания обозначающие назначение, правильный (или рекомендуемый) порядок расположения частей программы.
============================================================================= 3
===================================== Справочник по программированию «Bascom-AVR» ==
Рисунок 1 – Схема электрическая принципиальная электронных часов
ПРОГРАММА 1
Заголовок Комментарии, содержащие идентифицирующие сведения о программе: принадлежность изделию, номер версии, дату и место создания, имя автора, его телефоны и местонахождение, версии компилятора, модель процессора, способ отладки (и как это отражено в программе), способ программирования, используемые ресурсы микроконтроллера и все то, что невозможно узнать из последующего текста.
'------------------------------------------
'Программа электронных часов "AVR-WATCH" '------------------------------------------
'Микроконтроллер типа ATMEGA8
' |
------------------------------------------ |
|
Fuses: |
|
' Программируемые |
- низкочастотный кварцевый резонатор |
|||
' ... |
CKSEL3 |
CKSEL0 |
= 1001 |
'CKOPT = 0 - внутренние конденсаторы подключены к кварцевому резонатору
'RSTDISBL = 1 - порт PC6 используется как сброс
'WDTON = 1 - сторожевой таймер разрешен
'SPIEN = 0 - последовательное программирование разрешено
'BOOTSZ1,BOOTSZ0 = 00, BOOTRST=1 - параметры загрузчика
'EESAVE = 1 - НЕ ОЧИЩАТЬ EEPROM при программировании
'BODLEVEL = 1, BODEN = 1 - ПАРАМЕТРЫ СБРОСА
'SUT1 = 1,SUT1 = 0 - ВРЕМЯ СТАРТА
'------------------------------------------
'Используемый ресурсы микроконтроллера:
'Генератор RC - внутренний 1 МГц, а к TOSC1 and TOSC2 подключен кристалл 32768 Гц
'Timer0 – генератор прерываний с частотой 250 Гц для обслуживания индикатора, клавиатуры
'и других служб реального времени
============================================================================= 4
===================================== Справочник по программированию «Bascom-AVR» ==
'Timer1 – генератор звукового сигнала программируемой частоты
'На выходе PB1 (OC1A) формируется звуковой сигнал в форме меандра
'Timer2 – генератор прерываний с частотой 1 Гц, на основании которого вычисляется пройденное время
'Дополнительно на выходе PB3 (OC2) формируются импульсы длительностью 1 с (0.5 Гц),
'используемые для включения единичного светодиода
'Индикатор:
' |
Portd выход сегментов, Portc0... |
Portc3 - код знакоместа (позиционный). Он же порт |
' |
сканирования клавиатуры. Индикатор с общим анодом. Активным уровнем - является "0" |
' Четыре кнопки: Port0... |
Portc3 - код сканирования клавиатуры, Portc4 - линия возврата клавиатуры |
|
' |
На линию Portc5 от источника питания "+5 В" приходит сигнал "Включение сети" |
|
' |
------------------------------------------ |
|
Определить модель |
Записать имя файла, |
определяющего набор (имена) регистров с помощью директивы |
микроконтроллера |
$Regfile. Если это не сделать, но компилятор использует установки меню Options |
|
$regfile = "m8def.dat" |
'определить тип микроконтроллера |
|
'------------------------------------------ |
|
|
Определение Блок определения переменных оформляется в порядке возрастания их длины: Byte, Word, переменных Integer, Long, Single, Double, String, Array. Переменные типа Bit не имеют смысла, тоже зани-
мают один байт и принимают только два значения нуль и не нуль
Dim Ndat As Byte |
'признак "обновить данные" |
|
Dim Ddat As Byte |
'признак "обновить индикатор" |
|
'--------------------- |
|
'счетчик времени звонка |
Dim R_btim As Byte |
||
'--------------------- |
|
'счетчик секунд |
Dim Rsec As Byte |
||
Dim Rmin As Byte |
'счетчик минут |
|
Dim Rhour As Byte |
'счетчик часов |
|
'--------------------- |
|
'код нажатой кнопки |
Dim Buf_kl As Byte |
||
Dim Buf_pkl As Byte |
'предварительный код нажатой кнопки |
|
Dim R_ckl As Byte |
'счетчик удержания клавиатуры |
|
'--------------------- |
|
'буфер индикации (копия сегментов) |
Dim Buf_dis(4) As Byte |
||
Dim Cnt_dis As Byte |
'счетчик индикации |
|
'--------------------- |
|
'текстовая строка |
Dim Bufr As String * 20 |
||
'------------------------------------------ |
|
|
|
Объявление используемых прерываний и имен программ обработки прерываний (векторов). |
|
Настройка |
||
прерываний |
Задание типа прерываний и приоритетов. Применение опции Nosave обеспечивает отключение |
|
|
режима сохранение всех регистров общего назначения (R0…R31 и Sreg) |
'назначение векторов прерывания.
On Timer0 Timer0_int Nosave |
'вектор прерывания от таймера 0 |
|
On Timer2 Timer2_int Nosave |
'вектор прерывания от таймера 2 |
|
'------------------------------------------ |
|
|
|
Объявление частоты тактового генератора, скорости и последовательного интерфейса, режима |
|
Настройка |
||
периферии |
счетчиков, портов. Если, что-то из необходимых параметров конфигурации не будет объявлено, |
|
|
то компилятор использует значения, установленные в окнах меню Options |
$crystal = 1000000 |
'генератор 1 МГц |
||
' |
--------------------- |
'режим IDLE – разрешить |
|
Mcucr = &B10000000 |
|||
' |
ТАЙМЕРЫ |
'режим таймера 0: Fкв/64 - часы реального времени |
|
Tccr0 = &B00000011 |
|||
'--------------------- |
|
'режим таймера 1: генератор звука 2 кГц с выходом на PB1 |
|
Tccr1a = &B01000000 |
|||
(OC1A) |
'делитель Fкв / 1 и с выходам Oc1a |
||
Tccr1b = &B00001000 |
|||
Ocr1ah = 0 : Ocr1al = 250 |
'и коэффициетном Fкв/250*2 |
||
'--------------------- |
|
'режим таймера 2: генератор секундных импульсов |
|
Assr.3 = 1 : Wait 1 |
|||
'включить НЧ-генератор AS2 и подождать стабилизации амплитуды |
|||
Tcnt2 = 0 : Waitms 10 |
'очистить счетчик и подождать |
||
Ocr2 = 128 : Waitms 10 |
'пока значение перепишется из временного буфера |
||
'установить значение сравнения |
|||
Tccr2 = &B00010101 |
'установить коэффициент деления прескалера К=128 |
||
'и выход секундных импульсов на PB3 (OC2) |
|||
'--------------------- |
|
|
'ПОРТЫ
Ddrb |
= |
&B00001010 |
'направление линий порта B: 1 - на вывод |
Portb |
= |
&B11111111 |
'исходное состояние линий B: hhhh1h1h |
============================================================================= 5
===================================== Справочник по программированию «Bascom-AVR» ==
'--------------------- |
|
'направление линий порта C: 1 - на вывод |
Ddrc = &B00001111 |
||
Portc = &B11111111 |
'исходное состояние линий C: hhhh1111 |
|
'--------------------- |
|
'направление линий порта D: 1 - на вывод |
Ddrd = &B00000000 |
||
Portd = &B11111111 |
'исходное состояние линий D: hhhhhhhh |
|
' |
|
'* h - высокий уровень, подтянутый через резистор |
|
|
|
|
Разрешение отдельных типов прерываний и общее разрешение. Выполняется после инициали- |
|
Разрешение |
||
прерываний |
зации периферии |
|
'Прерывания
Timsk = |
&B010000001 |
'разрешить |
прерывание от переполнения таймера 0 и таймера 2 |
‘Enable |
Timer0 |
'допускаемая, но не рекомендуемая форма |
|
‘Enable |
Timer2 |
'разрешить |
прерывания. |
Enable Interrupts |
|||
'--------------------- |
|
|
Основная |
|
Главная программа и ее ветви. Описывается построение главного цикла программы, в котором |
|
|
программа |
|
происходит ожидание событий, и ветви отработки поступающих Чтобы придать главной про- |
|
|
|
|
грамме компактный вид, повторяющиеся и функционально законченные модули оформляются в |
|
|
|
|
виде подпрограмм. |
|
|
'ГЛАВНЫЙ ЦИКЛ |
|
|
||
Mc: |
|
|
|
|
Idle |
|
|
|
|
Goto Mc |
|
|
|
|
'---------------------------------------------------------------------------------- |
|
|
|
|
|
Обычно небольшие по объему модули для быстрой реакции на события, и поэтому критичные |
|
||
Подпрограм- |
|
|||
мы обработки |
к времени исполнения и количеству используемых ресурсов. Программы обработки прерыва- |
|
||
прерываний |
|
ний, в первую очередь, пишутся на ассемблере. Данные из программ прерывания передаются |
|
|
|
|
|
главной программе через общие регистры. |
|
'обработка прерывания таймера 0 'используется как часы реального времени с частотой 244 Гц (4 мс)
'для этого нужно организовать схему деления 1 МГц/64/64 = 0,000244140625 МГц
Timer0_int:
$asm |
'сохраним регистры |
Push R31 |
|
In R31 , Sreg |
|
Push R31 |
|
Push R30 |
|
'----- |
'переустановим счетчик |
Ldi R31 , 192 |
|
Out Tcnt0 , R31 |
|
'--------------------- |
'вывод в индикатор |
Rcall Led_out |
|
Rcall In_kl |
'опрос клавиатуры |
'--------------------- |
|
'обработка счетчика времени звонка |
|
Intt2_1: |
'считаем счетчик времени звонка |
Lds R31 , {r_btim} |
|
And R31 , R31 |
'если он равен 0 - переход |
Breq Intt2_2 |
|
Dec R31 |
'уменьшить |
Sts {r_btim} , R31 |
'и разрешить пищать |
Ldi R31 , &B00001001 |
|
Rjmp Intt2_3 |
|
Intt2_2: |
'запретить пищать |
Ldi R31 , &B00001000 |
|
Intt2_3: |
'в регистр управления таймером 2 |
Out Tccr2 , R31 |
|
'----- |
'восстановим регистры |
Pop R30 |
|
Pop R31 |
|
Out Sreg , R31 |
|
Pop R31 |
'дополнительная команда завершения прерывания |
Reti |
'в конце процедуры |
его обработки. Рекомендуется применять перед каждой |
командой |
Return, |
которая |
||||||
'должна скомпилироваться как Reti, однако |
по какой-то |
причине может быть пропущена |
и |
|
||||||
'скомпилирована как Ret. Подобное |
может |
происходить, |
когда в программе |
обработки прерывания |
||||||
'применено несколько команд завершения, |
а |
компилятор |
автоматически |
заменяет Ret |
на |
Reti |
только |
|||
'один раз – только |
первую команду |
Return после метки, |
обозначающей |
начало программу прерывания. |
============================================================================= 6
===================================== Справочник по программированию «Bascom-AVR» ==
$end Asm Return
'----------------------------------------------
'обработка прерывания таймера 2. Происходит 1 раз в секунду
Timer2_int:
$asm |
'сохраним регистры |
Push R31 |
|
'----- |
|
Ldi R31 , 255 |
|
Sts {ndat} , R31 |
|
'----- |
'восстановим регистры |
Pop R31 |
|
$end Asm |
|
Return |
|
'---------------------------------------------------------------------------------- |
|
Драйверы устройств (подпрограммы обслуживания периферии ввода вывода)
Экономичные, небольшие и быстро работающий модули. Также критичные к времени исполнения и используемым ресурсам. Используются при обработке прерываний. Также пишутся на ассемблере.
'ВВОД ДАННЫХ С КЛАВИАТУРЫ
'клавиатура опрашивается при выводе очередного знакоместа на индикатор
'код кнопки совпадает с номером знакоместа. Осуществляется подавление дребезга
'срабатывание фиксируется при удержании более 6 циклов опроса
In_kl: |
|
|
$asm |
|
'пока буфер клавиатуры не опустеет |
Lds R31 ,{Buf_kl} |
||
And R31 , |
R31 |
'сканирование не проводится |
Breq Inkl |
|
|
Ret |
|
|
'--------- |
|
|
' НАЧИНАЕМ |
|
|
Inkl: |
|
'подготовим счетчика нажатий к обработке |
Lds R31 , {r_ckl} |
||
Sbic Pinc , 4 |
'считать состояние линии опроса кнопки |
|
Rjmp N_st |
|
'нет нажатия - переход |
'--------- |
|
|
' НАЖАТИЯ ЕСТЬ |
|
|
Y_st: |
|
'если равен 6 - нажатие уже было зафиксировано |
Cpi R31 , 6 |
||
Breq Y_st1 |
|
'на выход без запоминания. |
Inc R31 |
|
'иначе нужен инкремент |
Sts {r_ckl} , R31 |
'и сохранить |
|
Cpi R31 , 6 |
'меньше 6 - тоже выход без действий |
|
Brne y_st1 |
|
|
'--------- |
|
|
' НАЖАТИЕ ЗАФИКСИРОВАТЬ |
'звонить 60 мс |
|
Ldi R31 , 3 |
||
Sts {r_btim} , R31 |
'преобразуем код знакоместа (от 0 до 3) |
|
Lds R31 , {Cnt_dis} |
||
Inc R31 |
|
'в код кнопки (от 1 до 4) |
Sts {Buf_kl} , R31 |
|
|
Y_st1: |
|
|
Ret |
|
|
'--------- |
|
|
' НАЖАТИЯ НЕТ |
|
|
N_st: |
|
'проверим счетчик "удержания" |
And R31 , R31 |
||
Breq N_st1 |
|
'не равен нулю |
Dec R31 |
|
'декремент |
Sts {r_ckl} , R31 |
'и сохранить |
|
N_st1: |
|
|
Ret |
|
|
$end Asm |
|
|
'---------------------------------------------------------------------------------- |
|
' МАСКА СКАНИРОВАНИЯ ДЛЯ ОА |
Const N_scn = &B11110000 |
||
Const N_sc1 = &B11111110 |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА |
|
Const N_sc2 = &B01111101 |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА |
|
Const N_sc3 = &B11111011 |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА |
|
Const N_sc4 = &B11110111 |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА |
|
'----------------------------- |
|
|
'обслуживание светодиодного 7-сегментного индикатора |
||
Led_out: |
|
|
$asm |
|
'считать значение счетчика сканирования |
Lds R31 , {Cnt_dis} |
||
Inc R31 |
|
|
Andi R31 , 3 |
'и сохранить |
|
Sts {Cnt_dis} , R31 |
============================================================================= 7
===================================== Справочник по программированию «Bascom-AVR» ==
'--------- |
1 |
|
Cpi R31 , |
|
|
Breq Led_1 |
|
|
'--------- |
2 |
|
Cpi R31 , |
|
|
Breq Led_2 |
|
|
'--------- |
3 |
|
Cpi R31 , |
|
|
Breq Led_3 |
|
|
Led_0: |
|
|
'--------- |
{buf_dis} |
|
Lds R30 , |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА |
|
Ldi R31 , |
N_sc1 |
|
Rjmp Led_e |
|
|
'--------- |
|
|
Led_1: |
{buf_dis+1} |
|
Lds R30 , |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА |
|
Ldi R31 , |
N_sc2 |
|
Rjmp Led_e |
|
|
'--------- |
|
|
Led_2: |
{buf_dis+2} |
|
Lds R30 , |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА |
|
Ldi R31 , |
N_sc3 |
|
Rjmp Led_e |
|
|
'--------- |
|
|
Led_3: |
{buf_dis+3} |
|
Lds R30 , |
' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА |
|
Ldi R31 , |
N_sc4 |
|
Led_e: |
, R30 |
|
Out Portd |
|
|
In R30 , Portc |
' МАСКА СКАНИРОВАНИЯ |
|
Ori R30 , |
N_scn |
|
And R30 , |
R31 |
|
Out Portc |
, R30 |
|
Ret |
|
|
$end Asm '----------------------------------------------------------------------------------
Скелет готов. Еще раз о результатах проделанной работы. Приведенная выше программа является полностью работоспособной, но при этом не совершает никаких внешних действий. С ее помощью оживлена и функционирует вся периферия, однако со стороны основной программы это будет незаметно, так как все устройства будут обслуживаться в фоновом режиме. Во-вторых, почти все написано на ассемблере и это сделано для полного контроля используемых ресурсов и обеспечения максимальной производительности, что является немаловажным при низкой тактовой частоте. В-третьих, практически аппаратная реализация счетчика прошедшего времени, звукового тонального генератора и мультиплексного индикатора обеспечивает хорошие потребительские свойства изделия за счет исключения «паразитных» эффектов, свойственных программной реализации этих функций, таких как погрешность хода, «грязный» (модулированный) звук, низкочастотное мерцание отдельных знакомест (за счет неравномерности и неодинаковости времени свечения). В-четвертых, система готова работать и для выполнения многих других задач и обеспечивает необходимую возможность расширения
Этап 3. «Построение главного цикла программы». Задача этапа – создание базовой структуры программы и определение номенклатуры базовых программных модулей.
Структура программы с ГЛАВНЫМ ЦИКЛОМ (ГЦ) является базовой для продолжительно работающих программ с многократно повторяющимся алгоритмом обработки данных. С другой стороны, ГЦ является средством выравнивания скорости работы более быстрого процессора и медленного процесса генерации исходных данных. Как правило, в ГЦ осуществляется последовательная проверка необходимости выполнения некоторого набора задач. Малое время исполнения опроса обеспечивает быстрое реагирования на события. В ГЦ включается операция перевода ядра микроконтроллера в спящий режим, способствующий снижения потребления энергии во время ожидания заданий. Выход из спящего режима происходит только по прерыванию и это не вызывает затруднений, так как и появление новых задач обычно обусловлено прошедшим прерыванием. По крайней мере, программа строится так, чтобы наиболее важные события сами вызывали прерывания или возникали вследствие прерываний.
Для нашего примера в ГЦ будет осуществляться проверка всего трех задач:
-окончания очередной секунды, по появлению ненулевого значения переменной “Ndat” ;
-нажатие кнопки, по появлению ненулевого значения переменной “Buf_kl” ;
-обновления индикатора, по появлению ненулевого значения переменной “ Ddat ” .
============================================================================= 8
===================================== Справочник по программированию «Bascom-AVR» ==
ПРОГРАММА 2
Главный |
Состоит из операций проверки появления одной из задач, вызова программы обработки задачи и |
||
цикл |
очистки признака наличия задачи. Причем для клавиатуры очистка производится после обработки, |
||
|
так как сам признак является носителем информации о номере кнопки. Проверяемые задачи рас- |
||
|
полагаются в порядке приоритета, а после обработки одно задачи производится переход на начало |
||
|
ГЦ. |
|
|
'---------------------------------------------------------------------------------- |
|
|
|
'ГЛАВНЫЙ ЦИКЛ |
|
|
|
Mc: |
|
|
|
If Ndat <> 0 Then |
'очистить "обновить данные" |
||
Ndat = 0 |
|||
Gosub New_data |
'обработать данные |
||
Goto Mc |
|
|
|
End If |
|
|
|
If Ddat <> 0 Then |
'очистить "обновить индикатор" |
||
Ddat = 0 |
|||
Gosub New_led |
'обновить индикатор |
||
Goto Mc |
|
|
|
End If |
|
|
|
If Buf_kl <> 0 Then |
'обработать нажатие, только потом |
||
Gosub W_klb |
|||
Buf_kl = 0 |
'очистить уже обработанное нажатие |
||
Goto Mc |
|
|
|
End If |
|
|
|
Idle |
|
|
|
Goto Mc |
|
|
|
'---------------------------------------------------------------------------------- |
|
|
|
|
|
|
|
Заготовки для программ |
Создаются одновременно с оформлением структуры ГЦ, чтобы не потерять все |
||
обработки событий ГЦ |
имеющиеся метки (имена подпрограмм) |
|
'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА
'---------------------
'обработать данные времени по истечении секунды
New_data:
Return '----------------------------------------------------------------------------------
'обновить индикатор по завершению одной из операций в соответствии с текущим состоянием
New_led:
Return '----------------------------------------------------------------------------------
'обработать нажатие кнопки в соответствии с текущим режимом
W_klb:
Return '----------------------------------------------------------------------------------
После добавления конструкции ГЦ программа работоспособна и пригодна к дальнейшему расширению путем добавления новых к списку задач.
Этап 4. «Создание программ главного цикла». Задача этапа – создание исполнительных программных мо-
дулей.
Данный этап позволяет создать первую версию рабочей программы, в соответствие с задачами, решаемыми программами ГЦ. При этом происходит описание действий, производимой программой.
ПРОГРАММА 3 |
|
|
|
|
Содержать три программных модуля по числу обрабатываемых задач |
|
|
Рабочие программы |
|
||
'---------------------------------------------------------------------------------- |
|
|
|
'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА |
|
|
|
'--------------------- |
|
|
|
'обработать данные времени по истечении секунды |
|
||
New_data: |
|
'плюс секунда |
|
Incr Rsec |
|
|
|
If Rsec > 59 Then |
|
'при необходимости |
|
Rsec = 0 : Goto Ndata1 |
'скорректировать счетчик секунд |
|
|
End If |
|
|
|
Goto Ndata3 |
|
|
|
Ndata1: |
|
'плюс минута |
|
Incr Rmin |
|
|
|
============================================================================= |
9 |
===================================== Справочник по программированию «Bascom-AVR» ==
If Rmin > 59 Then |
'при необходимости |
Rmin = 0 : Goto Ndata2 |
'скорректировать счетчик минут |
End If |
|
Goto Ndata3 |
|
Ndata2: |
'плюс час |
Incr Rhour |
|
If Rhour > 23 Then |
'при необходимости |
Rhour = 0 |
'скорректировать счетчик часов |
End If |
|
Ndata3: |
'поставить признак обновления индикации |
Ddat = 255 |
|
Return |
|
'---------------------------------------------------------------------------------- |
|
Программа |
Самая сложная программа. Содержит последовательность преобразований (символьное изо- |
формирования |
бражение – двоичное число – сегментный код числа). Повторяющиеся модули оформлены в |
изображения |
виде подпрограмм. |
'обновить индикатор по завершению одной |
из операций в соответствии с текущим состоянием |
New_led: |
|
'сформировать символьное изображение времени |
|
Bufr = "" |
'очистить строку |
If Rhour < 10 Then |
'если значение часов выражается одной цифрой |
Bufr = Bufr + "0" |
'добавить символ лидирующего нуля |
End If |
'добавить значение часов |
Bufr = Bufr + Str(rhour) |
|
If Rmin < 10 Then |
'если значение часов выражается одной цифрой |
Bufr = Bufr + "0" |
'добавить символ лидирующего нуля |
End If |
'добавить значение минут |
Bufr = Bufr + Str(rmin) |
|
'--------- |
'получить код первого знакоместа |
Gosub Asc_seg : Buf_dis(4) = Tmpb |
|
'--------- |
'получить код второго знакоместа |
Gosub Asc_seg2 : Buf_dis(3) = Tmpb |
|
'--------- |
'получить код третьего знакоместа |
Gosub Asc_seg2 : Buf_dis(2) = Tmpb |
|
'--------- |
'получить код четчертого знакоместа |
Gosub Asc_seg2 : Buf_dis(1) = Tmpb |
|
'--------- |
|
Return |
|
|
|
|
|
|
|
|
'----------------------------------------------------------- |
|
|
|
|
|
|
КОДЕ ИЗ ASCII (ВТОРОГО СИМВОЛА) |
|
'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ |
||||||||
Asc_seg2: |
|
|
|
|
'сдвинуть строку влево на одну позицию |
|||
Bufr = Mid(bufr , 2) |
|
|
||||||
'--------- |
|
|
|
|
|
|
КОДЕ ИЗ ASCII |
|
'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ |
||||||||
Asc_seg: |
|
|
|
|
'считать |
первый символ строки |
||
Tmpb = Asc(bufr) |
|
|
|
|||||
Tmpb = Tmpb - &H30 |
|
|
|
'преобразовать ASCII в число |
||||
Tmpb = Lookup(tmpb , Tabseg0) |
|
'считать |
из таблицы, используя число как смещение |
|||||
Return |
|
|
|
|
|
|
|
|
'--------- |
|
|
|
|
|
|
|
|
'ТАБЛИЦА РАСПОЛОЖЕНИЯ СЕГМЕНТОВ ИНДИКАТОРА - ПРОТОТИПА |
|
|||||||
'--------- |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
' |
||||||||
' |
¦-----------------------------------------------h1 |
g1 |
f1 |
e1 |
d1 |
c1 |
b1 |
a1 |
'BUF_DIS(1) |
||||||||
'BUF_DIS(2) |
¦ h2 |
g2 |
f2 |
e2 |
d2 |
c2 |
b2 |
a2 |
'BUF_DIS(3) |
¦ h3 |
g3 |
f3 |
e3 |
d3 |
c3 |
b3 |
a3 |
'BUF_DIS(4) |
¦ h4 |
g4 |
f4 |
e4 |
d4 |
c4 |
b4 |
a4 |
'------------------------------------------- |
|
|
|
|
|
|
|
|
'РАСПОЛОЖЕНИЕ СЕГМЕНТОВ НА ПОЛЕ ИНДИКАТОРА
'===============================================
' ¦ |
-a4- |
|
-a3- |
|
|
-a2- |
-a1- |
|
¦ |
' ¦ |
I |
I |
I |
I |
¦ |
||||
' ¦ I |
I |
I |
I |
¦ |
|||||
' ¦ |
f4 |
b4 |
f3 |
b3 |
f2 |
b2 |
f1 |
b1 |
¦ |
' ¦ I |
I |
I |
I |
I |
I |
I |
I |
¦ |
|
' ¦ |
-g4- |
I |
-g3- |
I |
I |
-g2- |
-g1- |
I |
¦ |
' ¦ I |
I |
I |
I |
¦ |
|||||
' ¦ |
e4 |
c4 |
e3 |
c3 |
e2 |
c2 |
e1 |
c1 |
¦ |
' ¦ I |
I |
I |
I |
I |
I |
I |
I |
¦ |
|
' ¦ |
-d4- |
[h4] |
-d3- |
[h3] |
|
-d2- |
-d1- |
|
¦ |
' ¦ |
|
|
|
[h2] |
|
[h1]¦ |
|||
' ¦ |
=============================================== |
¦ |
|||||||
' |
|
||||||||
'----------------------------------------------------------- |
|
|
|
|
|
|
15(0Fh) , СВЕЧЕНИЕ "0" |
||
' ТАБЛИЦА КОДОВ СЕГМЕНТОВ ОТ 0(00h) ДО |
============================================================================= 10