networking

i didnt have time to make my own circuit in fab lab so i started with arduino this week..

AGAIN???

  1. pulled the bus lines (sda , scl) to vcc (5v) through 10k resistors.

  2. the code:


#include <Wire.h>

char c = '1';

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  Wire.beginTransmission(10);
  Wire.write(c);
  if (c == '1') //BLINK THE c
    c= '0';
  else
    c= '1';
  Wire.endTransmission();
  delay(1000);
}
  

#include <Wire.h>

void setup() {
  pinMode(13,OUTPUT);
  Wire.begin(10); //i2c slave addr 10
  Wire.onReceive(rcvISR);
}

void loop() 
{
  /* NOTHING */
}

void rcvISR(int x)
{
  char c = Wire.read();
  Wire.flush();
  if (c == '1')
    digitalWrite(13,1);
  else
    digitalWrite(13,0);
}
  
  1. Result:

I2c driver implementation:

i want to implement i2c driver and understand how to do it with the microcontroller..

i was going to use I2C in Attiny44A but i didnt have it with me so i choose to go with atmega328 to understand how this peripheral works…

in atmega328, the TWI peripheral is standalone not like attiny44A where ATMEL combined two wire mode (TWI/I2C) with three wire mode (SPI) into one peripheral

26.3.3 Address Packet Format:

  • nine bits long
    • 7 address bits
    • 1 Read/Write control bit
    • 1 ACK bit (slave pull this line down)

registers:

  • TWBR - Two wire Baud Rate: in this register you select baud rate. its calculated with the following equation: F_CPU/(16+2*TWBR*4^TWPS)

where TWPS is prescaler that can be set in TWSR.

  • TWSR - Two wire Status resgister:

    • bits [0:1] -&gt prescaler
    • bits [3:7] -&gt Status bits
    • bit [2] -&gt reserved
  • TWAR - Two wire Address register: this bit you load it with the address of the slave (in slave mode) so when the master sends to the node it sends ACK and can respond…

  • TWDR - Two wire Data register: In Transmit mode, TWDR contains the next byte to be transmitted. In Receive mode, the TWDR contains the last byte received.

  • TWCR - Two wire Control resgister:

    • bit [7] TWINT TWI Interrupt Flag -&gt This bit is set by hardware when the TWI has finished its current job and expects application software response
    • bit [5] TWSTA TWI START Condition -&gt The application writes the TWSTA bit to one when it desires to become a master on the 2-wire serial bus
    • bit [4] TWSTO TWI STOP Condition -&gt Writing the TWSTO bit to one in Master mode will generate a STOP condition on the 2-wire serial bus
    • bit [2] TWEN TWI Enable -&gt enables TWI operation and activates the TWI interface. When TWEN is written to one, the TWI takes control over the I/O pins connected to the SCL and SDA pins.

code:

im using ATMEL STUDIO, after compiling im uploading with AVRDUDE


/*
    I2C master
    sends ‘1’ and ‘0’ to slave address 10
    and delay in-between (~1sec)
*/

#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>

int main(void)
{
    char c = '1';
    TWSR &= 0xF8; //set TWPS[1:0] to 0 -&gt 1 prescaler value
    TWBR = 0x30; //10khz @ 16mhz & 1 prescaler

    while (1) 
    {

        //start TWI:
        TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN); //set enable , reset int, set start
        while(!(TWCR & (1 << TWINT))); //wait for int flag
        if ( (TWSR & 0xf8) != TW_START)
            PORTB ^= 1 << PB5; //error dbg toggle led

        //send to address 10
        TWDR = 10  <<  1; //to send to addr 10 (address 7 bit mode + 0 write mode)
        TWCR = (1 <<  TWINT | 1 << TWEN); //start send
        while(!(TWCR & (1 << TWINT))); //wait for int flag
        if ((TWSR & 0xf8) != TW_MT_SLA_ACK ) 
            PORTB ^= 1 << PB5; //error dbg toggle led

        //send data (char c)
        TWDR = c;
        if (c == '1')
            c= '0';
        else
            c= '1';
        TWCR = (1 <<  TWINT | 1 << TWEN); //start send
        while(!(TWCR & (1 << TWINT))); //wait for int flag
        if ((TWSR & 0xf8) != TW_MT_DATA_ACK )
                PORTB ^= 1 << PB5; //error dbg toggle led


        //send stop condition
        TWCR = (1&lt &lt TWINT) | (1 &lt &ltTWEN) | (1  << TWSTO);
       for (int i=0; i<10; i++)
        _delay_ms(100);
    }

}

result is same as before… :)


references: