PEARSON CONSULTING | SOFTWARE | SERVICES | PROJECTS | IDEAS | ABOUT |
A1. Hardware support (TWI)
B3. Single Write and Read function
This project provides a minimal I2C Slave that can be used with an Arduino
or other board that can act as an I2C Master.
The four wire interface provides VCC, GND, SCL, and SDA signals. Since VCC is
supplied by the Master board, this design is compatible with 5v and 3.3v
systems provided that the AVR chip supports the voltage level. (2.7v-5.0v) or
(1.8v-5.0v).
The software is designed to run with a Slave using an 8 MHz CPU clock (uncheck
the CKDIV8 fuse when programming). No adjustment is needed to support the
Master provided 100 kHz or 400 kHz SCL clock speeds. However, if a different
CPU clock is used, it must be at least 16 times the SCL clock.
The software is compatible with Atmel Studio 6.2 and is written in 'C'.
Components for a basic A1+B3 Slave device to receive a command and send back data using an ATmega44/88/168/328, ATmega164/324/644/1284, or any AVR with a TWI hardware section.
Schematic A1B3 | Bread Board A1B3 |
Parts List
1 | Protoboard |
1 | AVR microcontroller (example Atmega88A) |
1 | 10uF electrolytic capacitor (optional for power filtering) |
2 | 6.8k ohm 1/4 watt resistor |
4 | Jumper wires for VCC, GND, SCL, and SDA lines. |
1 | Arduino UNO |
Copy the code from Slave_A1B3.c
into your main.c for the project and build.
Program the AVR chip and connect up the jumper wires to the Arduino board.
The complete Atmel Studio project can also be downloaded from GitHub.
Slave A1B3
Load the Arduino_A1B3_demo
code into the Arduino IDE and select the board and COM port that you will use.
Build and download into the Arduino board.
Go to Tools > Serial Terminal to monitor the data being read back.
If the AVR is connected to the Arduino, the terminal window should display an
incrementing data count as shown below.
Terminal A1B3 |
Process Flow: Like most C programs, the process begins with a call to
main() to start the program. The first thing that main() does is initialize the
data count to 0. It then calls twiSlaveInit( adrs ) to initialize the TWI hardware
and pass it the I2C address of the Slave.
The address is a unique 7-bit value and a different value has to be assigned to
each Slave on the I2C bus to prevent conflicts.
Once the hardware is setup, the interrupts are enabled by calling sei() to set
the Global Interrupt flag.
Finally, the Slave is activated by calling twiSlaveEnable(). After this point,
the Slave will automatically respond to its address. SDA_W data (commands) will
go into the RxBuf[] FIFO. When sent a SDA_R mode address, it will copy the
data from the TxBuf[] FIFO into the transmit register to be sent out.
The process now enters an infinite WHILE loop. This simple loop continually
checks for data in the Receive FIFO Buffer by calling twiDataInReceiveBuffer()
and checking for a TRUE return value just like in Slave _A1B1.
When the IF statement evaluates true (command received), the command is tested
and if it is 0x55, the command and data count are copied into the TxBuf[] FIFO
so that they will be sent out when a SDA_R is used to read the data.
If the command was not 0x55, the command is still sent to the TxBuf[], but a 0
is loaded in behind it instead of the count.
The last step is to adjust the count to show that the Slave is modifying the
data.
If the Serial Monitor does not show data, check wiring and that the Slave
address being sent by the Master is the same as the one the Slave is set to.
If the characters on the Serial Monitor look strange, check that the baud rate
setting (lower right corner) is set to 57600 to match the Arduino
Serial.begin(57600) setting.
Unfourtunatly, an oscilloscope is needed to troubleshoot farther than code
inspection and wiring checks.
With a single command to read back two bytes of data, the process is still
simple, but it is starting to get more complicated. If your step back and look
over the projects done so far, you should notice that they are fairly
modular with checks and calls to support commands and data processing.
The next examples will get rid of the IF statements and use a table structure to
develope a framework where Operation modules, with their own commands and data
generators, can be added with ease.
Now that this project is working, it provdes another baseline of operations.