Skip to content

Shift Out Basic Stamp Homework

The I2C standard can achieve synchronous serial communications between many ICs over a distance of a few meters, using only a single pair of shared lines  (besides the two power rails).

Every transfer over an I2C bus begins with a START signal  (more about that later)  followed by a control byte containing a 7-bit code followed by a one-bit mode  (0=write, 1=read).  The 7-bit code can be one of 112 short  slave addresses  or it can be one of the 16 commands tabulated next,  which ordinary  (7-bit)  I2C slave devices may safely ignore.

7-bit CodeR/WMeaning
000 00000General call
000 00001START byte
000 0001-CBUS format
000 0010-Other format (reserved)
000 0011-Reserved for future use
000 0011-Reserved for future use
000 01000Hs mode master code test (0)
000 01xyzHs mode master code xyz (1 to 7)
000 0011-Reserved for future use
111 10xyR/W10-bit address (xy bits & next byte)
111 1100-Device ID
111 1101-Reserved
111 1110-Reserved
111 1111-Reserved

Two I2C devices with the same address shouldn't coexist on the same bus.

The maximum capacitance allowed on each bus line  (400 pF)  restricts the physical characteristics of the bus and the number of connected devices.

The two I2C bus lines are called  clock  and  data  and denoted by two standard 3-letter abbreviations:

  • SCL :   Serial clock line.
  • SDA :   Serial data line.

Both lines are  open collector  with pull-up resistors connected to the positive power rail  (that name assumes the lines are driven by NPN transistors with grounded emitters, but other equivalent technologies can be used and the designation  open drain  is also common).  The logical state of either line is thus high by default and becomes "0" only when it's actively pulled to ground by a conducting transistor.

This holds for the normal I2C bus  (with a maximum clock rate of  100 kHz)  and all upgrades thereof, except the ultra-fast mode introduced in 2012  (supporting clock rates up to 5 MHz)  which uses push-pull logic on two bus lines with different names  (USCL and USDA).

ModeClock (max)YearStructure
 Slow10 kHz1982Open collector
 Normal100 kHz1982Open collector
FmFast400 kHz1992Open collector
Fm+Fast+1 MHz2007Open collector
HsHigh-speed3.4 MHz1998Open collector
UFmUltra fast5 MHz2012Push-pull

Atmel call their version of I2C "Two-Wire Interface" (TWI).  They currently do not support 10-bit addressing or high speeds.

The I2C bus is  very similar  to the SMBus  introduced by Intel in 1995  (the other accepted abbreviation for "System Management Bus" is SMB; please avoid "SMB bus" for grammatical reasons).

One significant difference is that SMBus allows dynamic allocation of slave addresses  (for "plug and play" operation of removable devices)  which is rare in the I2C world.  SMB devices aren't allowed to operate at very low frequencies (which makes them unsuitable for educational I2C demonstrations where where the bus is operated  manually):  They have a  minimum  operating frequency of  10 kHz  and a timeout of  35 ms.  SMB devices must be operated below  100 kHz.  Many implementations no not follow the official SMB recommendation of pull-up resistors of 14k or more (in 5V systems) which forces sluggish operations.  There are also differences between allowed voltages and current levels but, for the most part, both standards are compatible below  100 kHz.

Bus Masters :

Every transaction over the I2C bus is between two nodes dubbed  master  and  slave.  Those  rôles  pertain to a single transaction; several nodes may be capable of acting as masters of the bus.  When several masters can compete for control of the bus,  every one of them must be a qualified  multimaster  willing and able to follow strict arbitration procedures.  Usually, a BS2 only act as a  singlemaster  on an I2C bus where all other nodes are slaves.  It takes heroic efforts to turn it into a proper  multimaster.

A master obtains control of the bus by creating a  start condition  (namely, causing a high-to-low transition on SDA when SCL is high).  It's solely responsible for generating the clock signal  (SCL)  and formulating requests  (issuing additional START signals as needed)  until it gives up control of the bus by creating a  stop condition.  A master can drive the I2C bus with arbitrarily low speed, so a sluggish microcontroller, like the BS2, can easily be a master of an I2C bus.

