Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Справочник по программированию «Bascom-AVR» (М.Л. Кулиш)

.pdf
Скачиваний:
1045
Добавлен:
12.08.2013
Размер:
1.24 Mб
Скачать

===================================== Справочник по программированию «Bascom-AVR» ==

'

-----------------------------------------------------------

 

 

 

 

'ШЕСТНАДЦАТИРИЧНЫЕ ЦИФРЫ

 

 

 

Tabseg0:

 

 

 

 

 

 

&HC0

 

, &HF9

 

 

 

' 0 , 1

-d0 -

 

 

Data

 

 

 

 

I

 

Data

&HA4

 

, &HB0

 

 

 

' 2 , 3 I

 

 

Data

&H99

 

, &H92

 

 

 

' 4 , 5 D5

D1

 

Data

&H82

 

, &HF8

 

 

 

' 6 , 7 I

-d6 -

I

 

Data

&H80

 

, &H90

 

 

 

' 8 , 9

I

 

Data

&H88

 

, &H83

 

 

 

' A , B I

 

 

Data

&HC6

 

, &HA1

 

 

 

' C , D D4

D2

 

Data

&H86

 

, &H8E

 

 

 

' E , F I

-D3-

I

'

 

 

 

 

 

 

 

 

 

'

 

 

[D7]

----------------------------------------------------------------------------------

 

 

 

программы клавиатуры

 

 

 

 

'

 

 

 

 

 

 

 

 

'---------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

' ---------------------------------------

|

 

 

 

 

AVR-WATCH

 

 

 

|

 

 

'

 

 

 

 

 

 

 

 

 

' ---------------------------------

|

|

---

 

 

---

 

---

 

---

|

|

 

 

'

|

|

|

|

|

|

 

 

'

| | |

|

|

|

| |

 

 

'

|

|

---

|

|

---

|

---

|

---

|

|

 

 

'

| | |

|

|

|

| |

 

 

'

|

|

---

 

[]

--- []

 

--- []

 

--- [] |

|

 

 

' ---------------------------------

|

 

1

 

 

2

 

3

 

4

 

|

 

 

'

|

 

 

 

 

 

 

|

 

 

'

|

 

_

 

 

_

 

_

 

_

 

|

 

 

'

|

 

|_|

 

 

|_|

 

|_|

 

|_|

 

|

 

 

'

|

 

Reset

 

+

 

+

 

-

 

|

 

 

'

|

 

 

 

 

 

|

 

 

'

|

 

Min

 

 

Hour

 

Min

 

Min

 

|

 

 

' ---------------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'выполнение программ обработки кнопок - основной список

'0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й

'1: Сбросить минуты 2: Добавить час 3: Добавить минуту 4: Убавить минуту

'---------------------------------------------------------

Программа обНазначение кнопок выбрано произвольно. Для перехода к программам обработки кнопок работки кнопок используется специальная функция On – Goto с индексированием списка меток. Дает быстрый и экономичный код. Применение функции Select Case не рекомендуется, так как не по-

зволяет вкладывать объемные конструкции.

W_klb:

On Buf_kl Goto Kn , Km1 , Km2 , Km3 , Km4

'обработать нажатие кнопки

 

'---------

 

Km1:

'сбросить минуты

Rmin = 0

If Rmin > 30 Then

'при необходимости округления

Goto Km2

'скорректировать счетчик минут

End If

 

Km1_1:

'поставить признак обновления индикации

Ddat = 255

Kn:

 

Return

 

'---------

 

Km2:

'плюс час

Incr Rhour

If Rhour > 23 Then

'при необходимости

Rhour = 0

'скорректировать счетчик часов

End If

 

Goto Km1_1

 

'---------

 

Km3:

'плюс минута

Incr Rmin

If Rmin > 59 Then

'при необходимости

Rmin = 0

'скорректировать счетчик минут

End If

 

Goto Km1_1

 

'---------

 

Km4:

'минус минута

Decr Rmin

If Rmin = 255 Then

'при необходимости

