Você está na página 1de 10

AVR I2C bus ?

I2C (read as I Squared C) bus Philips 1980 .



I2C bus- IC- .
I2C bus clock, 2
. I2C 128
. I2C
IC- Serial EEPROM,
I/O Expander, Real-Time Clock, Digital to Analog Converter, Analog to Digital Converter,
Temperature Sensor .
I2C master, slave 2 . Master
. Serial
EEPROM, I/O Expander .
I2C bus- SDA (serial data)
. SCL (serial clock)
slave 7
.

7 4- 3-
. 24AA128 I2C CMOS serial EEPROM 4
1010 3- A0,
A1, A2 serial EEPROM- .

I2C- Microchip MCP23008 8-bit I/O Expander, Dalas


DS1307 Real Time Clock serial EEPROM- .
master I2C bus-
slave . I2C bus
master, slave- .
, I2C
.
ATMega32 Microchip 24AA128 I2C
serial EEPROM - EEPROM
PORTD
.
#include
#include
#include
#include

<avr/io.h>
<util/delay.h>
<compat/twi.h>
"adcA.h"

#define MAX_TRIES 50
#define EEPROM_ID
0xA0
// I2C 24AA128 EEPROM Device Identifier
#define EEPROM_ADDR 0x00
// I2C 24AA128 EEPROM Device Address
#define I2C_START 0
#define I2C_DATA 1
#define I2C_STOP 2
unsigned char i2c_transmit(unsigned char type) {
switch(type) {
case I2C_START:
// Send Start Condition
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
break;
case I2C_DATA:
// Send Data

TWCR = (1 << TWINT) | (1 << TWEN);


break;
case I2C_STOP:
// Send Stop Condition
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
return 0;
}
// Wait for TWINT flag set in TWCR Register
while (!(TWCR & (1 << TWINT)));
// Return TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
return (TWSR & 0xF8);
}
int i2c_writebyte(unsigned int i2c_address, unsigned int dev_id,
unsigned int dev_addr,char data) {
unsigned char n = 0;
unsigned char twi_status;
char r_val = -1;
i2c_retry:
if (n++ >= MAX_TRIES) return r_val;
// Transmit Start Condition
twi_status=i2c_transmit(I2C_START);
// Check the TWI Status
if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;
// Send slave address (SLA_W)
TWDR = (dev_id & 0xF0) | (dev_addr & 0x07) | TW_WRITE;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if ((twi_status == TW_MT_SLA_NACK) || (twi_status == TW_MT_ARB_LOST)) goto
i2c_retry;
if (twi_status != TW_MT_SLA_ACK) goto i2c_quit;
// Send the Low 8-bit of I2C Address
TWDR = i2c_address;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;
// Send the High 8-bit of I2C Address
TWDR = i2c_address >> 8;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;
// Put data into data register and start transmission
TWDR = data;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;
// TWI Transmit Ok
r_val=1;
i2c_quit:
// Transmit I2C Data
twi_status=i2c_transmit(I2C_STOP);
return r_val;
}
int i2c_readbyte(unsigned int i2c_address, unsigned int dev_id,
unsigned int dev_addr, char *data)
{
unsigned char n = 0;
unsigned char twi_status;
char r_val = -1;
i2c_retry:
if (n++ >= MAX_TRIES) return r_val;
// Transmit Start Condition
twi_status=i2c_transmit(I2C_START);

// Check the TWSR status


if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;
// Send slave address (SLA_W) 0xa0
TWDR = (dev_id & 0xF0) | ((dev_addr << 1) & 0x0E) | TW_WRITE;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if ((twi_status == TW_MT_SLA_NACK) || (twi_status == TW_MT_ARB_LOST)) goto
i2c_retry;
if (twi_status != TW_MT_SLA_ACK) goto i2c_quit;
// Send the Low 8-bit of I2C Address
TWDR = i2c_address;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;
// Send the High 8-bit of I2C Address
TWDR = i2c_address >> 8;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;
// Send start Condition
twi_status=i2c_transmit(I2C_START);
// Check the TWSR status
if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;
// Send slave address (SLA_R)
TWDR = (dev_id & 0xF0) | ((dev_addr << 1) & 0x0E) | TW_READ;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if ((twi_status == TW_MR_SLA_NACK) || (twi_status == TW_MR_ARB_LOST)) goto
i2c_retry;
if (twi_status != TW_MR_SLA_ACK) goto i2c_quit;
// Read I2C Data
twi_status=i2c_transmit(I2C_DATA);
if (twi_status != TW_MR_DATA_NACK) goto i2c_quit;
// Get the Data
*data=TWDR;
r_val=1;
i2c_quit:
// Send Stop Condition
twi_status=i2c_transmit(I2C_STOP);
return r_val;
}
int main(void)
{
char buffer[34]= {0b00001111,
0b11110000,
0b00000001,
0b00000011,
0b00000110,
0b00001100,
0b00011001,
0b00110011,
0b01100110,
0b11001100,
0b10011000,
0b00110000,
0b01100000,
0b11000000,
0b10000000,
0b00000000,
0b00000000,

0b00000000,
0b10000000,
0b11000000,
0b01100000,
0b00110000,
0b10011000,
0b11001100,
0b01100110,
0b00110011,
0b00011001,
0b00001100,
0b00000110,
0b00000011,
0b00000001,
0b00000000,
0b00000000,
0b00000000,
};
char data,id1,id2;
unsigned int dev_address,i,idelay;
DDRD=0xFF;
PORTD=0x00;
/* Initial ADC
InitADC();

// Set PORTD as Output


// Set All PORTD to Low
*/

TWSR = 0x00;
// Select Prescaler of 1
// SCL frequency = 11059200 / (16 + 2 * 48 * 1) = 98.743 khz
TWBR = 0x30;
// 48 Decimal
// Read the EEPROM ID
dev_address=0;
// Start at Address 0
i2c_readbyte(dev_address,EEPROM_ID,EEPROM_ADDR,&id1);
i2c_readbyte(dev_address + 1,EEPROM_ID,EEPROM_ADDR,&id2);
// Write to EEPROM if no ID defined
if (id1 != buffer[0] || id2 != buffer[1]) {
for(i=0;i < 34;i++) {
i2c_writebyte(dev_address + i,EEPROM_ID,EEPROM_ADDR,buffer[i]);
_delay_us(1);
}
}
// Initial Delay Value
idelay=100;
for(;;) {
for(i=2;i < 34;i++)
{
idelay = ReadADC(0);
// Read the EEPROM
i2c_readbyte(dev_address + i,EEPROM_ID,EEPROM_ADDR,&data);
// Put data to the PORTD
PORTD=data;
_delay_ms(idelay);
// Delay
}
}

return 0;
}

