ATtiny13a: использование ассемблера GNU-AS в программах на Си

разделы: AVR, АССЕМБЛЕР, дата: 17 февраля 2018г.

То, что Arduino очень медленно обрабатывает внешние прерывания, я заметил еще осенью прошлого года, когда разбирался с RTC. Тогда я пытался тактировать счетчик часов Arduino от 32кHz вывода DS3231, но такие часы у меня отставали секунд на десять в минуту. Для 16 МГц микроконтроллера, это было абсолютное фиаско.

В следующий раз я столкнулся с проблемой на ATtiny13, когда делал счетчик импульсов. В этот раз Arduino досталась роль передатчика, а ATtiny13a работающей на частоте 9.6 МГц был в роли счетчика. Но несмотря на то, что прошивка была написана на чистом Си, а обработчик внешнего прерывания прерывания состоял всего из одной строчки: "value++;", максимальная рабочая частота счетчика достигала всего 200кГц.

Такой результат меня тоже не устроил, и я решил, что обработчик прерывания нужно писать на ассемблере. Забегая вперед, скажу, что это дало мне прирост по максимальной частоте в три раза т.е. до 600кГц.

Ок, ассемблер это хорошая штука в плане скорости, но полностью прошивку писать на нем довольно тоскливое занятие. В AVR нет даже целочисленного деления. Выходом может стать написание смешанного кода на ассемблере и Си, т.к. gnu ассемблер по сути является бэкендом gcc-компилятора.

Но прежде чем начать использовать ассемблерные функции и прерывания в Си-программах, нужно будет познакомится с процессом компиляции, сборки и линковки таких смешанных проектов.

    Содержание статьи:
  1. Blink на ассемблере GNU-AS, создание проекта.
  2. Использование в ассемблерной программе мнемоники из Си для портов и регистров.
  3. Добавление таблицы векторов.
  4. Смешивание Си и ассемблерного кода в одной программе.
  5. Передача и получение параметров из Си-программы в ассемблерную функцию.
  6. Переписываем с Си на ассемблер функцию wait_ms() на прерывании таймера.
  7. Линковка проекта.
  8. Счетчик на 4-x разрядном семисегментном индикаторе.
  9. Счетчик импульсов на ассемблерном прерывании.

Архив с полными исходниками, сборочными файлами и скомпилированными прошивками можно будет скачать по ссылке в конце статьи.

Читать дальше

Связь двух микроконтроллеров на примере подключения 4-х разрядного семисегментного индикатора к Arduino через вспомогательный микроконтроллер ATtyny13a

разделы: Arduino, AVR, UART, I2C, дата: 29 января 2018г.

Если под вашу задачу требуется большее число пинов/портов/мегагерц/памяти, чем имеется в используемом вами микроконтроллере, то в ответ на эту проблему обычно советуют взять микроконтроллер "покрупнее". Ответ не лишенный смысла, однако мне удалось найти задачку, от которой так просто не отмахнешься. Героем сегодняшней статьи будет 4-х разрядный семисегментный индикатор с динамической индикацией.

Я уже упоминал о нем в статье про сдвиговые регистры, но тогда у меня не было на руках самой железки, и соответственно говорил я лишь теоретически. Сами ардуинщики об индикаторе отзываются не очень лестно, т.к. применение этого индикатора ограниченное из-за того, что вследствие динамической индикации его нужно постоянно обновлять, что накладывает серьезное ограничение на основную программу. Теоретически эту задачу можно было бы "скинуть" в прерывание таймера, но решение это спорное.

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

Индикатор не содержит подтягивающих резисторов(!), возможно здесь используются сдвиговые регистры с подтяжкой? Так или иначе, я замерял потребление модуля через EnargyTrace и получил значение около 23mA при питании 3.3 Вольт, что для такой "гирлянды" вполне нормально.