Rmin = 59

'скорректировать счетчик минут

End If

 

Goto Km1_1

 

'----------------------------------------------------------------------------------

 

============================================================================= 11

===================================== Справочник по программированию «Bascom-AVR» ==

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

-простое добавление новых функций по имеющимся правилам работы программы. Этот путь пригоден для небольших добавлений, похожих на уже имеющиеся;

-добавление новых функций по другим правилам построения программы. Необходимость в этом возникает при создании многофункциональных систем и обычно решается создание других разделов с собственной структурой ГЦ;

-добавление сложных функций в виде отдельных модулей, содержащих все необходимые компоненты ввода и отображения данных. Это приемлемый вариант реализации небольшого количества функций при некритичном времени реагирования на внешние воздействия. Примером таких функций могут быть программы тестирования, сохранения данных, обработка протокола установления связи;

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

Этап 5. «Создание утилит для расширения функциональных возможностей». Задача этапа – создание набора стандартных программных модулей для выполнения элементарных операций.

Требуемый для расширения набор утилит определяется составом добавляемых функций. Выберем, например, следующий набор расширяемых режимов:

-выбор с помощью меню;

-многофункциональная клавиатура;

-отображение текстовых сообщений.

Для этого нам понадобятся следующие утилиты:

-вывод указанного текстового сообщения на индикатор, например, с помощью индекса;

-останов на фиксированное время с ожиданием нажатия кнопки.

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

Этап 6. «Расширение функциональных возможностей с помощью утилит».

В программу версии 2 добавлено:

-несколько новых переменных для обеспечения работы новых систем;

-расширена функция программы прерывания таймера 0. Добавлена ветка формирования временных интервалов 64 мс и проверка запрета звукового сигнала;

-расширена функция программы формирования изображения;

-добавлен и выделен отдельно раздел утилит (вспомогательных универсальных программ формирования изображения и управления). Там же расположены расширенные таблицы кодов сегментов и сообщений;

-добавлено начальное сообщение;

-изменены и добавлены функции клавиатуры. Функции, конечно, надуманные, но это демонстрационная программа. Показан один из основных механизмов создания многофункциональной клавиатуры;

-добавлены программы коррекции монтажа индикатора и клавиатуры (при отклонении фактической разводки от теоретической модели.

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

Этап 7. «Оптимизация программы».

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

-просмотреть текст программы и одинаковые участки, даже если это всего одна строка, попытаться оформить в качестве отдельной подпрограммы. В приведенной программе такие примеры имеются;

-попробовать свести к одной подпрограмме похожие участки программы, сделав, например, несколько входов с различными параметрами и промежуточное преобразование;

-устранить слишком длинные участки программ, оформив их как функционально законченную подпрограмму. В первую очередь это относится к вычислительным программам;

============================================================================= 12

===================================== Справочник по программированию «Bascom-AVR» ==

-провести подробное комментирование программы. Особенно тщательно описывая, протоколы, форматы данных, условия принятия решение, обязательно применительно к тем физическим процессам, с которыми взаимодействует программа;

-в максимальной степени представить применяемые цифровые константы в символьном виде. Их определение вынести в заголовки и указать их назначение;

-обязательно указать номер версии продукта, разницу в версиях (историю доработок), дату создания (компиляции), версию и тип компилятора.

После оптимизации (и в процессе тоже) необходимо провести повторную компиляцию и проверку функционирования.

ПРОГРАММА 4

Вторая версия программы Содержит все добавления.

'------------------------------------------

' Программа "AVR-WATCH" (версия 2)

'------------------------------------------

 

типа 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 Гц

'На выходе PB3 (OC2) импульсы длительностью 1 с (0.5 Гц)

'На выходе PB1 (OC1A) звуковой сигнал

'Порт Portd выход сегментов

' Portc0...

Portc3 - код знакоместа (позиционный) он же порт сканирования клавиатуры

' Четыре кнопки: Port0...

Portc3 - код сканирования клавиатуры, Portc4 - линия возврата клавиатуры

'------------------------------------------

 

'определить тип микроконтроллера

$regfile = "m8def.dat"

'------------------------------------------

 

'признак "обновить данные"

Dim Ndat As Byte

Dim Ddat As Byte

'признак "обновить индикатор"

'---------------------

 

'режим отображения: 0 - ЧЧММ, 1 - ММСС, 2 - погашен

Dim Mdisp As Byte

Dim Msnd As Byte

'режим звука: 0 - включен, <>0 - выключен

'---------------------

 

'программный счетчик времени

Dim S_tim As Byte

Dim W_tim 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 Tmpb As Byte

'временное значение

Dim Index As Byte

'временное значение

Dim Value As Byte

'временное значение

'---------------------

 

'текстовая строка

Dim Bufr As String * 10

'------------------------------------------

 

'генератор 1 МГц, необходим компилятору для правильного

$crystal = 1000000

'

 

' вычисления задержек и других временных параметров

 

 

'назначение векторов прерывания.

On Timer0 Timer0_int Nosave

'вектор прерывания

от

таймера 0

On Timer2 Timer2_int Nosave

'вектор прерывания

от

таймера 2

'------------------------------------------

'режим IDLE - разрешить

Mcucr = &B10000000

============================================================================= 13

===================================== Справочник по программированию «Bascom-AVR» ==

'ТАЙМЕРЫ

Tccr0 = &B00000011

'режим таймера 0: Fкв/64 - часы реального времени

'

---------------------

 

'режим таймера 1:

Tccr1a

= &B01000000

'генератор звука 2 кГц с выходом на PB1 (OC1A)

Tccr1b

= &B00001000

'делитель Fкв / 1 и с выходам Oc1a

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)

