КОНТР-&-БАСИК
     

AVR BASIC interpreter
BASINT

ОГЛАВЛЕНИЕ

1. ВВЕДЕНИЕ
2. КОНТРОЛЛЕРНАЯ ВЕРСИЯ ЯЗЫКА AVR BASINT, КОМАНДЫ И ФУНКЦИИ
2.1 КОНСОЛЬНЫЙ ВВОД/ВЫВОД
2.2 УПРАВЛЕНИЕ ПРОЦЕССОМ
2.3 ДАННЫЕ
2.4 ПРЕРЫВАНИЯ И МАШИННЫЙ КОД
2.5 НАЗНАЧЕНИЕ И ИСПОЛЬЗОВАНИЕ ЛИНИЙ КОНТРОЛЛЕРА
2.6 ДОСТУП К РЕСУРСАМ МИКРОКОНТРОЛЛЕРА
2.6.1 Доступ к 16-битным регистрам AVR-микроконтроллера
2.7 ВЫЧИСЛЕНИЯ
2.8 ТРАДИЦИОННЫЕ РАСШИРЕНИЯ (BASIC STAMP, BASCOM)
2.9 ДВУХПРОВОДНЫЙ ИНТЕРФЕЙС
2.10 ДИАГНОСТИКА
3. ИСПОЛЬЗОВАНИЕ ПРЕПРОЦЕССОРА

1. ВВЕДЕНИЕ

    BASINT – это интерпретатор языка Бейсик для AVR микроконтроллеров AT Mega 16/32/64. Как продукт, представляет собой машинный код и предназначен для помещения в программную память AVR микроконтроллера. В комплексе, микроконтроллер и код интерпретатора BASINT, образуют программируемый логический контроллер, языком программирования которого является язык Бейсик. Далее в тексте под словом контроллер подразумевается такое программируемое логическое устройство.
    Конструктивное исполнение в данном документе не рассматривается, подразумевается, что изделие может представлять собой законченный модуль, предназначенный для встраивания или целиком входить в состав целой схемы.
    Основной принцип использования контроллера состоит в том, что все операции по созданию и загрузке программы пользователя на языке Бейсик производятся без применения специального оборудования и программного обеспечения. Например, в программе NotePad пишется программа, а загрузка производится при помощи терминальной программы HyperTerminal (OS WINDOWS). Эти средства стандартно присутствуют в операционной системе.
    Во время загрузки программы текстовый файл преобразуется в промежуточный код, который является сокращённой формой текстового исходного файла, например, лишние пробелы в тексте удаляются, числа в символах ASCII преобразуются в двоичный эквивалент, строки снабжаются счётчиками, имена операторов и функций заменяются кодами, в таком виде программа хранится во флеш-памяти. Во время исполнения интерпретатор пользуется этой сокращённой формой записи

    Так выглядит начальная заставка на экране гипертерминала.

    Ниже показаны среды "обитания" BASINT для трёх типов AVR микроконтроллеров

Схема в формате PDF

1

Схема в формате PDF

Область применения контроллера - разработка устройств неспециалистами в области программирования, любительское и учебное использование.

 


2. КОНТРОЛЛЕРНАЯ ВЕРСИЯ ЯЗЫКА AVR BASINT, КОМАНДЫ И ФУНКЦИИ

Особенностью данного диалекта языка Basic является то, что строки не нумеруются. Для обозначения точек перехода используются числовые метки.
Числа:
Все числа являются знаковыми целыми в диапазоне -32767 до +32767.
Допускаются три формы записи чисел:
- десятичная;
- шестнадцатеричная, числа имеют префикс &H;
- двоичная, числа имеют префикс &B;
При выводе листинга из памяти контроллера действует только десятичная форма представления, вне зависимости от формы записи в загружаемом тексте программы.

Переменные:
В программе допускается использования до 26 переменных. В качестве имен переменных можно использовать совокупность заглавных букв латинского алфавита от A до Z, общая длина может быть любой, но из расчёта, что длина строки в программе не должна превышать 64 символа.  При присвоении переменным символических имен следует учитывать, что значащим является только первый символ. Таким образом, различные имена, но начинающиеся с одинаковой буквы будут указывать на одну и ту же переменную
Внутреннее представление переменных 16-битное.
Допускается использование до 26 одномерных массивов, размер которых изначально не определён. Актуальный размер задаётся на этапе исполнения. Максимальный размер зависит от наличия свободной памяти. К выбору имени массива следует подходить так же, как и к именам переменных.
Доступ к элементу массива осуществляется через индекс в круглых скобках, например A(0), B(1). Следует иметь в виду, что это A и A(n) – это разные переменные.

Операторы
Арифметические:
+ сложение
- вычитание
* умножение
/ целочисленное деление (нужно иметь в виду, что, например, 14/5=2)
MOD - взятие остатка от деления (14 MOD 5=4)
AND - побитное И
OR - побитное ИЛИ
XOR - побитное исключающее ИЛИ
Сравнения (используются только оператором IF):
= равно
<> (или ><) не равно
> больше
< меньше
>= (или =>) больше или равно
<= (или =<) меньше или равно
Выражения
Выражения составляются из чисел, переменных, арифметических и битовых операторов. Операторы сравнения не могут быть использованы в выражениях. Вычисления производятся слева направо. Применением скобок можно изменить порядок вычислений.
Существует 3 уровня.
- cначала вычисляются выражение с унарными операторами + и –,
например: A=-B*2, при этом первым будет выполнено взятие B с противоположным знаком;

- затем вычисляются выражения с * и /
- вычисляются выражения с + - и MOD,AND,OR,XOR;
Метки
Метками являются положительные числа т 0 до 32767.
Метка ставится в начале строки, на которую предполагается делать переход или адресовать вызов подпрограммы. Не рекомендуется нумеровать все строки, количество меток ограничено размером таблицы меток и составляет 64.

 

 

 KeyWord \ Model Small
Atmega16
Mini
Atmega32
Maxi
Atmega64

ABS

* * *

ADC

* * *
AT   * *
ATTR   * *
BCD   * *
BIN   * *
CHR * * *
CLEAR * * *
CLS   * *
DATA * * *
DEFPIN AS * * *
DELAY * * *
DELETEVECTOR   * *
DIM * * *
DISABLE   * *
ENABLE   * *
END * * *
FOR TO NEXT * * *
GETATOMIC   * *
GOTO * * *
GOSUB * * *
HEX   * *
HIGH * * *
IF THEN ELSE * * *
INK   * *
INKEY * * *
INLINE   * *
INPUT * * *
INTERRUPT   * *
LASTERROR * * *
LOW * * *
PAPER   * *
PEEK * * *
POKE * * *
PRINT * * *
PULSEIN * * *
PULSEOUT * * *
PUTATOMIC   * *
PWM * * *
READ * * *
READEEPROM * * *
REM * * *
RESTORE * * *
RETURN * * *
ROL * * *
ROR * * *
SCALE * * *
SETADMUX * * *
SET * * *
SHIFTIN * * *
SHIFTOUT * * *
STOP * * *
TEST * * *
TOGGLE * * *
TWIINIT * * *
TWIREAD * * *
TWISTOP * * *
TWIWRITE * * *
WAITKEY * * *
WRITEEEPROM * * *

 

Small

Mini

Maxi

Базовый чип

ATMEGA16

ATMEGA32

ATMEGA64

Размер доступной
программной памяти

3К байт

16К байт

Будет определён по результатам портирования

 

2.1 КОНСОЛЬНЫЙ ВВОД/ВЫВОД

CLS

Действие:
Очищает экран консоли и переводит курсор в верхний левый угол
Синтаксис:
CLS

PRINT

Действие:
Оператор вывода, выводит на консоль сообщения
Синтаксис:
PRINT [список]
Примеры:

PRINT Переводит вывод на новую строчку
PRINT “Это сообщение” Выводит сообщение
PRINT “X=”;X; “ Y=”;Y;

Выводит список, символ “;”

означает, что вывод производится подряд без пробелов. Пробелы, указанные внутри кавычек, выводятся. Символ ”;” в конце строчки означает, что следующий оператор PRINT продолжит печать в текущей строчке
PRINT X,Y,Z,

Выводит список, символ “,”означает, что вывод производится c табуляцией на 8. Символ ”,” в конце строчки означает, что следующий оператор PRINT продолжит печать в текущей строчке в текущей позиции табуляции.

 

AT

Действие:
Функция позиционирования, входит как элемент списка в оператор PRINT
Синтаксис:
PRINT AT(x,y);[список]
x – выражение, определяющее позицию в строке (от 1 до 80)
y – выражение, определяющее номер строки (от 1 до 24)
Пример:

PRINT AT(35,12);“Это сообщение”; AT(1,1); Выводит сообщение в центре экрана и перемещает курсор в левый верхний угол

 

CHR

Действие:
Функция вывода на консоль числа как символа, входит как элемент списка в оператор PRINT
Синтаксис:
PRINT [список1; или ,] CHR(val)[; или , [список2]]
val – код символа от 0 до 255
Пример:

FOR I=32 TO 127
     PRINT I,CHR(I)
NEXT
Выводит в столбик код символа и соответствующий символ

 

HEX, BCD, BIN

Действие:
HEX - вывод значения числа в шестнадцатеричной форме,
BCD - вывод значения числа в двоично-десятичной форме,
BIN - вывод значения числа в двоичной форме.
Функции HEX, BCD, BIN входят как элементы списка в оператор PRINT.
Синтаксис:
PRINT [список1]; или , HEX(value, digits)[; или , [список2]]
PRINT [список1]; или , BCD(value, digits)[; или , [список2]]
PRINT [список1]; или , BIN(value, digits)[; или , [список2]]

value – выводимое значение, выражение         
digits – количество выводимых цифр

Пример:

10 INPUT X
     PRINT X,HEX(X,4);BIN(X,16)
GOTO 10
Выводит значение переменной в трёх представлениях: десятичном, шестнадцатеричном и двоичном

Примечание 1. Действие оператора BCD не отличается от действия оператора HEX в силу свойств двоично-десятичного представления
Примечание 2. функции AT, HEX, BCD, BIN, CHR могут быть использованы самостоятельно для вывода на консоль, при этом они возвращают количество выведенных символов, например, при выполнении строки
N=BIN(X,8)
будет произведён  вывод числа X в двоичном виде на консоль, а переменная N примет значение 8. Функция AT возвращает нулевое значение

ATTR

Действие:
Оператор установки атрибутов вывода
Синтаксис:
ATTR  выражение

Здесь значение выражения определяет особенности вывода на консоль

0 – нормальный режим
1 – повышенная яркость
4 – подчёркивание
5 – мерцание
7 – инверсия цвета фона и цвета символов
8 – цвет символов принимает цвет фона

Последовательное применение оператора ATTR с различными параметрами, отличными от нуля, приводит к накоплению эффектов вывода. Нулевое значение восстанавливает нормальный режим.

INK, PAPER

Действие:
Операторы задания цветовых атрибутов
INK – задаёт цвет символов
PAPER – задаёт цвет фона
Синтаксис:
INK  выражение
PAPER  выражение

Здесь значение выражения определяет цветовой параметр вывода на консоль

0 – чёрный
1 – красный
2 – зелёный
3 – жёлтый
4 – синий
5 – розовый
6 – голубой
7 – белый

Примечание. Применение функции AT, операторов CLS, ATTR, PAPER, INK предполагает, что консоль является ANSI терминалом. Многие терминальные программы имеет в своём составе эмулятор для работы в этом режиме.

 

INPUT

Действие:
Оператор ввода, ожидает ввода значения в переменную
Синтаксис:
INPUT [сообщение,] переменная
Примеры:

INPUT X Выводит знак вопроса “?” и ожидает ввод числа
INPUT “X=”,X Выводит сообщение в двойных кавычках и ожидает ввода числа

 

INKEY

Действие:
Оператор ввода, проверяет состояние приёмного буфера консоли.
Немедленно возвращает -1, если буфер пуст или код очередного символа, если в буфере имеются принятые символы.
Синтаксис:
Переменная = INKEY()
Примеры:

A=INKEY() Считывает текущее состояние буфера

10  C=INKEY()
      IF C=-1 THEN GOTO 10

Ожидание ввода символа

10 C=INKEY()
IF C<>-1 THEN GOTO 20
повторяющиеся действия
GOTO 10
20 реакция на принятые символы
GOTO 10

Выполнение повторяющихся действий на фоне ожидания приёма символов

 

WAITKEY

Действие:
Оператор ввода, ожидает прихода символа, возвращает код принятого символа.
Синтаксис:
Переменная = WAITKEY()
Примеры:

     A=INKEY() Считывает содержимое буфера

 


2.2 УПРАВЛЕНИЕ ПРОЦЕССОМ

IF / THEN / ELSE

Действие:
Условный оператор. В данной реализации интерпретатора используется “неструктурная” версия оператора, поэтому допускается только запись в одну строку.
Синтаксис:
IF условие THEN оператор1 [ELSE оператор2]
Примеры:

IF X<10 THEN X=X+1 Если условие истина, то вычисляется выражение

IF X=0 THEN GOTO 100 ELSE GOTO 200

Если условие истина, то производится переход на строчку с меткой 100, иначе переход на метку 200

IF Z=65 THEN GOSUB 200

Если условие истина, то производится вызов подпрограммы с меткой 200

 

FOR / TO / NEXT

Действие:
Оператор цикла
Синтаксис:
FOR переменная = выражение1 TО выражение2
операторы тела цикла (действия, которые необходимо повторять в цикле)
NEXT
Примечание:
выражение1 – начальное значение переменной цикла;
выражение2 – конечное значение переменной цикла;
шаг переменной цикла равен единице.
Примеры:

FOR I=32 TO 127
     PRINT CHR(I),I
NEXT

Производит действие 127-32+1 раз с наращиванием переменной цикла. В качестве действия, вывод переменной как символа с кодом I и вывод значения переменной (таблица символов)

 

GOTO

Действие:
Оператор перехода
Синтаксис:
GOTO метка
Пример:

GOTO 100

Производится переход на строчку с меткой 100

 

GOSUB

Действие:
Оператор вызова подпрограммы
Синтаксис:
GOSUB метка
Пример:

GOSUB 100

Производит вызов подпрограммы с меткой 200     

 

RETURN

Действие:
Возврат из подпрограммы
Синтаксис:
RETURN
Пример:

100 PRINT X
       RETURN

Производит возврат подпрограммы

 

END

Действие:
Завершает выполнение программы. В любом месте, где интерпретатор встретит оператор END, он прекращает выполнение программы. Ставить оператор END в конце программы, считается хорошим тоном.
Синтаксис:
END
Примеры:

IF Z=0 THEN END

 

 

STOP

Действие:
Приостанавливает выполнение программы и очищает приёмный буфер консоли, продолжение при получении любого символа в буфер консоли
Синтаксис:
STOP
Примеры:

IF Z=0 THEN STOP

 

 

REM

 Действие:
Оператор комментирования
Синтаксис:
REM [любая строка]
оператор : REM [любая строка]
Примеры:

REM Это комментарий

Интерпретатор не исполняет эту строчку

A=10: REM комментарий Интерпретатор исполняет только оператор перед REM

 

DELAY

Действие:
Формирование задержки
Синтаксис:
DELAY выражение
Примеры:

DELAY 100
DELAY  X
DELAY  X + I * 10

Формирует задержку, длительность которой определяется выражением. Дискретность задания 1 миллисекунда.

 

2.3 ДАННЫЕ

DIM

Действие:
Определяет размер одномерного массива
Синтаксис:
DIM список
Примечание:
Размер массива определяется размером текущей доступной памяти. Начальный доступный размер свободной памяти зависит от типа контроллера

 

Small

Mini

Maxi

Базовый чип

ATMEGA16

ATMEGA32

ATMEGA64

Размер доступной памяти

140 байт/
70 элементов

1000 байт/
500 элементов

Будет определён по результатам портирования

        
Примеры:

DIM A(10),B(20)

Массив A - зарезервирована память для 10 элементов
Массив B - зарезервирована память для 20 элементов

 

DATA

Действие:
Определяет блок данных. Максимальное количество данных в строке определяется длиной строки, которая не должна превышать 64 символа. Максимальное количество строк с данными ограничено только размером свободной памяти программ.

Синтаксис:
DATA список
После старта интерпретатора, указатель устанавливается на начало первого блока данных.
Примеры:

DATA 9999, -1, 23456

Определён блок данных из трёх значений

 

READ

Действие:
Читает данные из блока DATA и передвигает указатель на следующее значение
Синтаксис:
READ список
Примеры:

READ A,B,C

Последовательное чтение данных в переменные A,B и C

 

RESTORE

 Действие:
Передвигает  указатель на необходимый блок данных.
Синтаксис:
RESTORE [метка]
Оператор  RESTORE без параметров устанавливает указатель на начало первого блока данных.
Примеры:

100 DATA 1,2,3,4,5,6
       DATA 7,8,9
110 DATA 555,777,888
….
RESTORE 110

 

 

 

Устанавливает указатель на блок с меткой 110, первое, считанное оператором READ значение, будет 555

 

 RESTORE Устанавливает указатель на первый в программе блок DATA

 

WRITEEEPROM

Действие:
Записывает байт по указанному адресу в энергонезависимую память
Синтаксис:
WRITEEEPROM адрес, байт

READEEPROM

Действие:
Возвращает значение, хранящееся по указанному адресу в энергонезависимой памяти
Синтаксис:
переменная = READEEPROM(адрес)

 

Small

Mini

Maxi

Базовый чип

ATMEGA16

ATMEGA32

ATMEGA64

Размер доступной энергонезависимой памяти, байт

512

1024

2048

 

2.4 ПРЕРЫВАНИЯ И МАШИННЫЙ КОД

ENABLE

 Действие:
Разрешает прерывания
Синтаксис:
ENABLE

DISABLE

 Действие:
Запрещает прерывания
Синтаксис:
DISABLE

INLINE

 Действие:
Создаёт блок машинного кода на этапе загрузки программы. Несколько INLINE строк  в любом месте программы последовательно образуют единый блок кода в специальной области памяти. Если блок кода образован несколькими строчками INLINE, необходимо позаботиться, чтобы интерпретатор проходил только по первой из них. Остальные нужно спрятать, например, сразу после ближайшего оператора RETURN или GOTO или END.
Блок кода должен быть оформлен как подпрограмма, последним оператором должен быть оператор RET.  Связь с переменными бейсика простая, регистры R16,R17 содержат указатель на переменную A. Принцип формирования адреса любой из 26 (от A до Z) скалярных переменных следующий:
адрес =  cодержимое_R16R17 + 2 * (код_символа_переменной - 65)

Синтаксис:
  INLINE opcode1, opcode2….
Пример:

10  INLINE opcode1, opcode2….

Простой случай применения оператора INLINE, блок кода помещается в одну строчку

10  INLINE opcode1, opcode2….
      RETURN
      INLINE opcoden, opcoden+1….

    При интерпретации будет использован только первый оператор INLINE, он извлечёт адрес первой команды блока кода и произведёт вызов подпрограммы по этому адресу.
    Если оператор RETURN стоял бы в конце всех строчек INLINE, то последовательно исполнялись всё меньшие порции одного и того же кода.
    Соблюдение правила разделения первого оператора INLINE - плата за простоту реализации и компактность интерпретатора