Китайские ATtiny13a в SO-8 корпусе стоят около 15₽, они имеют пять рабочих выводов, три из которых нужно будет отдать на индикатор, остаются два вывода для организации линии связи, что более чем достаточно, но простенький SPI сюда не посадишь, т.к. тот SPI который будет использоваться для управления индикатором, работает мастером, а для связи с "главным" микроконтроллером нужен будет слейв( запускать слейв на главном микроконтроллере - это не вариант). К сожалению или к счастью(смотря как посмотреть), АTtiny13a не поддерживает аппаратно абсолютно никаких протоколов.

Т.о. перед нами стоит задача на ATtiny13a организовать c использованием не более двух пинов скоростную и надежную линию для приема двухбайтного числа от главного микроконтроллера, и отобразить его на 4-х разрядном семисегментном индикаторе. В идеале было бы использование аппаратного протокола главным микроконтроллером и его программной реализации на ATtiny13a. Также хотелось бы, что чтобы код реализации протоколов занимал минимально возможное место на флеше, чтобы его потом можно было использовать в других более сложных проектах.

    Оглавление статьи:
  1. Счетчик на ATiny13a и 4-х разрядном семисегментном индикаторе
  2. Простой протокол на счетчике импульсов
  3. Пакетная передача данных с использованием буфера
  4. Программный UART для ATtiny13a
  5. Программный I2C Slave на ATtiny13a

Т.к. подразумевается использование индикатора для отображения температуры паяльника, во всех примерах будут задействованы только три разряда индикатора.

Полные исходники вместе со сборочными файлами и скомпилированными прошивками можно скачать по ссылке к конце статьи.

Читать дальше

ATmega8 + PCD8544: работа с графическим дисплеем от телефонов Nokia 5110/3310

разделы: AVR, SPI, PCD8544, дата: 23 ноября 2017г.

Дисплей от мобильного телефона Nokia 5110/3310 - это довольно известный графический дисплей начального уровня на управляющем контроллере pcd8544. Цена на него колеблется в пределах ста рублей, что сделало его широко распространенным "народным" дисплеем, наряду со знакогенерирующим LCD1602. Несмотря на широкое распространение, имеющаяся информация по этому дисплею или противоречива, или обрывочна(например). Ниже приводится лог недельного изучения девайса с примерами кода от простого к сложному. Вначале я пытался использовать Proteus для большей наглядности, но его возможностей, увы, хватило только на три примера. Поэтому остальные примеры идут для реальной связки ATmega8+дисплей. Так или иначе примеры с Proteus работают и на настоящем устройстве. Ко всем примерами, исходники к ним, скомпилированные прошивками и сборочные Makefile можно скачать здесь https://gitlab.com/flank1er/pcd8544_atmega8.

Должен сразу сказать, что для русификации дисплея я использовал кодировку CP866, и сделал я это удобным для Linux-пользователей способом. В Windows это получится использовать разве что из CYGWIN (понадобится утилита iconv).

Также должен упомянуть, что у меня были сложности с управлением дисплеем через аппаратный SPI. Она заключается в том, что и USBasp, и дисплей используют SPI порт ATmega8, и чтобы загрузить прошивку в микроконтроллер, дисплей приходится отключать. Это просто неудобно. Поэтому почти во всех примерах используется подключение дисплея по программному SPI. Подключение через аппаратный SPI используется только во втором и в последнем (финишном) примере (там не сложно, лишь нужно поменять пару строчек в коде и переподключиться к нужным пинам).

