I2CSLAVE

Top  Previous  Next

The I2C-Slave library is intended to create I2C slave chips. This is an add-on library that is not included by default. It is a commercial add on library. It is available from MCS Electronics

 

All BASCOM I2C routines are master I2C routines. The AVR is a fast chip and allows to implement the I2C slave protocol.

 

You can control the chips with the BASCOM I2C statements like I2CINIT, I2CSEND, I2CRECEIVE, I2CWBYTE, etc. Please consult the BASCOM Help file for using I2C in master mode.

 

 

Before you begin

Copy the i2cslave.lib and i2cslave.lbx files into the BASCOM-AVR\LIB directory.

The i2cslave.lib file contains the ASM source. The i2cslave.lbx file contains the compiled ASM source.

 

 

Slave address

Every I2C device must have an address so it can be addressed by the master I2C routines.

When you write to an I2C-slave chip the least significant bit (bit0) is used to specify if we want to read from the chip or that we want to write to the chip.

When you specify the slave address, do not use bit 0 in the address!

 

 

For example a PCF8574 has address &H40. To write to the chip use &H40, to read from the chip, use &H41. When emulating a PCF8574 we would specify address &H40.

 

 

Use the CONFIG statement to specify the slave address:

 

Config I2cslave = &B01000000 ' same as &H40

Optional use : CONFIG I2CSLAVE = address, INT= int , TIMER = tmr

 

Where INT is INT0, INT1 etc. and TIMER is TIMER0, TIMER1 etc.

When using other interrupts or timers, you need to change the library source. The library was written for TIMER0 and INT0.

 

The I2C slave routines use the TIMER0 and INT0. You can not use these interrupts yourself. It also means that the SCL and SDA pins are fixed.

 

The following table lists the pins for the various chips

Chip

SCL

SDA

AT90S1200

PORTD.4

PORTD.2

AT90S2313

PORTD.4

PORTD.2

AT90S2323

PORTB.2

PORTB.1

AT90S2333

PORTD.4

PORTD.2

AT90S2343

PORTB.2

PORTB.1

AT90S4433

PORTD.4

PORTD.2

ATTINY22

PORTB.2

PORTB.1

ATTINY13

PORTB.2

PORTB.1

ATTINY2313

PORTD.4

PORTD.2

ATMEGA1280

PORTD.7

PORTD.0

ATMEGA128CAN

PORTD.7

PORTD.0

ATMEGA168

PORTD.4

PORTD.2

ATMEGA2560

PORTD.7

PORTD.0

ATMEGA2561

PORTD.7

PORTD.0

ATMEGA48

PORTD.4

PORTD.2

ATMEGA88

PORTD.4

PORTD.2

ATMEGA8

PORTD.4

PORTD.2

 

 

 

 

Note that new AVR chips have a TWI or hardware I2C implementation. It is better to use hardware I2C, then the software I2C. The slave library is intended for AVR chips that do not have hardware I2C.

 

CONFIG I2CSLAVE will enable the global interrupts.

 

After you have configured the slave address, you can insert your code.

 

A do-loop would be best:

 

Do

' your code here

Loop

 

This is a simple never-ending loop. You can use a GOTO with a label or a While Wend loop too but ensure that the program will never end.

After your main program you need to insert two labels with a return:

 

When the master needs to read a byte, the following label is always called.

You must put the data you want to send to the master in variable _a1 which is register R16

 

I2c_master_needs_data:

'when your code is short, you need to put in a waitms statement

'Take in mind that during this routine, a wait state is active and the master will wait

'After the return, the waitstate is ended

Config Portb = Input ' make it an input

 

_a1 = Pinb ' Get input from portB and assign it

Return

 

When the master writes a byte, the following label is always called.

It is your task to retrieve variable _A1 and do something with it

_A1 is register R16 that could be destroyed/altered by BASIC statements

For that reason it is important that you first save this variable.

 

I2c_master_has_data:

'when your code is short, you need to put in a waitms statement

'Take in mind that during this routine, a wait state is active and the master will wait

'After the return, the waitstate is ended

 

Bfake = _a1                   ' this is not needed but it shows how you can store _A1 in a byte

'after you have stored the received data into bFake, you can alter R16

Config Portb = Output      ' make it an output since it could be an input

Portb = _a1                    'assign _A1 (R16)

Return