Связь AtTiny44 и AtTiny 85
Я работаю над проектом, в котором использую два микроконтроллера : AtTiny44 (внешняя тактовая частота 20 МГц) и AtTiny85 (внутренняя 8 МГц).
Я пытаюсь добиться связи I2C между 85 и 44, при этом 44 выступает в качестве ведущего, а 85 — в качестве подчиненного, а затем передаю данные, считанные с них обоих, на ПК по кабелю FDTI с использованием программного обеспеченияSerial. .
Я начал с написания кода AtTiny85:
#include <TinyWireS.h>
#define ADC3 A3
void setup() {
TinyWireS.begin(I2C_SLAVE_ADDRESS); // присоединяемся к сети i2c
TinyWireS.onRequest(requestEvent);
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
pinMode(ADC3,INPUT_PULLUP);
}
void loop() {
// Это должно быть здесь
TinyWireS_stop_check();
}
// Вызывается, когда ATtiny получает запрос i2c
void requestEvent() {
int val=analogRead(ADC3);
byte valLow = val & 0xff;
byte valHigh = (val >> 8);
TinyWireS.send(valHigh);
TinyWireS.send(valLow);
}
Благодаря этому я могу отправить данные, считанные с АЦП (контакт A3), на Arduino в виде 2 байтов
Код Arduino:
#include <Wire.h>
int check=0;
void setup() {
Wire.begin(); // подключаемся к шине i2c (адрес для ведущего необязателен)
Serial.begin(9600); // запускаем последовательный порт для вывода
}
void loop() {
Wire.requestFrom(8, 2); // запрос 2 байтов от ведомого устройства №8
while (Wire.available()&&check<2) { // ведомое устройство может отправить меньше, чем
// запрошено
int c = Wire.read(); // получаем байт как int
check++;
int d = Wire.read();
check++;
int number = d | c << 8; //конвертируем два байта как int
Serial.println(number);
}
check=0;
delay(500);
}
Возможно, переменная check
бесполезна, но это не проблема, потому что я получаю правильные показания на последовательном мониторе.
Затем я перешел на AtTiny44; У меня есть встроенный термистор, и мне нужно напечатать на программном обеспечении Serial значение, считанное с него, и значение, считанное с платы AtTiny85.
Это код с использованием TinyWireM:
#include <TinyWireM.h>
#include <USI_TWI_Master.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(0, 1); // прием, передача
int adc = 2;
int check=0;
void setup() {
pinMode(1, OUTPUT);
pinMode(0, INPUT);
pinMode(4,INPUT_PULLUP);
pinMode(6,INPUT_PULLUP);
pinMode(7, OUTPUT);
pinMode(adc, INPUT);
mySerial.begin(9600);
TinyWireM.begin(); // подключаемся к шине i2c (адрес для ведущего необязателен)
while (!mySerial) {
;
}
mySerial.println("Serial comm started");
digitalWrite(7, HIGH);
delay(1000);
digitalWrite(7, LOW);
}
void loop() {
mySerial.println((int)analogRead(adc));
TinyWireM.requestFrom(8, 2); // запрос 2 байтов от ведомого устройства №8
while (TinyWireM.available()&&check<2) { // ведомое устройство может отправить меньше, чем
// запрошено
digitalWrite(7, HIGH);
int c = TinyWireM.receive(); // получаем байт как символ
check++;
int d = TinyWireM.receive();
check++;
int number = d | c << 8;
mySerial.println(number);
}
check=0;
delay(500);
}
Программное обеспечениеSerial работает хорошо (я записываю данные АЦП из 44), но я не могу найти, где проблема в I2C (на мониторе консоли отправляет mySerial.println(number)
) выход 0).
Что я пока исключил: ошибку подключения, перекос часов (часы разнесены между собой), подтягивание на шине I2c (они высокие в обоих устройствах)
@Ghesio, 👍-1
Обсуждение1 ответ
85 как раб
написание подчиненного устройства, особенно подчиненного устройства i2c, — занятие не для слабонервных. Обычно для этого используется конечный автомат.
Один из замечательных примеров представлен nxp в старом техническом описании LPC210x. AVR используют то же самое оборудование i2c, поэтому оно чрезвычайно переносимо на avr.
Я знаю, но самое смешное, что не работает именно мастер attiny44!, @Ghesio
- Digispark Rev. 3 Kickstarter ATtiny85 использует все 6 контактов
- ATtiny85 со сном и последовательным портом
- Используйте ATtiny85 для выполнения начальной настройки маршрутизатора Cisco с использованием его консольного порта USB.
- Целесообразно ли использовать Serial.write в ISR, когда loop() обычно использует Serial.read?
- Каково время выхода из Wire.begin()?
- AT-команда не отвечает на последовательный монитор
- Связь последовательного порта Digispark
- Как отправить команду AT на sim800l с помощью SoftwareSerial
Зачем использовать I2C? Может быть, другие протоколы могут быть быстрее/проще/меньше контактов для этого использования?, @bigjosh
Я не думаю, что существует более простой протокол или с меньшим количеством выводов. Я думал использовать два последовательных программного обеспечения, но они не могут работать вместе одновременно., @Ghesio
Вам кажется, что скорость передачи данных довольно низкая, и, возможно, вам нужно отправлять только в одном направлении по каналу между двумя устройствами? Если да, то, возможно, только один сигнальный провод и земля между ними. Отправитель подает на провод высокий уровень на 1 мс, чтобы сигнализировать «0», и на 2 мс, чтобы сигнализировать «1». Действительно простой последовательный порт., @bigjosh
Да, мне нужно отправить данные только одним способом. Я хотел бы использовать I2C, но меня интересует ваш обходной путь. Можете ли вы указать мне на некоторые подсказки? Кроме того, как я могу управлять запросом данных от ведущего устройства к ведомому устройству в вашем решении?, @Ghesio
Вам нужен главный запрос? Почему бы просто не заставить раба всегда отправлять сообщения вслепую?, @bigjosh
Он также мог бы отправлять вслепую, но как я могу управлять временем между программным последовательным портом и последовательным битом?, @Ghesio
На микросхеме, подключенной к FDTI, выполните смену контактов ISR для пиуна, который подключен к линии передачи данных, идущей от пульта дистанционного управления. Каждый раз, когда уровень сигнала меняется с низкого на высокий, сохраняйте текущее время. Каждый раз, когда оно меняется с высокого на низкое, обратите внимание на разницу между текущим временем и сохраненным временем. Если время ~1 секунда, то получен 0 бит, если время ~2 секунды, то получен 1 бит. переместите их в переменную хранения, пока у вас не будет байта данных. Когда все заработает, вы сможете работать намного быстрее, но отладку с помощью светодиода можно выполнить за 1–2 секунды., @bigjosh
Возможно, ATtiny85 не может справиться с тактовой частотой I2C, генерируемой AtTiny44. Попробуйте запустить их оба на одинаковой тактовой частоте., @Jeff Wahaus