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

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

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

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

Search_pin:

'повторять пока регистр Tmpb не станет равным нулю

While Tmpb <> 0

Shift Tmpb , Right : Incr Num_port

 

Wend

 

Return

 

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

 

Обработчик прерывания, написанный без применения ассемблера, не может иметь оптимального кода. Это показывает дисассемблированный текст (пример 6). Мы видим, что обработчик с одной стороны не выполняет недопустимых действий, а с другой – имеет явную избыточность и расточителен.

Пример 6 - Ассемблерный текст обработчика прерывания (листинг) из программы примера 5, получаемый при компиляции Bascom-AVR

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

 

 

Pc_int0:

 

 

;сохранение регистрового блока

 

push

r0

 

push

r1

 

push

r2

 

push

r3

 

push

r4

 

push

r5

 

push

r7

 

push

r10

 

push

r11

 

push

r16

 

push

r17

 

push

r18

 

push

r19

 

push

r20

 

push

r21

 

push

r22

 

push

r23

 

push

r24

 

push

r25

 

push

r26

 

push

r27

 

push

r28

 

push

r29

 

push

r30

 

push

r31

 

in

r24,$3F

 

push

r24

 

;Tmpb = Pina Xor Pcamsk

 

in

r16,$0

 

ldi

r20,#255

 

eor

r16,r20

 

ldi

r26,#5

 

ldi

r27,#1

 

st

x,r16

 

;Tmpb = Pina Xor Dub_pa

 

in

r16,$0

 

lds

r20,$101

 

eor

r16,r20

 

ldi

r26,#5

 

ldi

r27,#1

 

st

x,r16

 

;Num_port = 0

r24,#0

 

ldi

 

sts

$100,r24

'добавить в Num_port номер позиции единицы

;Gosub Search_pin

call

0000036A

 

;восстановление регистрового блока

 

pop

r24

 

out

$3F,r24

 

pop

r31

 

pop

r30

 

pop

r29

 

pop

r28

 

pop

r27

 

pop

r26

 

pop

r25

 

pop

r24

 

pop

r23

 

pop

r22

 

pop

r21

 

============================================================================= 31

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

pop

r20

 

pop

r19

 

pop

r18

 

pop

r17

 

pop

r16

 

pop

r11

 

pop

r10

 

pop

r7

 

pop

r5

 

pop

r4

 

pop

r3

 

pop

r2

 

pop

r1

 

pop

r0

 

;Return

 

 

Reti

 

 

;------

 

 

;подпрограмма Search_pin:

 

0000036A:

 

'повторять пока регистр Tmpb не станет равным нулю

While Tmpb <> 0

r16,$105

lds

 

cpi

r16,#0

 

brne

00000376

 

jmp

0000038E

 

00000376:

 

 

;Shift Tmpb , Right

 

ldi

r25,#1

 

ldi

r26,#5

 

ldi

r27,#1

;вызов библиотечной программы

call

000003C6

;Incr Num_port

r26,#0

 

ldi

 

ldi

r27,#1

 

ld

r24,x

 

subi

r24,#255

 

st

x,r24

 

;Wend

0000036A

 

jmp

 

0000038E:

 

 

ret

 

 

;------

 

 

;библиотечная подпрограмма сдвига вправо на число в R25

000003C6:

r25,#0

 

cpi

 

breq

000003D4

 

ld

r24,x

 

000003CC:

r24

 

lsr

 

dec

r25

 

brne

000003CC

 

st

x,r24

 

000003D4:

 

 

ret

 

 

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

 

 

============================================================================= 32

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

Вопросы и ответы (1-10)

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

Вопрос 1

Но вот не могу понять только одного, почему в такой короткой программе, как эта:

Dim A As Byte

For A=1 to 30

Print A

Next A

End

…при компиляции размер кода составляет более 300 байт?? Абсурд! Баском конечно кушает память, но чтобы так!.. Может я в чём не прав?

Ответ 1

1 Насчет размера вашего примера. Такой же будет для любого компилятора. В этот размер входит:

-заголовок программы, включаемый в код автоматически (по умолчанию) и содержащий место под все вектора прерывания по 4 байт на вектор, очистку памяти 20-30 байт и инициализацию оборудования 30 - 100 байт;

-библиотека используемой функции и плюс 2-3 стандартных - около 100 байт;

-и собственно код вашей программы. Т.е. все сходится. Зато еще один вызов данной функции приводит к добавлению всего 20 - 30 байт.

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

Вопрос 2

Да и вообще, здесь много подводных камней, про которые даже в pdf-файле не найдешь…Я изучал когда-то давно Бейсик, сейчас плохо помню, приходиться заново учить. К какому Бейсику ближе Баском?

Ответ 2

Синтаксис и мнемоника, в принципе, отвечают стандарту Basic для DOS с учетом особенностей, ограничений и дополнительных возможностей. Лучше на стандартный Basic не ориентироваться. Слишком много ограничений, обусловленных различными возможностями процессоров. Главное отличие в том, что нужно определить тип переменных заранее, не допускать скрытого преобразования типов и не применять больше одного действия в одном операторе.) Лучше ориентироваться на оригинальное описание Bascom-AVR – оно отличное. На русском имеется только описание Bascom-8051. И еще на примеры - их очень много.

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

Вопрос 3

Я сначала ничего не подозревал. Пытался спокойно делать себе программки в Баскоме, как вдруг понял, что реализация протокола I2C(TWI) в любом микроконтроллере происходит программно, независимо от того, есть ли в нём аппаратная поддержка данного протокола или нет. Я бы ничего этого не заметил, если бы не наткнулся на проблему нехватки памяти микроконтроллера. В конечном итоге выяснилось, что реализация аппаратного протокола возможна только в лицензионной версии Баскома, так как в демо-версии нет соответствующей библиотеки.

Ответ 3

По моему наблюдению, использование аппаратного контроллера с точки зрения размера кода совершенно неэффективно. При программной реализации размер кода получается равноценным. Потому, что работа с аппаратным портом конечно проще, но при этом требуется организовать обработку соответствующего прерывания. Преимущество аппаратного I2C только в возможности осуществлять "прозрачную" работу одновременно с другими процессами и при наличии очень медленных устройств. Когда, например, в фоновом режиме нужно постоянно считывать или дописывать данные. При этом в коде "весит" именно программа организации МАССИВА записываемых или считываемых данных, а не сам драйвер. Вот пример работающей программы на BAS и на ASM. В основной программе применяются готовые функции. В прерывании используется ассемблерная программа (а ее размер минимален). Если устройство более медленное - нужно вместо NOP-ов добавить в программу подпрограммы более продолжительной задержки. Не забывать, что когда работаешь с I2C, нужно бы запретить прерывания. Если длительность импульса SCL превысит 10 мкс устройство может само отключится! В последующем примере переключение уровней делается изменение направления порта. Это важно. Так можно манипулировать с им намного быстрее.

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

============================================================================= 33

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

' Программы обслуживания АЦП типа ADS1110 (Burr-Broun) '--------------------------------------------------------------

' результаты ' 1 смещение входа имеется и весьма заметно 1-2 мВ. Зависит от включенного коэффициента усиления

' 2 При усилении К=1 шум меньше 1 дискрета, что делает усреднение бесполезным ' 3 При максимальном усилении К=8 шум составляет около 20-30 мкВ пик-пик

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

 

 

'линия данных

Config Sda = Portc.1

Config Scl = Portc.0

'линия синхронизации

Config I2cdelay = 1

'наивысшая скорость

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

 

 

 

'АВТООПРЕДЕЛЕНИЕ АДРЕСА АЦП

 

Find_adr:

 

'АДРЕС НУЛЕВОЙ ПРОШИВКИ(90h -2)

 

Adradc = 142

 

Disable Interrupts

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

Findadr1:

 

'АДРЕС ДЛЯ ЧТЕНИЯ + 2

 

Adradc = Adradc + 2

 

If Adradc <> 160 Then

'ПРОВЕРИМ НА МАКСИМУМ(90h + 16)

 

Goto Findadr2

 

End If

 

'АДРЕС НУЛЕВОЙ ПРОШИВКИ (90h)

 

Adradc = 144

 

 

Goto En_intr

 

'НА ВЫХОД ЕСЛИ ВСЕ АДРЕСА ПРОЙДЕНЫ

Findadr2:

 

 

$asm

Lds R31 , {Adradc}

'АДРЕС ДЛЯ ЧТЕНИЯ

 