В целом, говоря про графические дисплеи, скажу, что эти штуки быстро "съедают" оперативную и флеш память и легко занимают всю пропускную способность SPI шины ;)

    Содержание статьи:
  1. Основные характеристики дисплея на контроллере pcd8544;
  2. Подключение дисплея к Arduino;
  3. Пишем HelloWorld для ATmega8+PCD8544 в Proteus;
  4. Переподключение дисплея на аппаратный SPI в Proteus;
  5. Функции масштабирование шрифта в два и три раза;
  6. Создание проекта для реального микроконтроллера ATmega8, чтение таблицы ASCII из флеш-памяти;
  7. Добавляем кириллицу в кодировке CP866
  8. Добавление фреймбуфера. Программа рисования фрактала.
  9. Делаем скринсейвер "сквозь звездное небо"
  10. Функции рисования прямых линий, и окружностей
  11. Интерфейс для метеостанции
  12. Интерфейс для FM-радиоприемника
  13. Финальная версия библиотеки на аппаратном SPI

Читать дальше

ATmega8 + PCF8574: 8-битный расширитель портов на I2C интерфейсе

разделы: AVR, Arduino, I2C, HD44780, дата: 24 октября 2017г.

Статья правилась 5-го августа 2022г. Было испрвлено неверное определение: "сдвиговый регистр pcf8574" на правильное: "расширитель портов pcf8574". Добавлено оглавление. Также поправлена битая ссылка на datasheet.

Этот расширитель портов наиболее известен по китайским драйверам дисплея HD44780, которые можно приобрести на али или ибэе. Он довольно подробно был разобран здесь: "Сообщество EasyElectronics.ru: I2C расширитель портов PCF8574". Я в свою очередь, попытаюсь сосредоточиться на программировании микроконтроллера ATmega8 для работы с этим регистром. Впрочем, начну я все же с Arduino и имеющегося у меня зоопарка: ATmega328/MSP430G2553/STM32F103C8.

Расширитель портов PCF8574 может выпускаться разными фирмами, мне попались чипы с суффиксом "T", что обозначает производителя как "NXP Semiconductor". Руководство на pcf8574t можно скачать с официального сайта NXP: "PCF8574; PCF8574A Remote 8-bit I/O expander for I2C-bus with interrupt".

Содержание:

I. Общие сведения

  1. Немного справочной информации
  2. Подключение LCD HD44780 к Arduino через модуль драйвера на PCF8574
  3. Подключение LCD HD44780 к STM32duino через модуль драйвера на PCF8574
  4. Подключение LCD HD44780 к MSP430 Launchpad через модуль драйвера на PCF8574
  5. Arduino библиотека PCF8574

II. Работа PCF8574 + ATmega8

  1. Сканер I2C шины
  2. Бегущий огонь на расширителе портов PCF8574
  3. Управление семисегментным индикатором через расширитель портов PCF8574
  4. Чтение из расширителя портов PCF8574
  5. Подключение LCD HD44780 через расширитель портов PCF8574

Читать дальше

ATmega8 + Proteus: входной сдвиговый регистр 74HC165, совместная работа с 74hc595

разделы: AVR, SPI, Proteus, HD44780, дата: 13 октября 2017г.

    Сдвиговые регистры, оглавление:
  1. ATmega8 + Proteus: работа со сдвиговыми регистром 74HC595
  2. ATmega8 + Proteus: входной сдвиговый регистр 74HC165, совместная работа с 74hc595
  3. ATmega8 + Arduino + Proteus: 8-битный сдвиговой регистр на I2C интерфейсе PCF8574

Вначале я хотел дополнить предыдущую статью входным регистром 74hc165, но потом понял понял, что он заслуживает "свои пять минут славы". Сложности возникают при подключении входного регистра совместно с выходным 74hc595 на один SPI порт. Кроме того, как оказалось, организация работы по SPI в ATmega8 имеет свои интересные особенности.

Итак, сдвиговый регистр 74hc165 преобразует параллельную шину в последовательную, работает только на вход, и имеет разрядность 8-бит. Их так же можно подключать цепочкой из n-элементов, которая даст 8^n - входов.