C
Atmega32 ADC, TWI (two wire interfaces)
. TWI Atmel I2C-bus .
EEPROM-
(0b00001111 and 0b1111000)
ADC- ms EEPROM
.
:

i2c_writebyte() 8-
.
i2c_readbyte() 8- I2C
.
i2c_transmit() .

I2C Bus (SCL)


I2C-bus 2
.
I2C (SCL)
(SDA) 8- .

I2C- TWI status register (TWSR) TWI Bit Rate


Generator register (TWBR) 2 .

I2C SCL 100 kHz


. I2C Microchip 24AA128
serial EEPROM 400 kHz .
:

TWSR TWPS1 = 0, TWPS0 = 0


( 1); TWBR 48 ( 30
hexadecimal) 4MHz
SCL Frequency = CPU Clock / ((16 + 2(TWBR) x (Prescaler Value))
SCL Frequency = 4000000 / (16 + 2 x 48) = 98.743 kHz
C
/* Initial TWI Peripheral */
TWSR = 0x00;
// Select Prescaler of 1
// SCL frequency = 11059200 / (16 + 2 * 48 * 1) = 35.398 Khz
TWBR = 0x30;
// 48 Decimal

I2C (SDA) ,
I2C .
Atmel AVR I2C-bus
TWI .
TWI . I2C

.


. START condition. AVR TWI
.

TWCR TWINT=1 (interrupt flag bit), TWSTA=1 (start condition bit),


TWEN=1 (enable TWI bit) . I2C
. TWI .
TWCR TWINT 1 .
// Transmit Start Condition
twi_status=i2c_transmit(I2C_START);

C i2c_transmit() I2C_START .
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
// Wait for TWINT=1 in the TWCR Register
while (!(TWCR & (1 << TWINT)));
// Return TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
return (TWSR & 0xF8);

TWI .
TWINT=1 (logical 1)
interrupt flag 1 ?; TWI
0
.
i2c_transmit()
TWSR TWPS1, TWPS0
.TWSR compat/twi.h
.
// Check the TWI Status
if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;

if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto


i2c_quit;

I2C .
slave . (4 ID, 3 )
// Send slave address (SLA_W)
TWDR = (dev_id & 0xF0) | (dev_addr & 0x07) | TW_WRITE;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if ((twi_status == TW_MT_SLA_NACK) || (twi_status == TW_MT_ARB_LOST)) goto
i2c_retry;
if (twi_status != TW_MT_SLA_ACK) goto i2c_quit;

slave TWDR i2c_transmit() .


I2C_DATA
.
.
// Send Stop Condition
twi_status=i2c_transmit(I2C_STOP);

The whole I2C-bus write operation C program is implemented in the i2c_writebyte()


function.
I2C (SDA) ,
.


// Send slave address (SLA_R)
TWDR = (dev_id & 0xF0) | ((dev_addr << 1) & 0x0E) | TW_READ;
// Transmit I2C Data
twi_status=i2c_transmit(I2C_DATA);
// Check the TWSR status
if ((twi_status == TW_MR_SLA_NACK) || (twi_status == TW_MR_ARB_LOST)) goto
i2c_retry;
if (twi_status != TW_MR_SLA_ACK) goto i2c_quit;

// Read I2C Data


twi_status=i2c_transmit(I2C_DATA);
if (twi_status != TW_MR_DATA_NACK) goto i2c_quit;
// Get the Data
*data=TWDR;

#define DEVICE_ID
0xA0
// I2C 24AA128 EEPROM Device Identifier
#define DEVICE_ADDR 0x00
// I2C 24AA128 EEPROM Device Address
#define DEVICE_REGISTER
0x00
// I2C Device Register
...
...
...
// I2C Device Write
i2c_writebyte(DEVICE_REGISTER,DEVICE_ID,DEVICE_ADDR,buffer[i]);
...
...
// I2C Device Read
i2c_readbyte(DEVICE_REGISTER,DEVICE_ID,DEVICE_ADDR,&data);

Você também pode gostar