Примечание. Для автоматизации создания блоков кода можно применять утилиту bin2line, которая создаёт блоки кода INLINE из машинного кода.
Ниже показано содержимое командного файла, осуществляющего последовательную цепочку запуска ассемблера от AVR студии, конвертера  HEX в BIN и конвертера машинного кода в блоки INLINE

avrasm32 -fI -l %1.lst -o %1.hex %1.asm
hex2bin %1.hex %1.bin
bin2line -i %1.bin -o %1.bas

Для примера рассмотрим плохо поддающуюся интерпретации процедуру  доступа к 16-битным аппаратным регистрам AVR контроллеров.

Ассемблерная процедура вывода содержимого регистра A в регистр OCR1A:

.include "m64def.inc"
mov r30,r16
mov r31,r17
ld  r18,z+
ld  r19,z+
cli 
out OCR1AH,R19
out OCR1AL,R18
sei
ret

INLINE-блок после цепочки преобразования:

INLINE 12256,12273,37153,37169,38136,48443
INLINE 48426,38008,38152

Осталось поместить блок в текст бейсик программы, снабдить меткой и отделить первый оператор INLINE

200   INLINE 12256,12273,37153,37169,38136,48443
RETURN
INLINE 48426,38008,38152

INTERRUPT

Действие:
Создаёт блок машинного кода на этапе загрузки программы
Подключает код к вектору на этапе исполнения.
Если код обработчика не умещается в одной строке, можно продолжить уже с использованием оператора INLINE. Строка с INTERRUPT должна быть отделена от остального кода одним из операторов RETURN, GOTO, END. На этапе исполнения строчка с INLINE должна вызываться один раз для инициализации прерывания. Требования по оформлению блока кода  такие же как и для оператора INLINE.
Может быть одновременно назначено до 10 векторов. Невозможно задать прерывания
для UART0 и TIMER0, так как они используются системой.
Синтаксис:
INTERRUPT vector, opcode1, opcode2….
Пример:


INTERRUPT  vector, opcode1, opcode2…

 

200  INTERRUPT  vector, opcode1, opcode2…
         RETURN
         INLINE  opcoden, opcoden+1…

Простой случай, обработчик умещается в одной строке

При интерпретации будет использован только оператор INTERRUPT, он извлечёт адрес первой команды блока кода и свяжет адрес вызова с номером вектора

 

 

DELETEVECTOR

Действие:
Отключает код от  вектора и запрещает соответствующее прерывание
Синтаксис:
DELETEVECTOR vector

PUTATOMIC

 Действие:
Присвоение значения переменной, используемой в подпрограмме прерывания. Во время действия этого оператора производится присваивание значения переменной при запрещённых прерываниях, это обеспечивает целостную (атомарную) модификацию двухбайтовой переменной. Это необходимо, так как операция присваивания содержит цепочку из нескольких команд, которая могла быть разорвана прерыванием, осуществляющим доступ к этой же переменной.
Синтаксис:
PUTATOMIC переменная, значение

GETATOMIC

Действие:
Взять значение переменной, используемой в прерывании. Во время действия этого оператора производится извлечение значения переменной при запрещённых прерываниях,
Синтаксис:
переменная1 = GETATOMIC(переменная)

2.5 НАЗНАЧЕНИЕ И ИСПОЛЬЗОВАНИЕ ЛИНИЙ КОНТРОЛЛЕРА


Номер
ножки

Линия порта

Дополнительная
функция

0

PA0

ADC0

1

PA1

ADC1

2

PA2

ADC2

3

PA3

ADC3

4

PA4

ADC4

5

PA5

ADC5

6

PA6

ADC6

7

PA7

ADC7

8

PB0

 

9

PB1

 

10

PB2

 

11

PB3

 

12

PB4

 

13

PB5

 

14

PB6

 

15

PB7

 

16

PC0

 

17

PC1

 

18

PC2

 

19

PC3

 

20

PC4

 

21

PC5

 

27

PD3

 

28

PD4

PWM0

29

PD5

PWM1

30

PD6

 

31

PD7

 


DEFPIN

Действие:
Оператор назначает функцию линии контроллера.
Линии контроллера имеют сквозную нумерацию от нуля, до некоторого максимального значения, определяемого типом контроллера. Все ножки могут быть назначены для дискретного ввода или вывода. Возможность назначения дополнительных функций ножек (аналоговый ввод, ШИМ) зависит от конкретного типа контроллера

 

Small

Mini

Maxi

Базовый чип

ATMEGA16

ATMEGA32

ATMEGA64

Общее количество линий (ножек)

26

26

 

Номера ножек, которым может быть назначена функция DIN/DOUT

0..21, 27..31

0..21, 27..31

 

Номера ножек, которым может быть назначена функция AIN

0..7

0..7

 

Номера ножек, которым может быть назначена функция PWM

28,29

28,29

 

Синтаксис:
DEFPIN ножка AS тип

Примечание:

тип

функция

DIN