'

---------------------ПОРТЫ

 

'

'направление линий порта B: 1 - на вывод

 

Ddrb = &B00001010

Portb = &B11111111

'исходное состояние линий B: hhhh1h1h

'

Ddrc---------------------= &B00001111

'направление линий порта C: 1 - на вывод

Portc = &B11111111

'исходное состояние линий C: hhhh1111

'

Ddrd---------------------= &B00000000

'направление линий порта D: 1 - на вывод

Portd = &B11111111

'исходное состояние линий D: hhhhhhhh

'

 

 

'* h - высокий уровень, подтянутый через резистор

---------------------прерывания.

 

'

 

Timsk = &B010000001

'разрешить прерывание от переполнения таймера 0

Enable

Timer0

Enable

Timer2

'разрешить прерывание от переполнения таймера 2

Enable

Interrupts

'разрешить прерывания.

'

---------------------Index = 1 : Gosub Dis_tr

'ВЫВОД СООБЩЕНИЯ СООБЩЕНИЯ (НОМЕР ВЕРСИИ)

 

Wait 1

'подождать

'ГЛАВНЫЙ ЦИКЛ

 

Mc:

Ndat <> 0 Then

 

 

If

'очистить "обновить данные"

 

 

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 Tr_klb

'скорректировать номер кнопок

 

 

Gosub W_klb

'обработать нажатие

 

 

Buf_kl = 0

'очистить оработанное нажатие

 

 

Goto Mc

 

End If Idle

Goto Mc '----------------------------------------------------------------------------------

'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА

'---------------------

'обработать данные времени по истечении секунды

New_data:

Incr Rsec

59 Then

'плюс секунда

If Rsec >

'при необходимости

Rsec =

0

: Goto Ndata1

'скорректировать счетчик секунд

End If

 

 

 

Goto Ndata3

 

 

Ndata1:

 

 

'плюс минута

Incr Rmin

59 Then

If Rmin >

'при необходимости

Rmin =

0

: Goto Ndata2

'скорректировать счетчик минут

End If

 

 

 

Goto Ndata3

 

 

Ndata2:

 

 

'плюс час

Incr Rhour

 

 

If Rhour > 23 Then

'при необходимости

Rhour = 0

 

'скорректировать счетчик часов

End If

 

 

 

