| ||||||||||||||||||||||||||||||||||||||||||
Музыка, I2C часы и другие забавные программы Tiny Basic был создан в середине 1970х годов для первых компьютеров с очень ограниченным объёмом памяти. В Tiny Basic имена переменных состоят только из одной буквы, поэтому в программе может быть не более 26 переменных (хотя можно декларировать массивы). Замечательную версию Tiny Basic для Arduino с открытым исходным кодом можно найти по адресу: https://github.com/slviajero/tinybasic Tiny Basic для Arduino обладает весьма большим быстродействием в сравнении с компьютерами 70х годов, но размер BASIC-программ ограничен примерно 1 килобайтом (!). Это делает его не очень полезным для разработок, но он очень удобен для обучения и простейших экспериментов с Arduino. Он поддерживает возможность работы с I2C интерфейсом, радио платами, дисплеями, клавиатурами и многим другим. В этой статье описываются основы работы с Tiny Basic в наиболее простых примерах. Скачайте архив с Tiny Basic и примерами программ с этой страницы. В файле manual.md дано подробное руководство по языку. Файлы .ino и .h - исходный текст программы. Загрузите скетч в Arduino IDE. Программу можно настроить операторами #define на разные конфигурации. В этой версии - целочисленный BASIC с поддержкой PLAY (функция tone()). Загрузите скётч в Arduino (у меня - Arduino Uno). Запустите терминал IDE Установите скорость обмена 9600 Бод и завершение строки символом NL. Теперь можно набрать простую программу, например: 10 A$=9:PRINT "Pythagorean table" 20 FOR J=1 TO 9 30 FOR I=1 TO 9 40 PRINT I*J;a$; 50 NEXT I 60 PRINT 70 NEXT JЗапустите программу командой RUN Неплохо, правда ? Но как теперь сохранить программу, не набирать же её каждый раз заново ? Наберите SAVE - программа сохранится в EEPROM Arduino. Теперь можно нажать на Reset или закрыть и снова открыть терминал, и даже отключить Arduino от питания. Программа исчезнет, но она может быть снова загружена командой LOAD Для того, чтобы загружать .bas файлы в Arduino, я написал простую программу !load.exe на языке PureBasic Откройте файл !load.ini и введите имя COM порта, к которому подключается Arduino. Запустите !load.exe Попробуйте набрать теперь load blink (обратите внимание - строчными буквами). Если всё нормально, должна загрузиться программа. Запустите её командой run и Вы увидите мигание встроенного на плату светодиода. Ну, а если потребуется загрузить программу из EEPROM ? Тогда используйте LOAD (большие буквы). Для сохранения программы на диске используется команда save filename или просто save Завершить наш маленький терминал можно командой exit (строчные буквы). Полезные команды Tiny Basic и !load
Я также написал версию терминала на VisualBasic.NET Эта версия программы называется SerialSmall.exe Перед запуском программы следует записать в файл SerialSmall.ini (с помощью notepad) номер COM порта, к которому подключается Arduino. Если записать в .ini файл COM0, то имя COM порта Arduino будет определяться автоматически (не до конца проверено). SerialSmall.exe выполняет те же команды, что и !load.exe. Для работы требуется установленная библиотека .NET Для дальнейших опытов понадобится пищалка (баззер), подключённая к выходу 8 Arduino и к земле (обязательно отключите плату Arduino от компьютера при монтаже). Подключите Arduino и запустите !load.exe Наберите к примеру load nokia. Наберите run - программа проиграет незабвенный рингтон Nokia. Обратите внимание, как закодированы ноты. (Команда list) В качестве первого параметра идёт частота звука, в качестве второго - достаточно большая задержка в миллисекундах, делённая на число (напомним, что BASIC - целочисленный). Это сделано для того, чтобы уменьшить объём памяти, занимаемый строками DATA. При желании можно изменить пин подключения баззера, отредактировав строку B=8 Я сконвертировал на Tiny Basic несколько мелодий, все программы построены сходным образом, за исключением minuet.bas Эта мелодия оказалась слишком длинной и не вмещалась в 1 килобайт. Поэтому я преобразовал строки "DATA число1,число2,..." в строки по 60 символов (20 нот). Один символ кодирует 5 бит: "@" - 0, "A" - 1, и далее до "^" - 31. Таким образом ноту кодируют 3 символа: 2 - частота (от 0 до 1023) и 1 - длительность (от 0 до 31). Попробуем написать на Tiny Basic более сложную программу - управление часами реального времени DS1307. Я использовал готовую плату - "Тройка модуль" от amperka.ru с литиевой батарейкой, кварцем и резисторами. Вы можете попробовать любую другую микросхему с интерфейсом I2C. На примере для часов я покажу, как действительно надо программировать обмен по I2C. Подключите модуль RTC к контактам A4 (D-SDA) и A5 (C-SCL), а также подключите питание на разъём питания. Контакты A4 и A5 являются аппаратными для шины I2C, но я предложу чисто программный вариант обмена I2C Master. Запустите !load.exe и в ней команды load i2cscan, run. Если всё работает нормально, появится сообщение "Device found at address 114". Теперь можно загрузить load i2clock и посмотреть, как она работает. Программа i2clock приближается по длине с максимуму для Tiny Basic и содержит следующие подпрограммы. Обратите особое внимание на переключение режимов линии SDA. PINM D,1 - запись, PINM D,2 - чтение с подтягивающим резистором.
Так как же программировать шину I2C ? В руководствах по чипам с I2C всё вроде бы просто: "выдайте Start-условие, затем 7-битный адрес slave и бит чтение-запись, затем по алгоритму пишите или читайте байты, в конце выдайте Stop-условие". При этом создатели I2C отмечают, что протокол синхронный, и его можно чуть ли не по шагам отлаживать. На самом деле I2C - это настоящий Ящик Пандоры. С линией SCL всё понятно - микроконтроллер переводит пин в режим записи и выдаёт через неё стробы. Но линия SDA - двунаправленная, поэтому при отладке (даже с помощью осциллографа) непонятно, кто генерирует сигнал - master или slave. Представим себе, что master читает, а slave передаёт байты, например байт со значением 0. И внезапно (например при отладке) мы остановили программу (где-то на середине приёма байта). Как правильно возобновить обмен с slave с самого начала ? Послать Start-условие ? Но если slave передаёт бит 0, он давит линию SDA низким уровнем и не отреагирует на Start. Послать Stop-условие ? Та же проблема. К тому же, особенно если slave программный, он может и не ждать Stop в этот момент, а просто сидеть в цикле, надеясь передать остатки байта. Здесь даже reset микроконтроллера не поможет, поскольку он не подействует на slave, поможет только полное отключение питания от схемы. Опытным путём я нашёл следующее решение: чтобы начать работу по шине I2C (особенно, если на ней подключено несколько slave) надо в цикле посылать Stop-условие, а затем читать линию SDA до тех пор, пока не придут подряд 18 уровней "1" (18=9*2, где 9 бит соответствует приёму или передаче одного байта с битом подтверждения). Следующая подпрограмма иллюстрирует этот способ. 590 rem "Reset I2C bus" 600 Z=0 605 rem "200 - subroutine of Stop" 610 gosub 200:A=dread(D) 620 if A=0 then goto 600 620 Z=Z+1:IF Z<=18 THEN GOTO 610 630 RETURN Ещё одна интересная микросхема с интерфейсом I2C - Atmel AT24C512 - FLASH память объёмом 64 KB. Этот чип относительно легко подключается и программируется, но имеет свои трюки. Для подключения AT24C512 достаточно 4 линий: земля, +5V, SCL, SDA. Если других микросхем на шине I2C нет, нужно исспользовать 2 подтягивающих резистора по 2 КОм на линиях SCL и SDA. По умолчанию AT24C512 имеет 7битный адрес устройства 50h (8битный - 0A0h). Чтение чипа возможно с любого адреса памяти на любую длину (в пределах ёмкости). Запись чипа возможна только в пределах адресов памяти одной страницы (для этой модели - 128 байт). Записав страницу, следует выдать Stop-условие и дождаться, пока страница запишется. Время записи - порядка десятков миллисекунд, что значительно больше, чем при обычном обмене с чипом по I2C (порадка нескольких микросекунд при передаче байта). В программе на Tiny Basic это не столь заметно, т к программа выполняется медленно, но при программировании на Си длинные задержки записи FLASH следует учитывать. Я написал 3 программы работы с AT24C512, используя уже описанные подпрограммы:
Подключите AT24C512 согласно схеме. Запустите !load.exe или serialsmall.exe Наберите load i2flashr runВы увидите содержимое первых 256 байт FLASH памяти. (если AT24C512 новая, то это будут байты 0FFh) Теперь наберите: load i2flashw run load i2flashr runСодержимое таблицы байт изменится на 00,01,02...FD,FE,FF - FLASH память запрограммирована. Чтобы вернуть память к исходному состоянию, наберите: load i2flasherase run load i2flashr runПервые 256 байт FLASH памяти будут заполнены байтами 0FFh. Загрузить скетч Tiny Basic, терминал !Load и .bas примеры программ Обновлено 7 июля 2024 Программа !load.exe заменена версией на PureBasic (см. исходный текст !load.pb). Добавлено несколько мелодий, программы i2clon.bas и i2clon2.bas теперь печатают дату и время. Добавлены программы i2flash*.bas для работы с FLASH памятью AT24C512 |