Руководство на SN74HC165N можно скачать например с сайта Texas Instruments.

    Оглавление:
  1. Чтение сдвигового регистра 74hc165 через программный SPI интерфейс;
  2. Чтение сдвигового регистра 74hc165 через аппаратный SPI ATmega8;
  3. Ретранслятор параллельной шины;
  4. LCD дисплей HD44780 и сдвиговый регистр 74HC165(вариант для Proteus);
  5. LCD дисплей HD44780 и сдвиговый регистр 74HC165(вариант для реального устройства);

Читать дальше

ATmega8 + Proteus: работа со сдвиговыми регистром 74HC595

разделы: AVR, SPI, Proteus, HD44780, дата: 26 сентября 2017г.

    Сдвиговые регистры, оглавление:
  1. ATmega8 + Proteus: работа со сдвиговыми регистром 74HC595
  2. ATmega8 + Proteus: входной сдвиговый регистр 74HC165, совместная работа с 74hc595
  3. ATmega8 + Arduino + Proteus: 8-битный сдвиговой регистр на I2C интерфейсе PCF8574

Изучение модуля USI MSP430 странным образом(на самом деле закономерным) вывела меня на такую штуку, как сдвиговый регистр. Имея о них лишь общее представление, мне пришлось срочно разбираться c этой, довольно обширной темой. Итак.

Сдвиговый регистр, он же расширитель портов, он же шинный преобразователь, преобразует сигнал последовательной шины в параллельный или/и обратно.

В рамках этой статью я рассмотрю работу с популярным 8-и битовыми сдвиговым регистром на SPI интерфейсе 74HC595.

В качестве практических примеров, я рассмотрю подключение светодиодной гирлянды, семисегментных индикаторов и дисплея с параллельной шиной HD44780.

В качестве микроконтроллера я буду использовать ATmega8, а в качестве среды моделирования Proteus 8.5.

Кроме этого, я затрону организацию SPI интерфейса у ATmega8.

    Оглавление:
  1. Сдвиговый регистр 74HC595 c SPI интерфейсом;
  2. Управление гирляндой светодиодов;
  3. SPI интерфейс в микроконтроллере ATmega8;
  4. Подключение семисегментного индикатора через сдвиговый регистр 74HC595;
  5. Подключение жидко-кристаллического дисплея HD44780 через сдвиговый регистр 74HC595;

Читать дальше

ATtiny13A: режимы энергосбережения, фьюзы и программный UART

разделы: AVR, ATtiny13A, дата: 10 апреля 2016г.

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

Первым делом мой взгляд упал на ATtiny13A. Небольшая микросхема, если логически подумать, должна потреблять минимум энергии. На практике однако, это зависит от используемого техпроцесса при изготовлении этой микросхемы.

Справедливости ради стоит заметить, что ATtiny13 с пониженным энергопотреблением имеют индекс V. А чипы с технологией picoPower, снабжаются индексом P. Что же до ATtiny13A, согласно документации, его потребление в обычном режиме, при питании 1.8V и частоте 1МГц - 160 микро ампер. В Idle режиме при тех же условиях - 24 микро ампер. Питание 1.8В я не собираюсь использовать, меня больше интересует потребление при 3.3В.

Мой мультиметр фирмы Mastech, модель: M830BZ. Это не весть что, но если измерять потребление различных чипов одним прибором, выводы сделать можно будет.

Для работы с режимами энергосбережения в avr-gcc есть библиотека avr/sleep.h. Переводной мануал по данной библиотеке можно почитать здесь. Я же пойду по традиционному пути ковыряния регистров.

В качестве исходного примера возьмем blink из старого поста:

Читать дальше

Отладка прошивки в Linux с помощью эмулятора SimulAVR и отладчика AVR-GDB. Чтение из Flash памяти AVR

разделы: AVR, дата: 20 марта 2016г.

Обычно, чем больше размер программы, тем чаще приходится пользоваться отладчиком. В AVR Studio встроен замечательный эмулятор микроконтроллеров, на котором можно проверить работоспособность прошивки, и можно порадоваться за Windows пользователей, но что делать пользователям Linux?

