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

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 17.06.2025

Просмотров: 748

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

===================================== Справочник по программированию «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