Введите текст заголовка

В данном уроке мы настроим микроконтроллер Atmega8 в качестве Slave для шины I2C(TWI), а так же плату Arduino Nano  в качестве Master шины I2C.

Для начала займемся микроконтроллером Atmega8.

Для настройки шины I2С  нам понадобится  регистр TWCR:

******************

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

TWEA — Enable ACK. Разрешение ответа ACK. Если его включить, то автомат TWI будет отзываться на свой адрес, а также давать ACK во всех случаях когда этого требует протокол. Скажем, после прием байта. Если нам надо послать NACK то бит не ставим.

TWSTA — Сформировать старт. Причем не факт, что прямо сейчас. От текущего состояния зависит. Например, если этот бит поставить в 0х38 состоянии, то старт будет сформирован когда шина освободится. Контроллер TWI умный и сам все хорошо знает.

TWSTO — сделать Stop. Опять же аналогично. После записи в этот бит модуль отваливается от сессии передачи. МК становится неадресованным ведомым.

TWWC — конфликт записи. Сигнализирует о том, что кто то из прикладной программы записал в TWDR данные. Тогда как в TWDR полагается писать только при поднятом TWINT (в нашем случае это будет толкьо в обработчике прерывания).

TWEN — блок TWI включен. Только и всего.

TWIE — прерывания от TWI разрешены.

Подчиненный:

#include <Wire.h>

#define GPIO0 2
#define GPIO1 3

#define GPIO11 11
#define GPIO12 12

int i =0;
int out[8]={0,0,0,0,0,0,0,0};

void setup() {
Wire.begin(10); /* задаем на шине i2c 10 адрес */
Wire.onReceive(receiveEvent); /* регистрируем полученное событие */
Wire.onRequest(requestEvent); /* регистрируем запрошенное событие */
Serial.begin(9600); /* открываем серийный порт для дебаггинга */

pinMode(GPIO0, OUTPUT);
pinMode(GPIO1, OUTPUT);

pinMode(GPIO11, INPUT);
digitalWrite(GPIO11, HIGH);
pinMode(GPIO12, INPUT);
digitalWrite(GPIO12, HIGH);

}

void loop() {
delay(100);
}

// Функция для извлечения любых принимаемых данных от мастера на шину
void receiveEvent(int howMany) {
i=0;
while (0 <Wire.available()) {
out[i] = Wire.read(); /* получаем байт как число*/

switch (i){
case 0:
{
if (out[0]==1) digitalWrite(GPIO0, HIGH);
else digitalWrite(GPIO0, LOW);
}
break;
case 1:
{
if (out[1]==1) digitalWrite(GPIO1, HIGH);
else digitalWrite(GPIO1, LOW);
}
break;
case 2:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
case 3:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
case 4:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
case 5:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
case 6:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
case 7:
{
if (out[i]==1) out[i]=1;
else out[i]=0;
}
break;
}
Serial.print(out[i]); /* выводим символ в серийный порт */
i++;
}
Serial.println(); /* переходим на новую строку */

}

// Отправляем данные на мастер.
void requestEvent() {
Wire.write(digitalRead(GPIO0));
Wire.write(digitalRead(GPIO1));
Wire.write(1);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(1);
Wire.write(0);
Wire.write(digitalRead(GPIO11));
Wire.write(digitalRead(GPIO12));
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.write(1);
Wire.write(1);
Wire.write(1);
}

Мастер:
#include <Wire.h>
int c[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i=0;
int m=0;

void setup() {
Serial.begin(9600); /* открываем серийный порт для дебаггинга */
Wire.begin(D1, D2); /* задаем i2c мост через контакты SDA=D1 и SCL=D2 на NodeMCU */
}

void loop() {
if (m==0)
{
Wire.beginTransmission(10); /* Начинаем передачу на адресе 10 */
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.endTransmission(); /* прекращаем передачу */
delay(1000);

Wire.requestFrom(10, 16); /* запрашиваем и считываем данные с 10 и 8 адреса slave устройства */
i=0;
while(Wire.available()){
c[i] = Wire.read();
Serial.print(«c[«);
Serial.print(i);
Serial.print(«]»);
Serial.print(c[i]);
Serial.println();
i++;
}
Serial.println();
delay(1000);
m=1;
}
if(m==1)
{
Wire.beginTransmission(10); /* Начинаем передачу на адресе 10 */
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.write(0);
Wire.write(1);
Wire.endTransmission(); /* прекращаем передачу */
delay(1000);

Wire.requestFrom(10, 16); /* запрашиваем и считываем данные с 10 и 8 адреса slave устройства */
i=0;
while(Wire.available()){
c[i] = Wire.read();
Serial.print(«c[«);
Serial.print(i);
Serial.print(«]»);
Serial.print(c[i]);
Serial.println();
i++;
}
Serial.println();
delay(1000);
m=0;
}
}