Inc R31

 

'СТАРТ, ДАННЫЕ И ЖДЕМ ПОДТВЕРЖДЕНИЯ

'

Rcall Start_bit

Rcall R_byte

 

'ПРИМЕМ СТАРШИЙ БАЙТ

 

 

 

Rcall Mstr_ack

'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ

 

Rcall R_byte

 

'ПРИМЕМ МЛАДШИЙ БАЙТ

 

Rcall Mstr_ack

'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ

 

Rcall R_byte

 

'ПРИМЕМ СТАТУС

 

Rcall No_ack

 

'ДА - БЕЗ ПОДТВЕРЖДЕНИЯ И СФОРМИРУЕМ СТОП-БИТ

 

Andi R31 , &B01100000

'АНАЛИЗИРУЕМ D5 И D6. ВСЕГДА Д.Б. = 0

 

Brne Findadr1

 

'ЕСЛИ НЕ НУЛЬ - ПОВТОРИТЬ

$end Asm

 

'НА ВЫХОД ЕСЛИ АДРЕС НАЙДЕН

'

Goto En_intr

 

 

 

 

'п/п записи статуса АЦП ADS1110 (нормальный медленный режим) 15 изм/с. Шкала 1.024 В

Slow_adc:

 

Запуск преобразования: 1 только в одиночном

'

|------------

 

'

|---------

Запуск: 0 - автоматический, 1 - одиночное

'

|

Скорость: 00 - 240 SPS, 01 - 60 SPS

'

|

| -------

'

|

| |

10 - 30 SPS, 11 - 15 SPS

'

|

| |

 

'

|

| | ----- Усиление: 00 - 1 , 01 - 2

'

| | | |

10 - 4 , 11 - 8

'

|

| | |

 

'

|

|||||

 

 

Value = &B00001101

 

Wr_adc:

 

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

Disable Interrupts

 

I2cstart

 

'старт

 

I2cwbyte Adradc

'байт адреса

 

I2cwbyte Value

'байт режима

 

I2cstop

 

'стоп

$asm

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

 

Cbi Ddrc , 0

 

'установим на Scl плавающую "1"

 

Cbi Portc , 0

 

'подготовим "0" для вывода

 

Cbi Ddrc , 1

 

'установим на Sda плавающую "1"

 

Cbi Portc , 1

 

'подготовим "0" для вывода

$end Asm

 

 

En_intr:

 

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

Enable Interrupts

 

Return

 

 

'

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

 

 

'п/п записи статуса АЦП ADS1110 (быстрый режим) 240 изм/с. Шкала 1.024 В

Speed_adc:

 

Запуск преобразования: 1 только в одиночном

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

|

 

' ---------

|

Запуск: 0 - автоматический, 1 - одиночное

'

|

Скорость: 00 - 240 SPS, 01 - 60 SPS

' -------

|

|

'

|

| |

10 - 30 SPS, 11 - 15 SPS

'

|

| |

----- Усиление: 00 - 1 , 01 - 2

'

|

| |

'

| | | |

10 - 4 , 11 - 8

============================================================================= 34

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

'

|

| | |

 

 

 

 

 

 

 

'

|

|||||

 

 

 

 

 

 

 

 

Value = &B00000001

 

 

 

 

 

 

 

'

Goto Wr_adc

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'п/п записи статуса АЦП ADS1110 (нормальный режим) 15 изм/с. Шкала 2.048 В

Wide_adc:

 

Запуск преобразования: 1 только в одиночном

'

|------------

 

'

|---------

Запуск: 0 -

автоматический, 1 - одиночное

 

'

|

Скорость: 00 - 240 SPS, 01 - 60 SPS

 

 

'

|

| -------

 

 

'

|

| |

10 - 30 SPS,

11 - 15 SPS

 

 

'

|

| |

----- Усиление: 00 - 1 , 01 - 2

 

 

 

'

|

| |

 

 

 

'

| | | |

10 - 4 , 11 - 8

 

 

 

'

|

| | |

 

 

 

 

 

 

 

'

|

|||||

 

 

 

 

 

 

 

 

Value = &B00001100

 

 

 

 

 

 

 

'

Goto Wr_adc

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'ЧТЕНИЕ ДАННЫХ ИЗ АЦП В R27(ст), R26(мл), статус в R31

 

 

 