Ndata3:

 

 

'поставить признак обновления индикации

Ddat = 255

 

 

============================================================================= 14

===================================== Справочник по программированию «Bascom-AVR» ==

Return '----------------------------------------------------------------------------------

Здесь проведена оптимизация Подпрограммы Add_vtmpb и Add_sz появились в результате оптимизации исходно текста

'обновить индикатор по завершению одной из операций в соответствии с текущим состоянием

New_led:

 

 

 

 

 

 

 

'очистить строку

 

Bufr = ""

 

 

 

 

 

 

 

If Mdisp = 1 Then

 

 

 

 

 

'выбрать вариант обработки индикатора

 

 

Goto Nled2

 

 

 

 

 

 

'на формирования отображения ММСС

 

Elseif Mdisp = 2 Then

 

 

 

 

'на гашение

 

 

Goto Nled3

 

 

 

 

 

 

 

End If

 

 

 

 

 

 

 

 

 

'сформировать символьное изображение времени в виде ЧЧММ

 

Tmpb = Rhour : Gosub Add_vtmpb

 

'добавить значение часов

'

Tmpb = Rmin : Gosub Add_vtmpb

 

 

'добавить значение минут

---------

 

 

 

 

 

 

 

 

 

 

Nled1:

 

 

 

 

 

 

 

 

'получить код первого знакоместа

'

Gosub Asc_seg : Buf_dis(1) = Tmpb

 

Gosub Asc_seg2 : Buf_dis(2) = Tmpb

'получить код второго знакоместа

'

Gosub Asc_seg2 : Buf_dis(3) = Tmpb

'получить код третьего знакоместа

'

Gosub Asc_seg2 : Buf_dis(4) = Tmpb

'получить код четвертого знакоместа

 

Return

 

 

 

 

 

 

 

 

 

 

'---------

 

 

 

 

 

 

 

 

 

 

 

'сформировать символьное изображение времени в виде ММСС

Nled2:

 

 

 

 

 

 

 

 

'добавить значение минут

 

Tmpb = Rmin : Gosub Add_vtmpb

 

 

 

Tmpb = Rsec : Gosub Add_vtmpb

 

 

'добавить значение секунд

'

Goto Nled1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'погасить индикатор

 

 

 

 

 

 

 

Nled3:

 

 

 

 

 

 

 

 

'погасить все сегменты

 

Buf _ dis(1) = 255

 

 

 

 

 

 

Buf _ dis(2) = &HFF

 

 

 

 

 

 

 

 

Buf _ dis(3) = &B11111111

 

 

 

 

 

Buf _ dis(4) = 255

 

 

 

 

 

 

 

Return

 

 

 

 

 

 

 

 

 

 

'---------

 

 

 

 

 

 

 

 

 

 

 

'п/п результат оптимизации

 

 

 

 

 

Add_vtmpb:

 

 

 

 

 

 

 

'если значение выражается одной цифрой

 

If Tmpb < 10 Then

 

 

 

 

 

 

 

Gosub Add_sz

 

 

 

 

 

'добавить символ лидирующего нуля

 

End If

 

 

 

 

 

 

 

'добавить значение

 

Bufr = Bufr + Str(tmpb)

 

 

Return

 

 

 

 

 

 

 

 

 

 

'---------

 

 

 

 

 

 

 

 

 

 

 

Add_sz:

 

 

 

 

 

 

 

 

'добавить символ лидирующего нуля

 

Bufr = Bufr + "0"

 

 

 

 

 

Return

 

 

 

 

 

 

 

 

 

 

'----------------------------------------------------------------------------------

 

 

 

программы клавиатуры

 

 

 

'

 

 

 

 

 

 

'---------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

' ---------------------------------------

|

 

 

AVR-WATCH

 

 

 

|

'

 

 

 

 

 

' ---------------------------------

|

|

---

---

 

 

---

---

 

|

|

'

|

|

|

|

|

'

| | |

|

|

|

|

| |

'

|

|

---

---

|

|

---

---

|

|

|

'

| | |

|

|

|

|

| |

'

|

|

--- []

--- []

 

--- []

--- [] |

|

' ---------------------------------

|

 

1

2

 

 

3

4

 

 

|

'

|

 

 

 

 

 

|

'

|

 

_

_

 

 

_

_

 

 

|

'

|

 

|_|

|_|

 

 

|_|

|_|

 

 

|

'

|

Reset

+

 

 

+

Shift

 

|

'

|

 

 

 

|

'

|

 

Min

Hour

 

Min

 

 

 

|

' ---------------------------------------

 

 

 

 

 

 

 

 

 

 

 

'выполнение программ обработки кнопок - основной список

'0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й

'1: Сбросить минуты 2: Добавить час 3: Добавить минуту 4: Второе назначение

'

|

_

_

_

_

|

'

|

|_|

|_|

|_|

|_|

|

============================================================================= 15

===================================== Справочник по программированию «Bascom-AVR» ==

'

|

ЧЧММ

ММСС

ON/OFF

ON/OFF

|

'

|

|

'

|

Формат

врем.

Sound

Disp

|

'---------------------------------------

'выполнение программ обработки кнопок - дополнительный список

'0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й

'1: Отображать ЧЧММ 2: Отображать ММСС 3: Вкл.Выкл. Звук 4: Вкл.Выкл. Индикацию

'---------------------------------------------------------

W_klb:

On Buf_kl Goto Kn , Km1 , Km2 , Km3 , Km4 '----------------------------------------------

W_skl:

On Buf_kl Goto Km1_1 , Ks1 , Ks2 , Ks3 , Ks4 '---------

Km1:

Rsec = 0 : Rmin = 0

'сбросить секунды и минуты

If Rmin > 30 Then

'при необходимости округления

Goto Km2

'скорректировать счетчик минут

End If

 

Km1_1:

'поставить признак обновления индикации

Ddat = 255

Kn:

 

Return

 

'---------

 

Km2:

'плюс час

Incr Rhour

If Rhour > 23 Then

'при необходимости

Rhour = 0

'скорректировать счетчик часов

End If

 

Goto Km1_1

 

'---------

 

Km3:

'плюс минута

Incr Rmin

If Rmin > 59 Then

'при необходимости

Rmin = 0

'скорректировать счетчик минут

End If

 

Goto Km1_1

 

'---------

' переключить режим второго назначения кнопок

Km4:

'выдать приглашение " SH "

Index = 2 : Gosub Dis_tr

Gosub Waitklc

'ожидание нажатий 2.5 с

If Buf_kl <> 0 Then

'есть нажания кнопки?

Goto W_skl

'да - переходим к обработке списка

End If

'на обновление индикации

Goto Km1_1

'---------

 

Ks1:

'установить режим отображения ЧЧММ

Mdisp = 0

Goto Km1_1

'на обновление индикации

'---------

 

Ks2:

'установить режим отображения ММСС

Mdisp = 1

Goto Km1_1

'на обновление индикации

'---------

Совет

Необходимо выбирать такие способы обработки управляющих переменных, чтобы ложные значения

 

не могли создаваться, а при появлении исключались автоматически. Пример тому обработка пере-

 

менной Msnd. Избыточности кода при этом не происходит.

Ks3:

'изменить режим звука на противоположенный

If Msnd <> 0 Then

Msnd = 0

 

Else

 

Msnd = 255

 

End If

'на обновление индикации

Goto Km1_1

'---------

 

Ks4:

'изменить режим гашения на противоположенный

If Mdisp <> 2 Then

Mdisp = 2

'установить режим гашения

Else

'снять режим гашения

Mdisp = 0

End If

'на обновление индикации

Goto Km1_1

'----------------------------------------------------------------------------------

 

'обработка прерывания таймера 0

 

============================================================================= 16

===================================== Справочник по программированию «Bascom-AVR» ==

'используется как часы реального времени с частотой 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

'опрос клавиатуры

'---------------------

 

'обработка счетчика времени

'считать счетчик

Lds R31 , {s_tim}

Dec R31

'уменьшить

Sts {s_tim} , R31

'сохранить

Andi R31 , &h0f

'маска

Brne Intt2_4

'каждое 16 прерывание (64 мс) обрабатываем еще два счетчика

'---------------------

 

'обработка счетчика переменных временных интервалов

Lds R31 , {w_tim}

'считать счетчик

Dec R31

'может уменьшаться только от 127 до нуля.

Brmi Intt2_1

 

Sts {w_tim} , R31

 

'---------------------

 

'обработка счетчика времени звонка

 

Intt2_1:

'проверим, а звонок разрешен?

Lds R31 , {Msnd}

And R31 , R31

'если не равен 0 - переход на отключение

Brne Intt2_2

'разрешен

'считаем счетчик времени звонка

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

'-----

 

Intt2_4:

'восстановим регистры

Pop R30

Pop R31

 

Out Sreg , R31

 

Pop R31

 

$end Asm

 

Return

 

'----------------------------------------------

'обработка прерывания таймера 2. Происходит 1 раз в секунду

Timer2_int:

 

$asm

push R31

'сохраним регистры

'

In R31 , Sreg

 

'

Push R31

 

'-----

ldi R31 , 255

 

'

Sts {ndat} , R31

 

Pop R31

'восстановим регистры

'

'

Out Sreg , R31

 

 

Pop R31

 

 

Reti

 

$end Asm Return

'----------------------------------------------------------------------------------

'ВВОД ДАННЫХ С КЛАВИАТУРЫ

'клавиатура опрашивается при выводе очередного знакоместа на индикатор

'код кнопки совпадает с номером знакоместа. Осуществляется подавление дребезга

'срабатывание фиксируется при удержании более 6 циклов опроса

In_kl:

 

 

$asm

,{Buf_kl}

'пока буфер клавиатуры не опустеет

Lds R31

And R31

, R31

 

============================================================================= 17

===================================== Справочник по программированию «Bascom-AVR» ==

Breq Inkl

 

'сканирование не проводится

Ret

 

 

 

 

'---------

 

 

 

' НАЧИНАЕМ

 

 

Inkl:

R31

,

{r_ckl}

'подготовим счетчика нажатий к обработке

Lds

Sbic Pinc

, 4

'считать состояние линии опроса кнопки

Rjmp N_st

 

'нет нажатия - переход

'---------

 

ЕСТЬ

 

' НАЖАТИЯ

 

Y_st:

R31

,

6

'если равен 6 - нажатие уже было зафиксировано

Cpi

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:

R31

,

R31

'проверим счетчик "удержания"

And

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

R31

,

{Cnt_dis}

'считать значение счетчика сканирования

Lds

Inc

R31

 

 

 

Andi R31 , 3

'и сохранить

Sts

{Cnt_dis} , R31

'---------

,

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:

R30

,

{buf_dis+1}

 

Lds

' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА

Ldi

R31

,

N_sc2

Rjmp Led_e

 

 

'---------

 

 

 

Led_2:

R30

,

{buf_dis+2}

 

Lds

' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА

Ldi

R31

,

N_sc3

Rjmp Led_e

 

 

'---------

 

 

 

Led_3:

R30

,

{buf_dis+3}

 

Lds

' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА

Ldi

R31

,

N_sc4

============================================================================= 18

===================================== Справочник по программированию «Bascom-AVR» ==

Led_e:

Portd , R30

 

Out

 

In R30 , Portc

' МАСКА СКАНИРОВАНИЯ

Ori

R30 , N_scn

And

R30 , R31

 

Out

Portc , R30

 

Ret

 

 

$end Asm

 

 

'----------------------------------------------------------------------------------

 

УТИЛИТЫ

'

 

'----------------------------------------------------------------------------------

 

 

'ВЫВОД СООБЩЕНИЯ СООБЩЕНИЯ, НОМЕР КОТОРОГО УКАЗАН Index

Dis_tr:

Value = 1 To 4

'определим число считываемых символов

For

 

Tmpb = Index * 4

'вычислить индекс, указывающих на начало сообщения

 

Tmpb = Tmpb + Value

'вычислить индекс, указывающих на текущий символ

 

Decr Tmpb

'коррекция индекса

 

Tmpb = Lookup(tmpb , Tr_led)

'считать из таблицы код символа

 

Gosub Pos_seg

'преобразовать в код сегментов

 

Buf_dis(index) = Tmpb

'записать в буфер индикации

Next Index

 

Return

 

 

'----------------------------------------------------------------------------------

 

 

'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII (ВТОРОГО СИМВОЛА)

Asc_seg2:

'сдвинуть строку влево на одну позицию

Bufr = Mid(bufr , 2)

'---------

'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII

Asc_seg:

 

 

 

 

'считать первый символ строки

 

Tmpb = Asc(bufr)

 

 

 

'

Tmpb = Tmpb - &H30

 

 

 

'преобразовать ASCII в число

---------

 

 

 

 

7-СЕГМЕНТНЫЙ КОД

 

'П/П ПРЕОБРАЗОВАНИЯ ПОЗИЦИОННОГО КОДА В

 

Pos_seg:

 

 

 

 

'считать из таблицы, используя число как смещение

 

Tmpb = Lookup(tmpb , Tabseg0)

 

'при необходимости подключить следующую

строчку

 

 

'

Gosub Tr_seg

 

 

 

'исправить монтаж сегментов индикатора

Return

 

 

 

 

 

 

 

 

'---------

 

 

 

 

 

ДЛЯ КОРРЕКЦИИ "НЕПРАВИЛЬНОГО" МОНТАЖА

'П/П ПЕРЕСЫПКИ БИТОВ 7-СЕГМЕНТНОГО КОДА

Tr_seg:

 

 

 

 

: Value.2 = Tmpb.5

'например "отзеркалить"

 

Value.0 = Tmpb.7 : Value.1 = Tmpb.6

 

Value.3 = Tmpb.4 : Value.4 = Tmpb.3

: Value.5 = Tmpb.2 : Value.6 = Tmpb.1 : Value.7 = Tmpb.0

'

Tmpb = Value : Return

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'ТАБЛИЦА РАСПОЛОЖЕНИЯ СЕГМЕНТОВ ИНДИКАТОРА - ПРОТОТИПА

 

'---------

 

D7

D6

D5

D4

D3

D2

D1

D0

'

 

'

 

¦-----------------------------------------------h1

g1

f1

e1

d1

c1

b1

a1

'BUF_DIS(4)

'BUF_DIS(3)

¦ h2

g2

f2

e2

d2

c2

b2

a2

'BUF_DIS(2)

¦ h3

g3

f3

e3

d3

c3

b3

a3

'BUF_DIS(1)

¦ 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

-g2-

I

-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-

 

-d2-

[h2]

-d1-

 

¦

 

' ¦

 

 

[h3]

 

[h1]¦

 

' ¦

 

 

 

 

 

 

 

 

¦

 

'

===============================================

 

'-----------------------------------------------------------

 

 

 

 

, СВЕЧЕНИЕ "0"

 

 

 

' ТАБЛИЦА КОДОВ СЕГМЕНТОВ

 

 

 

'-----------------------------------------------------------

 

 

'ШЕСТНАДЦАТИРИЧНЫЕ ЦИФРЫ ОТ

0(00h) ДО 15(0Fh)

Tabseg0:

 

 

 

 

 

 

' 0 ,

1

-d0 -

 

 

Data &HC0 , &HF9

 

 

 

I

 

Data &HA4 , &HB0

 

 

 

' 2 ,

3

I

 

Data &H99 , &H92

 

 

 

' 4 ,

5

D5

D1

 

Data &H82 , &HF8

 

 

 

' 6 ,

7

I

I

 

Data &H80 , &H90

 

 

 

' 8 ,

9

-d6 -

 

============================================================================= 19

===================================== Справочник по программированию «Bascom-AVR» ==

 

Data

&H88

, &H83

' A

, B I

I

 

Data

&HC6

, &HA1

' C

, D D4

D2

 

Data

&H86

, &H8E

' E

, F I

I

'

 

 

 

'

 

-D3-

[D7]

 

 

'ДРУГИЕ СИМВОЛЫ (УСЛОВНАЯ

НУМЕРАЦИЯ)

 

 

Data

&HAF

 

 

 

' R

*(16)

 

 

Data

&HE3

 

' U

*(17)

 

 

Data

&HC7

 

' L(18)

 

 

 

Data

&HFF

 

' ПРОБЕЛ(19)

 

 

Data

&H0B

 

' H

*(20)

 

 

Data

&HB7

 

' =(21)

 

 

 

Data

&HF7

 

' _(22)

 

 

 

Data

&HC3

 

' ЛЕВАЯ ЧАСТЬ БУКВЫ "W"(23)

 

Data

&HE1

 

' ПРАВАЯ ЧАСТЬ БУКВЫ "W"(24)

 

Data

&H0C

 

' P(25)

 

 

 

Data

&HFB

 

' I

*(26)

 

 

Data

&H07

 

' T

*(27)

 

 

Data

&HAB

 

' П

*(28)

 

 

Data

&HA3

 

' O

*(29)

 

 

Data

&HE7

 

' L

*(30)

 

 

Data

&H09

 

' H(31)

 

 

 

Data

&H9C

 

' ГРАДУС(32)

 

 

Data

&HAF

 

' ФРОНТ -(33)

 

 

Data

&HBB

 

' СПАД ¬(34)

 

 

Data

&HBF

 

' МИНУС -(35)

 

'ПРИМЕЧАНИЕ. * - МАЛЫЕ СИМВОЛЫ

 

 

 

 

'-----------------------------------------------------------

 

 

 

 

символов таблицы Tabseg0

'сообщения индикатора, записанные в номерах

Tr_led:

17 ,

22 , 1 , 2

' "v_12" (0)

 

 

Data

 

 

Data

19 ,

5 , 31 , 19

' "

SH " (1)

 

 

Data

14 ,

16 , 12 , 5

' "ErCS" (2)

 

 

Data

19 ,

0 , 15 , 15

' "

OFF" (3)

 

 

Data

19 ,

0 , 18 , 19

' "

OL " (4)

 

 

Data

19 ,

18 , 0 , 19

' "

LO

" (5)

 

'

Data

19 ,

23 , 24 , 19

' "

W

" (6)

 

 

 

 

 

 

 

 

'ожидание нажатий 2.5 с

 

 

 

 

Waitklc:

 

 

'задать время ожидания 2500=64 мс * 40

 

W_tim = 40

 

 

Buf_kl = 0

 

'очистим регистр клавиатуры от кода предыдущего нажати

'цикл ожидания нажатий

 

 

 

 

Do

If Buf_kl

<> 0 Then

'есть нажания кнопки?

 

Goto Wtklend

'да

- на выход

 

 

End If

 

 

 

 

 

 

Idle

 

 

'или истечения разрешенного времени 2.5 с

Loop Until W_tim = 0

Wtklend:

 

 

 

 

 

 

'следующая строка добавляется при необходимости

 

 

'

Gosub Tr_klb

'скорректировать номер кнопокReturn

'---------

 

 

 

 

 

 

 

'П/П ПЕРЕСЫПКИ НОМЕРОВ КНОПОК - ПЕРЕХОД ОТ ФИЗИЧЕСКИХ НОМЕРОВ К ЛОГИЧЕСКИМ

Tr_klb:

 

 

 

 

 

 

 

Buf_kl = Lookup(Buf_kl , tklb) : Return

 

 

 

Tklb:

0 , 4 , 3 , 2 , 1

 

'таблица перекодировки, например, наоборот

'

Data

 

 

 

 

 

 

 

 

============================================================================= 20