Дискретный ввод

DOUT

Дискретный вывод

AIN

Аналоговый ввод

PWM

ШИМ

Пример:

DEFPIN 8 AS DOUT

Настроить линию 8 для работы на вывод

CLEAR

Действие:
Установить линию в ноль
Синтаксис:
CLEARBIT pin

SET

Действие:
Установить линию в единицу
Синтаксис:
SETBIT pin

TOGGLE

Действие:
Изменить состояние линии на противоположное
Синтаксис:
TOGGLE pin

TEST

Действие:
Прочитать состояние линии
Синтаксис:
var = TESTPIN(pin)

PWM

Действие:
Вывод значения в канал ШИМ
Синтаксис:
PWR pwm_pin, value

SETADMUX

Действие:
Настройка мультиплексора АЦП
Синтаксис:
SETADMUX value
Примечание:
value = источник_опоры + канал_мультиплексора

источник_опоры

 

0

Источник опорного напряжения – ножка AREF

64

Источник опорного напряжения – ножка AVCC

192

Внутренний источник напряжения 2.56 Вольт

 

ADC

Действие:
Чтение измеренного значения напряжения текущего канала АЦП
Синтаксис:
var = ADС

 


2.6 ДОСТУП К РЕСУРСАМ МИКРОКОНТРОЛЛЕРА

 

POKE

Действие:
Помещает байт в ячейку памяти (внутреннюю или регистр ввода/вывода)
Синтаксис:
POKE adr, val

PEEK

Действие:
Чтение ячейки памяти (внутренней или регистров ввода/вывода)
Синтаксис:
var = PEEK(adr)

Примечание. В каждом конкретном случае, для определения адреса нужного регистра, необходимо сверяться с документацией на микроконтроллер.
В документации для регистров обычно указывается два адреса, по одному осуществляется доступ как регистрам ввода-вывода, а по другому как к ячейке памяти. Оператор POKE и функция PEEK оперируют с адресами ячеек памяти, поэтому, если известен адрес для ввода-вывода, нужно прибавить к этому адресу 32 для получения адреса в пространстве ячеек памяти.

2.6.1 Доступ к 16-битным регистрам AVR-микроконтроллера

Доступ к 16-битным регистрам AVR микроконтроллера имеет особенность. Для обеспечения одновременной модификации всех 16 бит таких регистров аппаратно задействуется временный 8-битный регистр. С точки зрения программы это происходит прозрачно, необходимо только выдержать последовательность обращения к половинкам этих регистров:
сначала к старшей, потом младшей при записи и, наоборот, при чтении, обязательно с использованием ассемблерных команд IN и OUT. Эти команды трудно параметризировать, они используют константы в своём теле и пришлось бы создать дополнительное число редко используемых бейсик операторов по числу регистров. Это в данном интерпретаторе не реализовано. Но, благодаря возможностям оператора INLINE, возможно создание подпрограмм для каждого конкретного случая.
В качестве примера приведены две подпрограммы для доступа к регистру OCR1A через переменную A.

REM .include "m64def.inc"
REM    mov r30,r16
REM    mov r31,r17
REM    ld  r18,z+
REM    ld  r19,z+
REM    cli 
REM    out OCR1AH,R19
REM    out OCR1AL,R18
REM    sei
REM    ret

REM   WRITE to OCR1A
200   INLINE 12256,12273,37153,37169,38136,48443
RETURN
INLINE 48426,38008,38152

REM  .include "m64def.inc"
REM    mov r30,r16
REM    mov r31,r17
REM    cli 
REM    in R18,OCR1AL
REM    in R19,OCR1AH
REM    sei
REM    st  z+, r18
REM    st  z+, r19
REM    ret

REM   READ from OCR1A
300   INLINE 12256,12273,38136,46378,46395,38008
RETURN
INLINE 37665,37681,38152


2.7 ВЫЧИСЛЕНИЯ

HIGH

Действие:
Возвращает старший байт числа
Синтаксис:
переменная = HIGH(выражение)

LOW

Действие:
Возвращает младший байт числа
Синтаксис:
переменная = LOW(выражение)

ABS

Действие:
Возвращает абсолютное значение числа
Синтаксис:
переменная = ABS(выражение)

ROL

Действие:
Сдвигает число в переменной влево, при этом в младший разряд втягиваются нули
Синтаксис:
ROL переменная, число_сдвигов

ROR

Действие:
Сдвигает число в переменной влево, при этом в старший разряд втягиваются нули
Синтаксис:
ROR переменная, число_сдвигов

SCALE

Действие:
Оператор масштабирования
Синтаксис:
SCALE переменная, множитель, делитель
Примеры:


SCALE X,100,Y

Рассчитывает процент числа X от числа Y.
Сначала производится умножение X на 100 и результат помещается в 32-х битную временную переменную, затем производится деление на Y, результат помещается в X

SCALE X,1000,Y

Тоже, но с точностью до десятых долей процента