Rd_adc:

 

 

 

 

 

 

 

 

$asm

Cbi Ddrc , 0

 

 

'установим на Scl плавающую "1"

'

 

 

'

Cbi Portc , 0

 

'подготовим "0" для вывода

 

'

Cbi Ddrc , 1

 

 

'установим на Sda плавающую "1"

'

Cbi Portc , 1

 

'подготовим "0" для вывода

 

 

Lds R31 , {Adradc}

 

'АДРЕС ДЛЯ ЧТЕНИЯ

 

 

 

Inc R31

 

 

'СТАРТ, ДАННЫЕ И ЖДЕМ ПОДТВЕРЖДЕНИЯ

'

Rcall Start_bit

 

Rcall R_byte

 

 

'ПРИМЕМ СТАРШИЙ БАЙТ

 

 

 

 

 

 

 

 

Mov R29 , R31

 

 

'ЗАПИШЕМ ДАННЫЕ В ОЗУ

 

 

 

Rcall Mstr_ack

 

'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ

 

 

Rcall R_byte

 

 

'ПРИМЕМ МЛАДШИЙ БАЙТ

 

 

 

Mov R28 , R31

 

 

'ЗАПИШЕМ ДАННЫЕ В ОЗУ

 

 

 

Rcall Mstr_ack

 

'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ

 

 

Rcall R_byte

 

 

'ПРИМЕМ СТАТУС

 

 

 

'

Rjmp No_ack

 

 

'ДА - БЕЗ ПОДТВЕРЖДЕНИЯ И СФОРМИРУЕМ СТОП-БИТ

 

 

 

 

 

 

 

 

 

'порты PC.0, PC1 инициализированы на ввод (исходно DDRC.0 = 0, DDRC.1 = 0),

'а в порты PORTC.0 PORTC.1 записывается

"0". Таким образом на линиях устанавливается "1".

'воспроизведение "0" производися переключением направления

 

 

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

 

 

 

 

 

 

 

 

 

' Portc.0 - Scl, Portc.1 - Sda

 

 

 

 

 

 

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

 

 

 

 

 

 

 

 

 

'ФОРМИРОВАНИЕ СТАРТ-БИТА И ЕЩЕ ДВЕ ОПЕРАЦИИ

 

 

 

 

 

Start_bit:

 

 

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l

 

Cbi Ddrc , 0

 

 

 

Nop

 

 

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

¦

 

¦

 

 

 

Nop

 

 

'

 

 

 

 

Cbi Ddrc , 1

 

 

'---

 

 

-

 

 

 

Nop

 

 

'Scl

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

 

 

 

 

 

Nop

 

 

'

 

 

 

 

 

 

Sbi Ddrc , 1

 

 

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

¦

 

¦

 

 

 

Nop

 

 

'

 

 

 

 

Nop

 

 

'-------

 

 

------

 

 

'

Sbi Ddrc , 0

 

 

'Sda

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

 

 

 

 

 

 

 

 

 

 

 

 

 

'ВЫДАЧА НА ЛИНИЮ БАЙТА ДАННЫХ ЗАПИСАННЫХ В R31

 

 

 

 

T_byte:

 

 

'ЧИСЛО БИТ

 

 

 

 

 

Ldi R30 , 8

 

 

 

 

 

 

T_by0:

 

 

'ЦИКЛ ПЕРЕДАЧИ

 

 

 

 

Sbi Ddrc , 0

 

 

 

 

 

 

Rol R31

 

 

'СДВИГ

 

 

 

 

 

Brcc T_by1

 

 

'порт в "1"

 

 

 

 

 

Cbi Ddrc , 1

 

 

 

 

 

 

 

Rjmp T_by2

 

 

 

 

 

 

 

 

T_by1:

 

 

'порт в "0"

 

 

 

 

 

Sbi Ddrc , 1

 

 

 

 

 

 

T_by2:

 

 

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l

 

Cbi Ddrc , 0

 

 

 

 

 

'-

-----

- - --

¦

-----

 

Dec R30

 

 

' ¦

¦

¦

¦

¦

 

Brne T_by0

 

 

'------

 

 

----

----

 

 

 

 

 

'Scl

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

 

 

 

 

 

 

 

 

