The initialization portion of the program will include two main registers that serve two purposes, the prescaler and the
actual bit rate. The bit rate is a rate of speed that each bit will be sent over the SDA line. The SCL is the heart
beat which pulses at the bit rate.
To make things really easy, it is recommended that the prescaler stay zero. This is not because
dealing with a prescaler
is hard, but because the TWSR (Two Wire Status Register) holds the prescaler and also serves as the status during
transmission. If a prescaler was mixed into this number, then the status would be more difficult to determine.
If you do wish to modify the prescaler because your microcontroller has a very high CPU clock rate, then you can shift
the TWSR status register so the prescale drops off when you need only the status, or you can determine the values
of the status with the included prescaler. See the list of status values below. If you use a prescaler, just add that
value to the status value.
TWSR (TWI Status Register (Prescaler Bits)) -
TWSR - TWS7 | TWS6 | TWS5 | TWS4 | TWS3 | –---- | TWPS1 | TWPS0
TWSR - --7--|---6--|---5--|---4--|---3--|---2---|---1---|---0-----
TWSR - (----------Status Bits-----------)-------(-Prescaler Bits-)
TWSR will be 0x08 after a start condition
The SCL clock should be 100kHz
Calculating the TWBR is relatively straightforward. First, you need to know the desired speed that you intend the SCL to be.
For standard mode, this speed is a maximum of 100 KHz and for fast mode the maximum speed is 400 KHz. Notice that these
frequencies are maximums. That means that you can still communicate using I2C or TWI at lower speeds. In the example
I show in the video on this page, I use a frequency of 50 KHz. To determine the TWBR (Two Wire Bit Rate Register), you can
use this formula:
Bit Rate Generator Unit
TWBR (TWI Bit Rate Register) - will be 2 for a 50kHz SCL
TWBR - TWBR7 | TWBR6 | TWBR5 | TWBR4 | TWBR3 | TWBR2 | TWBR1 | TWBR0
TWBR - --7---|---6---|---5---|---4---|---3---|---2---|---1---|---0----
SCL Frequency = (CPU Internal Clock Frequency) / 16 + 2 (TWBR) * 4 ^ TWPS
You see that TWPS? You're saying to yourself, what is that! That is the prescale bits found in the TWSR register. Notice
the bits in the TWSR where I describe the TWSR above. The bits are called TWPS0 and TWPS1. Let's do some algebra to make
it easier to find TWBR. Welcome to algebra class!
SCL_Clock = (CPU_Clock_Rate) / 16 + 2(TWBR) x 4 ^ TWPS
SCL_Clock = (CPU_Clock_Rate) / 16 + 2(TWBR) (We can remove the 4 ^ TWPS since the prescaler is 0)
Cross Multiply:
SCL_Clock x (16 + 2(TWBR)) = CPU_Clock_Rate
Divide SCL_Clock by both sides to get it to the other side of the equasion:
16 + 2(TWBR) = CPU_Clock_Rate / SCL_Clock
Subtract 16 from both sides:
2(TWBR) = (CPU_Clock_Rate / SCL_Clock) - 16
Divide both sides by 2:
TWBR = ((CPU_Clock_Rate / SCL_Clock) - 16) / 2
There! Now you have a simple formula you can apply in the program.
Or you can use the following table to make it easier.
CPU_Clock_Rate(MHz)|TWBR|SCL_Clock(KHz)
---------16--------|-12-|------400-----
---------16--------|-72-|------100-----
---------14.4------|-10-|------400-----
---------14.4------|-64-|------100-----
---------12--------|--7-|------400-----
---------12--------|-52-|------100-----
----------8--------|--2-|------400-----
----------8--------|-32-|------100-----
----------4--------|-12-|------100-----
----------3.6------|-10-|------100-----
----------2--------|--2-|------100-----
----------2--------|-12-|-------50-----
----------1--------|--2-|-------50-----