2.8 ТРАДИЦИОННЫЕ РАСШИРЕНИЯ (BASIC STAMP, BASCOM)

PULSEIN

Действие:
Возвращает длительность импульса на выводе контроллера, каждая единица соответствует
приблизительно 1 микросекунде при частоте кварца 14.745 Мгц
Синтаксис:
var = PULSEIN(pin, option, timeout)
Примечание:


option

 

0

ожидание положительного фронта и измерение длительности до изменения фронта

1

ожидание отрицательного фронта и измерение длительности до изменения фронта

 

PULSEOUT

Действие:
Изменяет состояние вывода, формирует паузу и снова изменяет состояние вывода
Синтаксис:
PULSEOUT pin, duration

pin – номер ножки, на которую предполагается выводить импульс
duration - определяет длительность импульса, одна единица соответствует приблизительно 1 микросекунде при частоте кварца 14.745 Мгц

SHIFTIN

Действие:
Возвращает принятую последовательность бит
Синтаксис:
var = SHIFTIN(data_pin, clock_pin, bits, delay, option, timeout)
Примечание:


data_pin

входные последовательные данные

clock_pin

синхронизация, режим определяется в option

Bits

количество втягиваемых бит

Delay

в усл. единицах при формировании импульсов синхронизации,
приблизительно 1 микросекунда при частоте кварца 14.745 Мгц

Option

режим синхронизации:
clk_pin – выход:
0 – старший бит первый по положительному фронту
1 – старший бит первый по отрицательному фронту
2 – младший бит первый по положительному фронту
3 – младший бит первый по отрицательному фронту
clk_pin – вход:
option = option + 4

timeout

время в мс, по истечению которого функция возвращает ноль и переменная LASTERROR принимает значение 1. Значение timeout актуально когда clk_pin работает как вход синхронизации

 

SHIFOUT

Действие:
Выводит содержимое переменной как последовательность бит
Синтаксис:
SHIFTOUT var, data_pin, clock_pin, bits, delay, option
Примечание:


Var

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

Data_pin

входные последовательные данные

clock_pin

синхронизация, режим определяется в option

Bits

количество втягиваемых бит

Delay

в усл. единицах при формировании импульсов синхронизации,
приблизительно 1 микросекунда при частоте кварца 14.745 Мгц

Option

режим синхронизации:
clk_pin – выход:
0 – старший бит первый по положительному фронту
1 – старший бит первый по отрицательному фронту
2 – младший бит первый по положительному фронту
3 – младший бит первый по отрицательному фронту

 


2.9 ДВУХПРОВОДНЫЙ ИНТЕРФЕЙС

TWIINIT

Действие:
Инициализация TWI (I2C) интерфейса
Синтаксис:
TWIINIT bps, prescale

bps – коэффициент для бодовой скорости
prescale – показатель для предделителя

Скорость на ножке SCL определяется по формуле, приведённой ниже:

SCL frequency = CPU Clock frequency / (16 + 2(bps) * 4^prescale )

TWISTART

Действие:
Генерирует START условие на выводах SDA,SCL
Синтаксис:
TWISTART

TWIWRITE

Действие:
Отправляет байт на TWI (I2C) устройство
Синтаксис:
TWIWRITE байт

TWIREAD

Действие:
Принимает байт от TWI (I2C) устройства, генерирует ACK/NACK
Синтаксис:
Переменная = TWIREAD(ack)
Значение параметра ack:
0 – генерируется NACK
1 – генерируется ACK

TWISTOP

Действие:
Генерирует STOP условие на выводах SDA,SCL
Синтаксис:
TWISTOP

 Пример:

  print "***************************"