'

 

 

 

 

 

 

 

 

 

'----

|----------

 

|--- - -

---|-------

 

 

 

 

 

'

 

 

============================================================================= 35

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

 

 

'----

----------

 

---

- -

---

-------

'

 

'Sda--------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'СОСТОЯНИЕ ОЖИДАНИЯ БИТА ОТВЕТА (ПОДТВЕРЖДЕНИЕ)

 

 

 

 

 

Slave_ack:

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l

Sbi

Ddrc , 0

Nop

Ddrc , 1

'

 

----

¦

 

 

 

Cbi

 

¦

 

 

 

Nop

Ddrc , 0

' ------

 

 

---

 

 

 

Cbi

'Scl-------------

 

 

 

 

 

 

Nop

 

'

 

 

 

 

 

 

Nop

Ddrc , 0

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

¦ |

 

|

 

 

 

Sbi

'

 

 

 

 

Ret

 

'-----

 

------

 

 

 

'

 

'Sda-------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'БЕЗ ВЫДАЧИ СИГНАЛА ПОДТВЕРЖДЕНИЯ И ЕЩЕ ОДНА ОПЕРАЦИЯ

 

 

 

 

No_ack:

Ddrc , 1

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l

Cbi

Cbi

Ddrc , 0

'

¦------

¦

 

 

 

 

'

----

 

 

 

Nop

 

'----

 

 

 

 

 

Nop

Ddrc , 0

'Scl-------------

 

 

 

 

 

 

Sbi

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'-

 

 

 

 

 

 

'

 

'Sda-------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'ФОРМИРОВАНИЕ СТОП-БИТА

 

 

 

 

 

 

 

Stop_bit:

'

 

 

 

 

 

 

Sbi

Ddrc , 1

¦---------

 

 

 

 

 

 

 

'

 

 

 

 

 

Cbi

Ddrc , 0

'-----

 

 

 

 

 

 

'Scl------------

 

----

 

 

 

Nop

Ddrc , 1

'

 

 

 

 

Cbi

 

¦

 

 

 

 

Ret

 

' ---------

 

 

 

 

 

 

'

 

'Sda------------

 

 

 

 

 

 

С ЛИНИИ БАЙТА ДАННЫХ В R31

 

 

 

 

 

 

 

'ЧТЕНИЕ

 

 

 

 

 

 

 

R_byte:

Ddrc , 1

'НА ВСЯКИЙ СЛУЧАЙ

 

 

 

Cbi

 

 

 

Ldi

R30 , 8

'ЧИСЛО СЧИТЫВАЕМЫХ БИТ

 

 

R_by0:

Ddrc , 0

'ЦИКЛ СЧИТЫВАНИЯ

 

 

 

Cbi

 

 

 

Sec

 

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ SCL

Nop

 

'-------

 

¦

--- --

¦

----

Sbis Pinc , 1

' ¦

 

¦

¦

¦

'--

 

----

 

----

 

-----

Clc

Ddrc , 0

'SCL--------------------------------

 

 

 

 

 

 

Sbi

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

| R

 

| R

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

 

| R

Rol

R31

 

 

 

Dec

R30

| D

 

| D

 

 

| D

Brne R_by0

'

---------

 

-

- -------

 

--------

Ret

 

'SDA--------------------------------

 

 

 

 

 

 

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

СИГНАЛА ПОДТВЕРЖДЕНИЯ

 

 

 

 

 

 

 

'ВЫДАЧА

 

 

 

 

 

 

 

Mstr_ack:

 

 

 

 

 

 

 

Sbi

Ddrc , 0

'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ SCL

Nop

Ddrc , 1

Sbi

'

 

¦------

¦

 

 

 

Nop

Ddrc , 0

 

-----

 

 

Cbi

' --------

 

 

 

 

 

Nop

Ddrc , 0

'SCL-------------------

 

 

 

--

 

 

Sbi

'----

¦

 

 

 

 

Nop

Ddrc , 1

'

 

 

¦

 

 

Cbi

'

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

 

 

 

 

 

Ret

 

'SDA-------------------

 

 

 

 

 

 

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

 

 

 

 

 

 

 

 

$end Asm

 

 

 

 

 

 

 

 

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

Вопрос 4

