Файл: Справочник по программированию «Bascom-AVR» (М.Л. Кулиш).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 17.06.2025
Просмотров: 745
Скачиваний: 3
===================================== Справочник по программированию «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