print "*    DS1339U TWI TEST     *"
print "***************************"
DIM A(16)
TWIINIT 16,2
TWISTART
rem DS1339U Slave address to write
TWIWRITE &HD0
rem Trickle Charger Register (10h)
TWIWRITE &H10:TWIWRITE &B10100101
TWISTOP
10    A=0:TWISTART:TWIWRITE &HD0:TWIWRITE A:TWISTOP
TWISTART:TWIWRITE &HD1
FOR i=0 to 5
A(i)=TWIREAD(1)
NEXT
A(6)=TWIREAD(0):TWISTOP
PRINT "Year:";
if (A(5)AND 128)=0 then print "19";else print "20";
print bcd(a(6),2);
print " Month:";bcd(a(5) AND 127,2);
print " Date:";bcd(a(3),2);" Day:";bcd(a(3),2);
print " ";bcd(a(2),2);":";bcd(a(1),2);":";bcd(a(0)
GOTO 10

2.10 ДИАГНОСТИКА

При выполнении программы могут возникать ситуации, при которых интерпретатор останавливает свою работу и выводит сообщение об ошибке, в котором указывается код и номер строки.

Код ошибки

Значение ошибки

0

Синтаксическая ошибка

1

Нарушена парность скобок

2

Ожидалось выражение

3

Ожидался знак выражения

4

Ожидалась переменная

5

Таблица меток переполнена

6

Несколько меток с одинаковыми именами

7

Неопределённая метка

8

Ожидался оператор THEN

9

Ожидался оператор TO

10

Слишком много вложенных циклов

11

Встречен оператор NEXT, не принадлежащий оператору FOR

12

Слишком много вложенных подпрограмм

13

Встретился оператор RETURN, но вызова подпрограммы не было

14

Размер массива не определён

15

Повторное определение размера массива

16

Недостаточно памяти

17

Индекс за пределами массива

18

Указатель вне блока DATA

20

Невозможно назначить ещё один вектор прерывания

Существует ряд критических ситуаций, при которых работа не прекращается и эту ситуации можно детектировать при помощи функции LASTERROR

LASTERROR

Действие:
Возвращает код последней ошибки или критической ситуации
Синтаксис:
переменная = LASTERROR()
Примечание:

Код ошибки

Значение ошибки

0

Нет ошибок

1

Ошибка таймаута (в функциях PULSEIN и SHIFTIN)

2

Ошибка в работе TWI

 

 


3. ИСПОЛЬЗОВАНИЕ ПРЕПРОЦЕССОРА

Язык Бейсик является чрезвычайно простым языком, но в то же время, на нём трудно писать большие программы, особенно в реализациях языка, где имена переменных зарезервированы, а длина составляет 1-2 символа, в таких случаях комментарии не сильно помогают. Идеальный случай, когда длина имени переменной такова, что понятен смысл и без комментариев, то есть, когда можно говорить, о “самокомментируемости“ объекта языка, сказанное относится и к именам меток. Длинные имена находятся в противоречии с быстродействием интерпретатора и размером памяти программ.
Эту проблему может разрешить применение препроцессора, специальной программы-конвертора. В тексте программы помещаются строчки c директивой препроцессора DEFINE, пишется желаемое длинное имя, знак “=”, а за ним численное значение или имя переменной. В тексте программы размещается необходимое количество пояснений, их можно писать с использованием оператора REM и с использованием знака апострофа. Далее, везде, где необходимо, вместо коротких имён и численных значений, можно использовать символьные определения, сделанные ранее при помощи директивы DEFINE. В конечном итоге, текст будет похож на пример, который приведён ниже.

 

 

'--------------------------------------------------------
'  TBC GROUP                                        2006
'                    SHIFTOUT TEST
'
'--------------------------------------------------------
' Опции для тактового сигнала
define  MSB_FIRST_POSITIVE = 0 'старший бит первый, по положительному фронту
define  MSB_FIRST_NEGATIVE = 1 'старший бит первый, по отрицательному фронту
define  LSB_FIRST_POSITIVE = 2 'младший бит первый, по положительному фронту
define  LSB_FIRST_NEGATIVE = 3 'младший бит первый, по отрицательному фронту

define  TotalBits  = N ' Количество бит от 1 до 16
define  SrcData    = A ' Переменная с исходным словом
define  DataPin    = D ' Номер ножки данных
define  ClockPin   = C ' номер ножки синхронизации
define  Options    = B ' опцияклоков
define  PulseDelay = 100 ' определяет длительность тактовых импульсов,
                   ' которая получается равной 2 * PulseDelay
define  MainLoop   = 10  ' Значение метки, просто число
CLS
    PRINT "*******************************"
    PRINT "*       SHIFTOUT TEST         *"
    PRINT "*******************************"
    input "DATA PIN=",DataPin
           DEFPIN DataPin AS DOUT:SET DataPin
    input "CLOCK PIN=",ClockPin
           DEFPIN ClockPin AS DOUT:CLEAR ClockPin
MainLoop
    input "TOTAL BITS=",TotalBits
        input "options=",options
          input "data=",SrcData
        shiftout SrcData,DataPin,ClockPin,TotalBits,PulseDelay,Options
GOTO MainLoop

 

 

 

Полученный текст сохраняется под именем, например, shift.bas.
Далее, в командной строке набирается:
BASPREP.EXE –I shift.bas –O shift.out

Примечание. BASPREP.EXE должен находиться в этом же каталоге или быть видимым из текущего расположения. Чтобы он был виден из любого места, самый простой способ – поместить его в директорию C:\WINDOWS, например.

В результате работы препроцессора, будет получен файл shift.out (содержимое показано ниже), в котором отсутствуют комментарии, а вместо символьных имён подставлены значения, расположенные в правой части определений.

 

 

 

CLS
PRINT"*******************************"
PRINT"*       SHIFTOUTTEST         *"
PRINT"*******************************"
INPUT "DATA PIN=",D
DEFPIN D AS DOUT:SET D
INPUT "CLOCK PIN=",C
DEFPIN C AS DOUT:CLEAR C
10 INPUT "TOTAL BITS=",N
INPUT "options=",B
INPUT "data=",A
SHIFTOUT A,D,C,N,100,B
GOTO 10

 

 

 

Такой текст займёт меньше места в контроллере

 

 

 

19.02.2007