Я читал, что Bascom дает громоздкий и неоптимальный код. Это правда? Тогда какие выгоды дает применение этого компилятора?

============================================================================= 36

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

Ответ 4

Не нужно паниковать о том, что Bascom дает некомпактный код. Размер кода полностью соответствует классу компиляторов с языков высокого уровня. Уступает только CodeVision на малых проектах, а с другими компиляторами Си успешно конкурирует. Bascom особенно хорош в больших проектах, когда мелочная оптимизация уже не приносит заметного выигрыша, а важнее структурированность исходного текста.

Размер кода в громадной степени зависит от стиля написания. Нужно применять тоже приемы, что и при программировании на ассемблере:

- похожие программы оформлять в подпрограммы. Различия формировать ветвлением и дроблением участ-

ков;

-применять простые конструкции, минимум вложенности (от вложенности код становится еще больше). Лучше больше ветвится по тексту программы, чем применять вложенные проверки условий. Чем длиннее текст и применяются более мелкие операторы, тем короче код и он быстрее работает;

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

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

-применять конструкцию On … Goto с таблицей переходов даже избыточной, а не любимую многими

Select Case;

-применять табличные методы установки и выбора параметров Lookup(offset,Table);

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

-также как и задание числовых данных нужно делать один раз.

Не рекомендуется применять экзотические методы передачи параметров (через стек). Просто советы:

-не вставлять Return внутрь закрытых конструкций (типа if.. do.. for..) , а применять переход Goto на выходную метку;

-не располагать переменные (Single, массивы и строковые) на границе страниц памяти. Поступать так - скомпилить и посмотреть. При необходимости определить распределение памяти для Single и String самостоятельно вручную. Например:

Dim Kzr0 As Single At 1024 Dim Kzr1 As Single At 1028

или набить промежутки на границе страниц пустыми неиспользуемыми переменными;

-не забывать один оператор - одно действие (это не Си).

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

Вопрос 5

При преобразовании демоверсии 1.11.8.1 в полную, добавление dll-файлов библиотека не расширяется. Как

быть?

Ответ 5

Неполность библиотек не имеет большого значения. Большинство из них просто не представлено в виде исходного текста, который можно править и добавлять. За 10 лет использования Bascom ни разу в исходном она мне понадобилась. На самом деле, отсутствуют только утилиты уникального оборудования, которое, все равно, приходится описывать "вручную", чтобы не потерять критичные свойства. Во-вторых, имеющиеся библиотеки часто не обеспечивают совместную (параллельную) работу с другим оборудованием (параллельными задачами). В-третьих, со сложной периферией МК приходится работать напрямую - просто пишешь и читаешь регистры, анализируешь биты. Так вернее и полезней - иначе нельзя использовать все возможности и не будешь отчетливо представлять ее работу. Если лень читать, можно применять утилиту CodeVizard компилятора CodeVision. Сделано очень точно.

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

Вопрос 6

Не могу понять, как правильно использовать эту настройку. 1. По поводу настройки ТАЙМЕРА1.В оригинальном описании написано:

CONFIG TIMER1 = COUNTER | TIMER | PWM , EDGE=RISING | FALLING , PRESCALE= 1|8|64|256|1024 , NOISE CANCEL=0 |1, CAPTURE EDGE = RISING | FALLING , CLEAR TIMER = 1|0,

COMPARE A = CLEAR | SET | TOGGLE I DISCONNECT ,

COMPARE B = CLEAR | SET | TOGGLE I DISCONNECT

============================================================================= 37

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

Ответ 6

Не пользуйтесь для настройки конфигурации ключевыми словами Баскома. Забыть их! Ведь кристаллы разные, расположение битов и регистров различное, очень велика вероятность, что вы или компилятор ошибется. Например, в Bascom-8051 кристаллы совместимы по периферии и все поэтому работает надежно. В Bascom-AVR такие настройки оставлены для совместимости. Читайте Datasheet на процессоры и записывайте необходимые настройки сами. Причем лучше пользоваться оригинальными документами. В переводных много ошибок. Их ценность только в возможности быстрее изучить интересующий вопрос.

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

Вопрос 7

Как записать значение в регистр совпадения OCR1A, причём так, чтобы это можно было сделать в любом месте программы? Как записать в значение в сам таймер-счётчик (регистр TCNT1)?

Ответ 7

'Да. Например, число 12345. Преобразуем в калькуляторе в HEX 12345=3039h OCR1AH=&H30 : OCR1AL=&H39 'при записи обязательно старший байт первым

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

TCNT1H=&h11:TCNT1H=&hFF 'по записи первым старший потом младший Byte1=TCNT1H:Byte2=TCNT1H 'при чтении первым младший потом старший

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

TCNT1H=High(word):TCNT1H=low(word) 'так записывается двухбайтное число

TEMPh=TCNT1H : TEMPl=TCNT1H : Word=Makeint(Temph,Templ) 'так читается в двухбайтовое число '-----------------------------

'и как это выглядит на ассемблере

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

'считать значение, полученное в счетчике таймера 1

Rd_tim1:

 

$asm

'СЧИТАТЬ ДАННЫЕ

In R30 , Tcnt1l

In R31 , Tcnt1h

'из таймера

Sts {r_bd} , R30

 

Sts {r_bd + 1} , R31

 

Lds R30 , {c_msb}

 

'---------

'проверим бит переполнения таймера 1

In R31 , Tifr

Sbrs R31 , 2

'этой операцией мы учтем еще не обработанное переполнение таймера

Rjmp Rdtim_1

'если бит переполнения таймера 1 установлен,

Inc R30

'добавим единицу в счетчик старших разрядов

'---------

 

Rdtim_1:

 

Sts {r_bd + 2} , R30

 

Clr R31

 

Sts {r_bd + 3} , R31

 

$end Asm

 

Return

 

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

 

'оформление прерывания на ассемблере

 

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

 

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

 

Timer1_int:

 

$asm

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

Push R31

In R31 , Sreg

 

Push R31

 

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

 

Lds R31 , {c_msb}

 

Inc R31

'добавить единицу в счетчик старших разрядов

Sts {c_msb} , R31

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

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

Pop R31

Out Sreg , R31

 

Pop R31

 

Reti

 

$end Asm

 

Return

 

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

 

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

Вопрос 8

============================================================================= 38

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

Как подключить таймер1 в режиме сравнения к выводу OC1A?(а так же OC1B)?

Ответ 8

'все назначения конфигурации записывать в основной программе так TCCR1A=&b01010000 'переключение выходов по совпадению OCR1A и OCR1B) TCCR1B=&b00001001 'считать с частотой Fкв, перезагрузка по OCR1A

'если конфигурация делается в теле прерывания оформлять так

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

'запретить прерывание таймера 1

 

Dis_timer1:

 

$asm

 

Ldi R31 , &b00000001

'сбросить бит разрешения прерывания таймера 1.

Out Timsk , R31

Ldi R31 , &b00000100

'после запрещения сбросить флаг прерывания таймера 1

Out Tifr , R31

$end Asm

 

Return

 

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

 

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

 

Dis_int0:

 

$asm

'сбросить бит разрешения внешнего прерывания.

Ldi R31 , &b00000000

Out Gimsk , R31

'по datasheet этот регистр называется Gicr

Ldi R31 , &b01000000

'после запрещения сбросить флаг прерывания.

Out Gifr , R31

$end Asm

 

Return

 

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

Вопрос 9

Могу ли я одновременно использовать COMPARE A и COMPARE В?

Ответ 9

'Да, но режим CTC (сброс по совпадению) возможен только от OCR1A 'или от OCR1B если не используется OCR1A

'вообще это "скользкое" место, плохо прописанное в оригинальной документации 'при этом коэффициент деления определяется OCR1A,

'а переключение выхода совпадением и с OCR1A и с OCR1B

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

Вопрос 10

Что означает Compare = Off(On) для компаратора? Я так понял, что это функция захвата таймера1, подключенного непосредственно к выходу компаратора.

'смотри регистр ACSR. Эта опция - фактически бит ACSR.2

'когда ACSR.2 = 1 по любому переключению компаратора значение TCNT1 запоминается в ICR1, 'как и по перепаду на входе CP1

Как можно в самой программе включить и выключить компаратор?

'это бит ACSR.7. По сбросу компаратор включен! ACSR=&B1xxxxxxxx 'выключить

ACSR=&B0xxxxxxxx 'включить, значение остальных битов смотри сам

============================================================================= 39