События‎ > ‎

Соединение двух mbed через I2C

Отправлено 20 июл. 2013 г., 11:22 пользователем Олег Евсегнеев   [ обновлено 20 июл. 2013 г., 11:23 ]
Итак, разработка квадрокоптера снова перешла в активную фазу. Согласно новой концепции, управлять машиной будут сразу два mbed контроллера. Первый из них должен работать с радиопередатчиком, GPS и с прочими медленными устройствам. Второй же будет осуществлять стабилизацию и маневрирование.

Понятное дело, что оба контроллера должны как-то общаться между собой. Mbed имеет множество интерфейсов на борту: UART, SPI, I2C, CAN. В принципе, для связи двух контроллеров можно использовать любой из них. Я же, без определенных причини, решил остановиться на шине I2C. 

Соединение

Подключение по I2C сродни UART - используются только две линии. Соединяем линии SCL и SDA на обоих устройствах.
Согласно спецификации интерфейса I2C, обе линии нужно потянуть к питанию +3.3В (через резисторы 2.2кОм). В противном случае интерфейс просто не будет работать.

Программа

В тестовой программе, один из контроллеров (ведущий) передает на второй (ведомый) строку "ping". Второй же, в ответ отправляет строку "pong". Для индикации процесса, оба контроллера пишут тексты в консоль и мигают светодиодами (LED1).

Код ведущего

I2C Master

#include "mbed.h"

DigitalOut led1 (LED1);
I2C i2c( p28, p27 );
Serial pc(USBTX, USBRX);

Timeout t1;

void t1out(void) { led1 = 0; }
void blip1(void) { led1 = 1; t1.attach(&t1out, 0.01); }

int main() {
    char msg[10];
    int x;
    int idx = 0;

    pc.printf("Start Master\r\n");

    while(1) {
        pc.printf(">>ping %d\r\n", idx);
        sprintf(msg, "ping");
        x = i2c.write( 0xA0, msg, strlen(msg) + 1);
        blip1();
        i2c.read( 0xA0, msg, 10);
        pc.printf("<<%s\r\n", msg);
        idx ++;
        wait(1.0);
    }
}

Код ведомого

I2C Slave

#include "mbed.h"
 
DigitalOut led1 (LED1);
I2CSlave slave(p28, p27);
Serial pc(USBTX, USBRX);

Timeout t1;

void t1out(void) { led1 = 0; }
void blip1(void) { led1 = 1; t1.attach(&t1out, 0.01); }

int main() {
    char buf[10];
    char msg[16];
    int idx = 0;
     
    pc.printf("Start Slave\r\n");
     
    slave.address(0xA0);
     
    while (1) {
        int i = slave.receive();
        switch (i) {
            case I2CSlave::ReadAddressed:
                pc.printf(">>pong %d\r\n", idx);            
                sprintf (msg, "pong");
                slave.write(msg, strlen(msg) + 1);
                idx ++;
                break;

            case I2CSlave::WriteAddressed:
                slave.read(buf, 10);
                blip1();
                pc.printf("<<%s\r\n", buf);
                break;
        }
        for(int i = 0; i < 10; i++) {
            buf[i] = 0;
        }
    }
}

Comments