A well-behaved multimaster would at least need to monitor the I2C bus continuously to know when it's busy  (between a START and a STOP).  This part is easily handled in hardware  (it would be foolish to attempt it in software, even using interrupts)  by creating a BUSY indicator available to all potential masters sharing the bus.  The START procedure in a multimaster environment is:

  • Make sure the bus isn't BUSY  (poll hardware indicator).
  • Pull SDA low  to create a START signal.

... / ...

Slaves :

An I2C slave device must be able of recognize its own address quickly to respond to a master's request.  A microcontroller can hardly function as a slave unless it can handle hardware interrupts,  which the BS2 can't do.

In normal synchronous data transfer, the logical state of the data bus line can only change when the clock line is low  (a high clock thus indicates stable valid data which can be safely read by the receiver).  A data transition when the clock is high indicates either a start bit  (when the data line goes from high to low)  or a stop bit  (for a low to high data transition).

After the start bit, the master sends an 8-bit piece of data  (always starting with the most significant bit)  containing the 7-bit address of the slave it wishes to communicate with, followed by a R/W bit set to "0" if it wants to write to the slave or "1" if it wants to read from it.  The slave so addressed should send an  acknowledge  bit  (ACK)  by pulling SDA low during the entire high time of the ninth clock pulse on SCL.

Once communication is established in this way, a normal transfer of data takes place in the direction previously indicated by the master, which keeps clocking the bus  (not faster than the rate used for the above initial handshake).  The slave is responsible for issuing an ACK bit after each byte transferred.  Failure to do so is a NACK condition, which tells the master it should terminate that multi-byte transaction  (with a stop bit)  and liberate the bus for the next transaction.

