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

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

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

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

Добавлен: 17.06.2025

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

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

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

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