Attiny85, I2C и расширитель портов PCF8574
- Войдите на сайт для отправки комментариев
Всем привет! Делаю небольшое устройство на Attiny85. К МК нужно подключить 6 расширителей портов PCF8574.
Для работы с PCF8574 я установил библиотеку A85_PCF8574: https://github.com/debsahu/A85_PCF8574
Так же я установил зависимую библиотеку TinyWireM: https://github.com/adafruit/TinyWireM
Ядер для Attiny85 есть очень много... вот список: https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls
Я установил 2 ядра:
ATtiny: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
ATFlash: https://mesom.de/atflash/package_atflash_index.json
Накидал простой пример:
#include <A85_PCF8574.h> // SDA - P0 - 0 // CLK - P2 - 2 #define PCF8574_ADDRESS (0x20) A85_PCF8574 myPCF8574; void setup() { myPCF8574.begin(PCF8574_ADDRESS); } void loop() { myPCF8574.setBit(0, 0); _delay_ms(1000); myPCF8574.setBit(0, 1); _delay_ms(1000); }
По сути это простой "Блинк" на пине P0 PCF8574. Компилирую в Ардуино ИДЕ, прошиваю через USBASP.
Настройки Ардуино: Attiny85, Clock: internal 8 Mhz
Фьюзы установлены следующие: High:0xDF; Low: 0xE2
у Attiny85 никакой обвязки нет кроме питания и подключенной PCF8574.
Но не работает. Пробовал оба ядра - результата нет. Посмотрел осциллографом - Сигнал на линиях SDA и SCL отсутствует.
Распаковал новый МК, прошил - то же самое. При этом если прошить обычный Блинк и подключить светодиод к МК то работает, светодиод мигает. Немного модифицировал пример:
#include <A85_PCF8574.h> // SDA - P0 - 0 // CLK - P2 - 2 #define PCF8574_ADDRESS (0x20) A85_PCF8574 myPCF8574; void setup() { myPCF8574.begin(PCF8574_ADDRESS); pinMode(1, OUTPUT); } void loop() { myPCF8574.setBit(0, 0); digitalWrite(1, HIGH); // turn the LED on (HIGH is the voltage level) _delay_ms(1000); myPCF8574.setBit(0, 1); digitalWrite(1, LOW); // turn the LED off by making the voltage LOW _delay_ms(1000); }
На пине PB1 есть "мигание", а на пинах PB0 и PB2 (SDA и SCL) - тишина... Можете подсказать что я не так делаю? Почему не работает? Как это можно исправить?
где у тебя SoftWire инициализируется? Вот это вот хде?
TinyWireM.begin()
Добавлю еще: Может есть способ для подключения "стандартных" библиотек? Так как много раз натыкался на подобные статьи: https://create.arduino.cc/projecthub/Samhain/pcf8574-expander-with-4-inputs-4-outputs-9a80ef
Где нет использования специализированных библиотек, но увы, нет и описания что за ядро используется, какие именно библиотеки используются и т.д.
А если использовать код "как есть", то получаю много ошибок (ВНИМАНИЕ! большой спойлер!):
DetSimen, инициализируется в самой библиотеке A85_PCF8574. Если заглянуть в функцию myPCF8574.begin то там есть инициализация TinyWireM. И да, я пробоал выносить инициализацию в основной код:
Но результат тот же.
Попробуй ядро для Тинек от Spence Konde.
"I2C support
On the following chips, I2C functionality can be achieved with the hardware USI. As of version 1.1.3 this is handled transparently via the special version of the Wire library included with this core. Be aware that USI-based I2C is not available when USI-based SPI is in use.
Программный I2C те ещё грабли.
Риск попалить порты высокий.
Может уже ?
Всем привет! Делаю небольшое устройство на Attiny85. К МК нужно подключить 6 расширителей портов PCF8574.
каждый расширитель PCF8574. - это 8 GPIO. То есть на "небольшом устройстве" ТС хочет адресовать 48 портов... на тиньке?
"Скажите, а вас уже выпустили из сумасшедшего дома?" (с)
Все еще хуже чем вы думаете :))))))
К тиньке будет подключено 6 плат, на каждой по PCF8574, а к каждой PCF8574 подключена матрица из 32 светодиодов (матрица 4х4, светодиоды соединены встречно - параллельно). так что управлять 192 светодиодами..... Одновременно будут работать не больше 30 светодиодов. Двух буферов в 4-5 бай каждый должно хватить. А сам код не большой.
Друзья, проблему решил. Я просто забыл о подтягивающих резисторах на линии I2C. Поставил два резистора к "+" питания, и все заработало. Перепроверил разные примеры и разные ядра - все работает!
Поставить токоограничивающие резисторы в линии и всех делов. Все равно на софт I2C большой скорости не получишь.
Поставить токоограничивающие резисторы в линии и всех делов. Все равно на софт I2C большой скорости не получишь.
Об этом думают обычно тогда, когда уже поздно
Все равно на софт I2C большой скорости не получишь.
Какой например ? Стандартные 400000 при 16 МГц легко получаются !
Все равно на софт I2C большой скорости не получишь.
Какой например ? Стандартные 400000 при 16 МГц легко получаются !
Я лично не тестировал, но насколько я помню из прочитанного, реальная максимальноя скорость софт I2C около 100КГц. Но дело даже не в этом. Для предохранения входов/выходов в линии надо ставить резисторы в районе 100ом. Это приводит к затягиванию фронтов. И в итоге, скажем, на 1МГц уже, скорее всего, работать не будет. А для 100КГц и, возможно, и для 400КГц это проблем не должно вызывать.
Риск подпалить порты есть при любой операции с кривыми руками. Программный i2c в этом никак не выделяется.
Риск подпалить порты есть при любой операции с кривыми руками. Программный i2c в этом никак не выделяется.
Объясните ваше утверждение... Я за I2C связь между устройствами , питающимися одним напряжением и подключенными правильно.Насколько кривые нужны руки. Приведите пример . Я хочу повторить и спалить порты своего МК.
Объясните ваше утверждение... Я за I2C связь между устройствами , питающимися одним напряжением и подключенными правильно.Насколько кривые нужны руки. Приведите пример . Я хочу повторить и спалить порты своего МК.
При аппаратном I2C порты не спалить если только кривыми руками не устроить КЗ. А вот при софтверном можно если со сторны МК, по ошибке, выставить в линию HIGH .
выставить в линию HIGH .
Понятно, что в библиотеке этого не делается. Но юзер может и в сетапе напортачить или где еще. Плюс всегда есть вероятность багов.
Ох, что-то мне не верится. Можно примерчик скетча, например обмена с внешним EEPROM? Осциллограф есть - померяю сколько там на самом деле.
А самому че? не дается такой сложный код ;)
функции SDA_... SCL_... расписать или осилишь? там просто переключение порта на вывод и ввод записью напрямую в DDR. А WITE_HIGHT_SDA() можешь убирать, это ожидание АСК от приемника, код выдрал из поддержки 24C512, ей нужно это. Оно не всем устройствам нужно, для SSD1306 нет. asm volatile ("nop"); - тоже можешь убрать если на предельное быстродействие хочешь тестить, это тоже от 24C512.
Все эти кучи вызовов функций - это куча тактов на вход/выход и сохранение переменных в стеке...
Если функции inline, то оверхеда быть не должно.
Разумеется. Только компиляторы нынче шибко умные, они и без указания inline делают его. Как впрочем могут и не сделать при явно указанном inline.
Сдается мне что я знаю причины сомнения. Смотрим на код if (v & 0x80) ..... v <<=1; Иногда народ реализует это так if (v & (1<<n)) .....; где n от 7 до 0. Но в системе кодов проца нет команды сдвига на произвольное кол-во бит. Потому 1<<n компилится в цикл. А это дико тормозит. Вот и думают гадости о софтовом i2c.
Меня вообще забавляет, когда в любительской разработке начинают такты считать. Сидят такие два человека с разными настройками компилятора (или вообще версиями) и спорят за быстродействие или степень оптимизации.
Там где речь о тактах - нужен ассемблер http://arduino.ru/forum/programmirovanie/assembler-i-sreda-razrabotki-arduino#comment-540650
ASM - это уже из другой оперы, не про ардуину. Этак можно сразу в шестнадцатеричных кодах лупить и публиковать в 7-м номере журнала "Радио".
А самому че? не дается такой сложный код ;)
функции SDA_... SCL_... расписать или осилишь? там просто переключение порта на вывод и ввод записью напрямую в DDR. А WITE_HIGHT_SDA() можешь убирать, это ожидание АСК от приемника, код выдрал из поддержки 24C512, ей нужно это. Оно не всем устройствам нужно, для SSD1306 нет. asm volatile ("nop"); - тоже можешь убрать если на предельное быстродействие хочешь тестить, это тоже от 24C512
Вообще-то у ТС речь шла о библиотеке TinyWireM и вот смотрю я код для i2C (https://github.com/adafruit/TinyWireM/blob/master/USI_TWI_Master.cpp) и не верю что он даст даже 400КГц.
У тебя есть готовая библиотека или ссылка на чужую котороя работает быстрее? Поделись. А писать на ассемблере для каждого конкретного I2C устройства? Ну может и вытянет килогерц 600, но это для avrfreaks а не для ардуиновского форума.