В Linux в качестве эмулятора может выступить SimulAVR, а отладчиком avr-gdb. Собственно, работе с этим отладчиком и посвящен этот пост, потому-что им же производится отладка по JTAG. Но, пока я JTAG не разжился, придется пользоваться эмулятором. SimulAVR поддерживает небольшой набор микроконтроллеров и к том уже не всю периферию он эмулирует, но таймеры и порты преимущественно работают.

При запуске SimulAVR без параметров отобразится справка по ключам и список поддерживаемых микроконтроллеров:
Supported devices: at90can128 at90can32 at90can64 at90s4433 at90s8515 atmega128 atmega1284 atmega1284a atmega16 atmega164 atmega164a atmega168 atmega32 atmega324 atmega324a atmega328 atmega48 atmega644 atmega644a atmega8 atmega88 attiny2313 attiny25 attiny45 attiny85

К сожалению XMega не поддерживается ;) поэтому тренироваться будем на ATmega8. Для работы с отладчиком нужно будет скомпилировать прошивку с опцией -ggdb и убрать оптимизацию кода опцией -O0.

SimulAVR и AVR-GDB работают по клиент-серверной архитектуре. Первый выступает в роли сервера, второй в роли клиента.

Для отладки возьмем такой пример:

Читать дальше

ATmega168: колесный энкодер на дополнительном внешнем прерывании

разделы: AVR, myRobot, дата: 11 марта 2016г.


колесо в сборе с двигателем постоянного тока, редуктором и диском энкодера

Дополнительные внешние прерывания, относительно новая штука в периферии AVR. В микроконтроллерах ATmega8/ATmega16 их нет, зато они есть в ATmega88/ATmega168. В официальной документации они описаны в главе 13 "Внешние прерывания". В отличии от обычных внешних прерываний, в дополнительных, одно прерывание отведено на один порт (т.е. на восемь пинов), и в них нельзя выставить условия срабатывания. Прерывание будет генерироваться при любом изменении сигнала, даже если он был изменен программно, самим микроконтроллером.

    Т.о. задача состоит в следующем. Дано одно прерывание, и на него подключено два энкодера. Нужно:
  • определить какой именно энкодер вызвал прерывание;
  • определить время прошедшее с предыдущего срабатывания энкодера, т.е. интервал;
  • обеспечить защиту от "дребезга"
    Рассмотрим матчасть:
  • Диск энкодера имеет двадцать прорезей. Следовательно, поворот на одно деление примерно равно ~0.1π
  • Диаметр колеса около 66мм. Окружность 20.5 см, т.е. поворот на одно деление диска, равно примерно 1см пройденного пути.

Читать дальше

ATmega168: подключение нескольких ультразвуковых сенсоров HC-SR04 используя аналоговый компаратор

разделы: AVR, HC-SR04, myRobot, дата: 6 марта 2016г.

Компаратор это единственная периферия в AVR которая включена по умолчанию. Поэтому, если он не используется, его следует выключать. Допустимая ошибка (напряжение смещения) не более 40мВ, время отклика не более 0,5 мкс. Рабочие пины: прямой AIN0 и инверсный AIN1. Так же AIN0 называют положительным, а AIN1 отрицательным. Результат заносится в ACO бит регистра ACSR.

Официальный datasheet на ATmega168: http://www.atmel.com/images/doc2545.pdf работа компаратора описана в главе 23.2 на странице 246

    Хорошие справочные обзоры по работе компаратора в AVR можно найти здесь:
  1. Учебный курс AVR. Аналоговый компаратор
  2. AVR. Учебный курс. Использование аналогового компаратора

Я потратил немного времени на перевод официального руководства, с которым и предлагаю далее ознакомится.

Описание регистра ACSR

Компаратор управляется через регистр "Analog comparator control and status register" т.е. ACSR:

Читать дальше