A slave can deny access to a master at any part of a write transaction (from the master's perspective) or at the beginning of a read request simply by doing nothing, instead of pulling SDA low before the master issues its ninth clock pulse.  Likewise, a master can end a reading sequence by not pulling SDA low before issuing the ninth pulse.

However, no part of the I2C protocol allows a slave to request termination of a read sequence once it has started.  It can either do nothing  (which will look to the master as if the slave is sending an endless sequence of $FF)  or "wrap around" its own address space as if its first register followed its last.  For some obscure reason, the latter solution is more popular than the former.

Properly resetting a singlemaster I2C bus and its connected interfaces :

The procedure described below should be made part of the initialization routine of any microcontroller with a reset button or any microcontroller which can be powered down independently of some devices connected to its I2C bus.

The problem is that the microcontroller in charge could have been reset at any point in the middle of an I2C transaction, so a slave could be pulling SDA low forever,  waiting for a clock pulse which never comes.

Making the following procedure part of the microcontroller initialization will remedy that situation and put any interrupted interface back to its normal state after every microcontroller reset.  This indispensable piece of I2C folklore is now mentioned, more or less precisely, in the datasheets from several I2C manufacturers  (including Maxim and Atmel).

The trick is to toggle SCL  (up to 9 times)  until SDA is brought to a high-level while SCL is high.  At this point, we can simply pull SDA low to generate a start condition.  I like to complete the initialization by letting SDA go high again,  which creates a stop condition and releases the I2C bus for normal use  (in pristine condition, with both lines pulled up).

SHIFTOUT

 

 

Syntax: SHIFTOUTDpin, Cpin, Mode, [OutputData {\Bits} {,OutputData {\Bits}...}]

Function

Shift data out to a synchronous serial device.

  • Dpin is a variable/constant/expression (0 - 15) that specifies the I/O pin that will be connected to the synchronous serial device's data input. This pin will be set to output mode.
  • Cpin is a variable/constant/expression (0 - 15) that specifies the I/O pin that will be connected to the synchronous serial device's clock input. This pin will be set to output mode.
  • Mode is a variable/constant/expression (0 - 1), or one of two predefined symbols, that tells SHIFTOUT the order in which data bits are to be arranged. See the table below for value and symbol definitions.
  • OutputData is a variable/constant/expression containing the data to be sent.
  • Bits is an optional variable/constant/expression (1 - 16) specifying how many bits are to be output by SHIFTOUT. If no Bitsentry is given SHIFTOUT defaults to 8 bits. When the Bits entry is given, the BASIC Stamp transmits the rightmost number of bits specified, regardless of the Mode.

Quick Facts

 BS2, BS2e, and BS2peBS2sx and BS2pBS2px
Timing of Th, Tl, Ta and Tb14 µs / 46 µs / 15 µs / 30 µs5.6 µs / 18 µs / 6.3 µs / 12.5 µs3.6 µs / 11.8 µs / 4.0 µs / 7.8 µs
Transmission Rate~ 16 kBits/Sec~ 42 kBits/Sec~ 65 kBits/Sec
Related Commands

SHIFTIN

Explanation

SHIFTIN and SHIFTOUT provide an easy method of acquiring data from synchronous serial devices. Synchronous serial differs from asynchronous serial (like SERIN and SEROUT) in that the timing of data bits (on a data line) is specified in relationship to clock pulses (on a clock line). Data bits may be valid after the rising or falling edge of the clock line. This kind of serial protocol is commonly used by controller peripherals like ADCs, DACs, clocks, memory devices, etc.

At their heart, synchronous-serial devices are essentially shift-registers; trains of flip-flops that pass data bits along in a bucket brigade fashion to a single data output pin. Another bit is output each time the appropriate edge (rising or falling, depending on the device) appears on the clock line.

The SHIFTOUT instruction first causes the clock pin to output low and the data pin to switch to output mode. Then, SHIFTOUT sets the data pin to the next bit state to be output and generates a clock pulse. SHIFTOUTcontinues to generate clock pulses and places the next data bit on the data pin for as many data bits as are required for transmission.

Making SHIFTOUT work with a particular device is a matter of matching the mode and number of bits to that device's protocol. Most manufacturers use a timing diagram to illustrate the relationship of clock and data. One of the most important items to look for is which bit of the data should be transmitted first; most significant bit (MSB) or least significant bit (LSB). The table below shows the values and symbols available for the Mode argument

SymbolValueMeaning
LSBFIRST0Data is shifted out LSB-first
MSBFIRST1Data is shifted out MSB-first

 

(MSB is most-significant bit; the highest or left-most bit of a Nibble, Byte, or Word. LSB is the least-significant bit; the lowest or right-most bit of a Nibble, Byte, or Word.)

SHIFTOUT Timing

Here is a simple example:

SHIFTOUT 0, 1, MSBFIRST, [250]

Here, the SHIFTOUT command will write to I/O pin 0 (the Dpin) and will generate a clock signal on I/O 1 (the Cpin). The SHIFTOUT command will generate eight clock pulses while writing each bit (of the 8-bit value 250) onto the data pin (Dpin). In this case, it will start with the most significant bit first as indicated by the Mode value of MSBFIRST.

By default, SHIFTOUT transmits eight bits, but you can set it to shift any number of bits from 1 to 16 with the Bits argument. For example:

SHIFTOUT 0, 1, MSBFIRST, [250\4]

Will output only the lowest (rightmost) four bits (%1010 in this case). But what if you want to output the leftmost bits of a given value? By adding the right-shift operator (>>) to the code you can adjust the output as required:

SHIFTOUT 0, 1, MSBFIRST, [(250 >> 2)\6]

...will output the upper six bits (%111110 in this case).

Some devices require more than 16 bits. To solve this, you can use a single SHIFTOUT command with multiple values. Each value can be assigned a particular number of bits with the Bits argument. As in:

SHIFTOUT 0, 1, MSBFIRST, [250\4, 1045\16]

The preceding example will first shift out four bits of the number 250 (%1010) and then 16 bits of the number 1045 (%0000010000010101). The two values together make up a 20 bit value.

In the examples above, specific numbers were entered as the data to transmit, but, of course, the SHIFTOUT command will accept variables and expressions for the OutputData and even for the Bits argument.