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