Title: Chapter 11 Interintegrated Circuit I2C Interface
1Chapter 11Inter-integrated Circuit (I2C)
Interface
2The I2C Protocol
- Developed by Philips in late 1980s
- Version 1.0 published in 1992
- Supports standard (100 Kbps) and fast (400 Kbps)
mode - Version 2.0 published in 1998
- High-speed mode (3.4 Mbps) added
- Classifies devices into slave and master
- Allows multiple masters to be attached to the
same bus - The master device uses either a 7-bit or 10-bit
address to specify the slave device as its
partner of data communication. - Supports bi-directional data transfer
- Allows multiple masters (microcontrollers) to
share the same peripheral devices
3I2C Signal Level
- Float high and driven low
- Use the SCL signal to carry clock signal to
synchronize data transfer - Use the SDA signal to carry data and address
- The SDA and SCL pins of I2C devices (masters and
slaves) are open-drain and need external pull up
resistors. - The resistors 2.2 K? and 1 K ? are recommended
for 100 Kbps and 400 Kbps baud rate.
4(No Transcript)
5Signal Components
- I2C data transfer consists of 5 signal
components - Start (S)
- Stop (P)
- Repeated Start (R)
- Data
- Acknowledge (A)
6Start Condition
- Used to indicate that a device would like to
transfer data on the I2C bus - Represented by the SDA line going low when the
clock (SCL) signal is high - Will initialize the I2C bus
7Stop Condition
- A condition that a device wants to release the
I2C bus - Is represented by the SDA signal going high when
the SCL signal is high - Once the stop condition is complete, both the SCL
and SDA signals are high. This is the idle bus.
8Repeated Start (R) Condition
- A Start signal generated without first generating
a Stop condition to terminate the communication - Used by the master to communicate with another
slave or change data transfer direction without
releasing the bus - Also referred to as Restart condition
9Data
- It represents the transfer of eight bits of
information. - Data on the SDA line is considered valid only
when the SCL signal is high. - When the SCL signal is low, the data is allowed
to change. - The eight-bit data may be a control code, an
address, or data.
10Acknowledge (ACK) Condition
- Data transfer needs to be acknowledged either
positively (A) or negatively (NACK). - A device acknowledges a byte it receives
positively by bringing the SDA line low during
the ninth clock pulse of SCL. - If the device allows the SDA line to float high,
it is transmitting a negative acknowledge (NACK).
11Synchronization (1 of 2)
- All masters generate their clocks on the SCL line
to transfer messages on the I2C bus. - A defined clock is needed for the bit-by-bit
arbitration procedure to take place. - Most microcontrollers generate the SCL clock by
counting down a programmable reload value using
the instruction clock signal. - Clock synchronization occurs when multiple
masters attempt to drive the I2C bus and before
the arbitration scheme can decide which master is
the winner. - Clock synchronization is performed using the
wired-AND connection of I2C interfaces to the SCL
line. - The high-to-low transition on the SCL line causes
the devices concerned (masters) to start counting
off their low period.
12Synchronization (2 of 2)
- A master device that is counting off their low
period will hold the SCL line low until the
counter is count down to 0. At this point, the
device will release the SCL line to high. - If there are other devices holding the SCL low,
then the SCL line will remain low until all
master devices have counted down to 0. At this
point, the SCL line will go high and all devices
will start to count high. - The SCL line will be held low by the device with
the longest low period. - By the same reasoning, the high period of the SCL
signal is determined by the device with the
shortest high period.
13Handshaking
- The clock synchronization mechanism can be used
as a handshake in data transfer. - Slave device can hold the SCL line low after
completion of one byte transfer (9 bits). - Slave halts the bus until it gets ready for the
next operation and then release the SCL line.
14Arbitration
- In the event two or more master devices attempt
to begin a transfer at the same time, an
arbitration scheme is employed to force one or
more masters to give up the bus. - The master devices continue to transmit data
until one master attempts to send a high while
the other transmits a low. - Since the SDA bus has open drain, the master
device that attempts to send a high will detect a
low. At this point, it will stop driving the bus. - The arbitration process does not slow down the
winning masters transfer and no data gets lost.
15I2C Addressing Methods
- I2C protocol allows master devices to use either
the 7-bit and 10-bit address to specify the slave
device for data communication. - The 7-bit addressing uses the upper 7 bits of the
address byte for address and the least
significant bit to specify the data transfer
direction. The format is shown in Figure 11.13. - The 10-bit addressing uses two bytes to carry the
address information. - The bit 0 of the high byte is used to indicate
the data transfer direction. - The upper 7 bits have the pattern of 1111 0xx
with xx representing the most significant two
address bits of the slave. - The second byte carries the lower 8 address bits.
16Data Transfer Format (7-bit Addressing) (1 of 2)
- Master transmitter to slave receiver shown in
Figure 11.10 - Master reads slave immediately after the first
byte (address byte) shown in Figure 11.11 - Combined format. A master may transfer some data
to the slave and then generate a restart
condition to read data from the slave or
send/read data to/from other slave-- shown in
Figure 11.12.
17Data Transfer Format (7-bit Addressing) (2 of 2)
18Data Transfer Format10-bit Addressing (1 of 3)
- Master transmitter transmits to slave receiver
with a 10-bit address Figure 11.16 - Master receiver reads slave transmitter with a
10-bit address Figure 11.17 - Restart condition generated in this format
- Combined format A master sends data to a slave
and then reads data from the same slave. Shown in
Figure 11.18. - Combined format A master sends data to one
slave and then transmit data to another slave.
Shown in Figure 11.19. - Combined format 10-bit and 7-bit addressing
combined in one transfer. Shown in Figure 11.20.
19Data Transfer Format10-bit Addressing(2 of 3)
20Data Transfer Format10-bit Addressing (3 of 3)
21Overview of the HCS12 I2C Module
- Implements a subset of the I2C protocol
- Provides interrupts on start and stop bits in
hardware to determine if the I2C bus is free - Supports only 7-bit addressing
- Supports 100 Kbps baud rate but requires the user
to limit the slow rate to no higher than 100 ns
if the 400 Kbps baud is to be used - Limit the maximum bus capacitance to 400 pF for
all conditions. - Use PJ7 (SCL) and PJ6 (SDA) pins to support the
I2C communication. - Use five registers to support its operation
- I2C Control Register (IBCR)
- I2C status Register (IBSR)
- I2C data I/O register (IBDR)
- I2C Frequency Divider Register (IBFD)
- I2C Address Register (IBAD)
22(No Transcript)
23Registers for I2C Operation
- I2C Address Register (IBAD)
- Contains an address to which it will respond when
the I2C module is configured as a slave device.
24I2C Data Register (IBDR)
- In master transmit mode, a data transfer is
started whenever this register is written into. - The most significant bit is shifted out first.
- In master receive mode, reading this register
initiates the reception of the next byte. (The
master sends out nine clock pulses to shift in
data bits and replies with an acknowledge.)
25The I2C Control Register (1 of 2)
26The I2C Control Register (2 of 2)
- When setting the MS/SL bit from 0 to1, a start
signal is generated on the I2C bus and the master
mode is selected. - In the master mode, the Tx/Rx bit should be set
according to the type of transfer required. - The TxAK bit specifies the value driven onto the
SDA line during data acknowledge cycles for both
master and slave receivers. - I2C module always acknowledges the address
matches regardless of the value of TxAK. - Writing a 1 to the RSTA bit will generate a
Restart condition on the I2C bus.
27The I2C Status Register (IBSR) (1 of 2)
- When a byte is being transferred, the TCF bit is
cleared. - When the I2C is configured as a slave and the
address matches, then the IAAS bit will be set. - The IBIF bit will be set under three
circumstances - Arbitration lost (IBAL bit is set)
- Byte transfer complete (TCF bit is set)
- Addressed as a slave (IAAS bit is set)
28The I2C Status Register (IBSR) (2 of 2)
29I2C Frequency Divider Register (IBFD)
- Four timing requirements to be met
- SCL divider
- SDA hold time
- SCL hold time for start condition
- SCL hold time for stop condition
30The Use of the IBFD Register (1 of 2)
- IBC7-IBC6 multiply factor (shown in Table 11.3)
- IBC5-IBC3 prescaler divider (shown in Table
11.4) - IBC2-IBC0 shift register tap points (shown in
Table 11.5)
31The Use of the IBFD Register (2 of 2)
- Using Table 11.3, 11.4, and 11.5 is a laborious
process. - These three tables can be combined into the Table
11.6. - With Table 11.6, finding values to be written
into the IBFD register becomes a simple table
look up. - By dividing the intended baud rate into the bus
clock, one can locate one or multiple rows in
Table 11.6 with the same SCL divider value. - One needs to verify that the SDA hold time, SCL
hold time (start), and SCL hold time (stop) all
satisfy the timing requirements set out in Table
11.2 before making the selection.
32- Example 11.1 Assuming that the HCS12 is running
with a 24 MHz bus clock, compute the values to be
written into the IBFD register to set the baud
rate to 100 KHz and 400 KHz. - Solution
- Case 1 baud rate 100 KHz
- SCL divider 24 MHz ? 100KHz 240
- From Table 11.6,
- SDA hold time 33 E clock cycles 1.375 ms lt
3.45 ms - SCL hold time (start) 118 E clock cycles
4.92 ms gt 4.0 ms - SCL hold time (stop) 121 E clock cycles
5.04 ms gt 4.0 ms - The computed value satisfies the timing
requirement. - Write the value 1F into the IBFD register at
100 KHz baud rate. - Case 2 baud rate 400 KHz
- SCL divider 24 MHz ? 400KHz 60
- From Table 11.6, the corresponding IBC value is
45. - SDA hold time 18 E clock cycles
0.75 ms lt 0.9 ms - SCL hold time (start) 22 E clock
cycles 0.917 ms gt 0.6 ms - SCL hold time (stop) 121 E clock
cycles 1.33 ms gt 0.6 ms - The computed value satisfies the timing
requirement. - Write the value 45 into the IBFD register at
400 KHz baud rate.
33Configuring the I2C Module
- Compute an appropriate value and write it into
the IBFD register. - Load a value into the IBAD register if the MCU
may operate in slave mode. - Set the IBEN bit of the IBCR register to enable
I2C module. - Modify the bits of the IBCR register to select
master/slave mode, transmit/receive mode, and
interrupt enable mode
parameters are passed in accumulator A (baud
rate) and B (slave address) openI2C bset IBCR,IBEN
enable I2C module staa IBFD establish SCL
frequency stab IBAD establish I2C module
slave address bclr IBCR,IBIE disable I2C
interrupt bset IBCR,IBSWAI disable I2C in wait
mode rts
void openI2C (char ibc, char i2c_ID) IBCR
IBEN / enable I2C module / IBFD ibc /
set up I2C baud rate / IBAD i2c_ID / set
up slave address / IBCR IBIE / disable
I2C interrupt / IBCR IBSWAI / disable I2C
in wait mode /
34Programming the I2C Module
- Generating Start condition and send slave ID
sendSlaveID brset IBSR,IBB, wait until I2C bus
is free bset IBCR,TXRXMSSL generate a start
condition staa IBDR send out the slave
address brclr IBSR,IBIF, wait for address
transmission to complete movb IBIF,IBSR clear
the IBIF flag rts
void sendSlaveID (char cx) while
(IBSRIBB) / wait until I2C bus is idle
/ IBCR TXRXMSSL / generate a start
condition / IBDR cx / send out the slave
address with R/W bit set to 1/ while(!(IBSR
IBIF)) / wait for address transmission to
complete / IBSR IBIF / clear IBIF flag /
35- Instruction sequence to send a byte in
accumulator A
staa IBDR brclr IBSR,IBIF, wait until IBIF
flag is set to 1 movb IBIF,IBSR clear the
IBIF flag
- C statements to send a byte to I2C bus
- IBDR cx / send out the value cx /
- while (!(IBSR IBIF)) / wait until the byte
is shifted out / - IBSR IBIF / clear the IBIF flag /
- Instruction sequence to read a byte and
acknowledge it
bclr IBCR,TXRXTXAK prepare to receive and
acknowledge ldaa IBDR a dummy read to trigger
9 clock pulses brclr IBSR,IBIF, wait until
the data byte is shifted in movb IBIF,IBSR
clear the IBIF flag ldaa IBDR place the
received byte in A and also initiate the
next read sequence
36- C Statements to read a byte from the I2C bus
IBCR (TXRX TXAK) / prepare to receive
and acknowledge / dummy IBDR / a dummy
read / while(!(IBSR IBIF)) / wait for the
byte to shift in / IBSR IBIF / clear the
IBIF flag / buf IBDR / place the received
byte in buf and also initiate the next
read sequence /
- Instruction Sequence to Read a Byte, Send NACK,
and Generate Stop Condition
bclr IBCR,TXRX prepare to receive bset IBCR,TX
AK to send negative acknowledgement
ldaa IBDR dummy read to trigger clock
pulses brclr IBSR,IBIF, wait until the byte
is shifted in movb IBIF,IBSR clear the IBIF
flag bclr IBCR,MSSL generate a stop
condition ldaa IBDR place the received byte in
A
37- C statements to Read a Byte, send NACK, and
generate a Stop condition
IBCR TXRX / prepare to receive / IBCR
TXAK / prepare not to acknowledge / dummy
IBDR / a dummy read to trigger 9 clock
pulses / while(!(IBSR IBIF)) / wait for a
byte to shift in / IBSR IBIF / clear the
IBIF flag / IBCR MSSL / generate a stop
condition / buf IBDR / place the received
byte in buf /
38I2C Data Transfer in Slave Mode
- After reset and stop condition, the I2C module is
in slave mode. - Once in slave mode, the I2C module waits for a
start condition to come. - Following the start condition, eight bits are
shifted into the IBAD register. - The value of the upper 7 bits of the received
byte is compared with the IBAD register. - If the address matches, the following events
occur - The bit 0 of the address byte is copied into the
SRW bit of the IBSR register. - The IAAS bit is set to indicate the address
match. - An ACK pulse is generated regardless of the value
of the TXAK bit. - The IBIF bit is set.
39Instruction Sequence to Make Sure the Addresses
Match and Take Appropriate Action
brset IBSR,IAAS,addr_match is address
matched? addr_match brclr IBSR,SRW,slave_rd
bset IBCR,TXRX prepare to transmit
data movb tx_buf,IBDR place data in IBDR to
wait for SCL to shift it out brclr IBSR,IBIF,
wait for data to be shifted out slave_rd bclr I
BCR,TXAKTXRX prepare to receive and send
ACK brclr IBSR,IBIF, wait for data byte to
shift in movb IBIF,IBSR clear the IBIF
flag movb IBDR,rcv_buf save the received data
40The Serial Real-Time Clock DS1307
- Uses BCD format to represent the clock and
calendar information - Has 56 bytes to store critical information
- Clock calendar provides seconds, minutes, hours,
day, date, month, and year information - Operates in either the 24-hour or 12-hour format
with AM/PM indicator - Has built-in power sense circuit that detects
power failure and automatically switches to the
battery supply - The SQW output frequency may be 1 Hz, 4 KHz, 8
KHz, and 32 KHz.
41DS1307 Address Map
- Bit 6 of the hours register selects whether the
12-hour or 24-hour mode is used. - Bit 5 of the
hours register selects whether the current time
is AM or PM if 12-hour mode is selected.
42DS1307 Control Register
- Bit 7 controls the output level of the SQWOUT pin
when the square output is disabled. - The SQWE bit enables/disables the SQWOUT pin
output. - Bits 1 and 0 select the output frequency of the
SQWOUT pin.
43Data Transfer
- DS1307 supports standard mode (100 Kbps) of data
transfer. - The device address (ID) of the DS1307 is 1101000.
44Circuit Connection between the DS1307 and the
HCS12
45- Example 11.3 Write a function to configure the
DS1307 to operate with the following setting - - SQWOUT output enabled
- - SQWOUT output set to 1 Hz
- - SQWOUT idle high when it is disabled
- - Control byte passed in B
- Solution
openDS1307 ldaa D0 place device ID of the
DS1307 in A jsr sendSlaveID brclr IBSR,RXAK,sndR
egAdr did DS1307 acknowledge? ldab FF
return error code -1 rts sndRegAdr movb 07,IBDR
send out the control register
address brclr IBSR,IBIF, wait until the
register address is shifted out movb IBIF,IBSR
clear the IBIF flag brclr IBSR,RXAK,sndok did
DS1307 acknowledge? ldab FF rts sndok stab IBD
R send out control byte brclr IBSR,IBIF,
wait until the control byte is shifted
out movb IBIF,IBSR bclr IBCR,MSSL generate a
stop condition rts
46char openDS1307(char ctrl)
sendSlaveID(0xD0) / send out DS1307's ID /
if (IBSR RXAK) / if DS1307 did not
acknowledge, send error code / return
-1 IBDR 0x07 / send out control
register address / while(!(IBSR IBIF))
IBSR IBIF / clear IBIF flag /
if (IBSR RXAK) / if DS1307 did not
acknowledge, send error code / return
-1 IBDR ctrl / send out control
byte / while(!(IBSR IBIF)) IBSR
IBIF if (IBSR RXAK) / if DS1307 did
not acknowledge, send error code /
return -1 IBCR MSSL / generate a
stop condition / return 0
47- Example 11.4 Write a function to read the time
and calendar information from the DIP - switches and store them in a buffer to be sent to
the DS1307. The DIP switches are driven - by Port AD1.
- Solution The procedure to enter a bye of
information - Outputs a message to remind the user to enter a
value. - The user sets up a value using the DIP switches
and presses the button connected to PJ0 pin to
remind (interrupt) the MCU to read the value. - MCU reads the value of DIP switches and sends it
to the DS1307
tready ds.b 1 a flag to indicate that data is
ready getTime pshx pshy ldy buf Y is the
pointer to the buffer movb FF,ATD1DIEN
enable Port AD1 for digital inputs bclr DDRJ,BIT0
enable PJ0 pin for input bset PERJ,BIT0
enable pull-up or pull-down on PJ0
pin bclr PPSJ,BIT0 enable pull-down so that
interrupt is rising edge triggered bset PIEJ,BIT0
enable PJ0 interrupt cli
" movb 0,tready clear the data ready flag to
0 ldaa 80 set LCD cursor to the upper left
corner jsr cmd2lcd "
48 ldx prompty output the prompt "Enter
year" jsr puts2lcd " waity tst tready is
new year info. ready? beq waity " movb PTAD1
,1,y save year info. in buffer movb 0,tready
ldaa 80 set LCD cursor to the upper left
corner jsr cmd2lcd " ldx promptm output
the prompt "Enter month" jsr puts2lcd
" waitm tst tready is new month info.
ready? beq waitm " movb PTAD1,1,y save
month info. in buffer movb 0,tready clear
the ready flag ldaa 80 set LCD cursor to
the upper left corner jsr cmd2lcd
" ldx prompte output the prompt "Enter
date" jsr puts2lcd "
49waite tst tready is new date info.
ready? beq waite " movb PTAD1,1,y save
date info. in buffer movb 0,tready clear the
ready flag ldaa 80 set LCD cursor to the
upper left corner jsr cmd2lcd
" ldx promptd output the prompt "Enter
day" jsr puts2lcd " waitd tst tready is
new day info. ready? beq waitd " movb PTAD1,
1,y save day info. in buffer movb 0,tready
ldaa 80 set LCD cursor to the upper left
corner jsr cmd2lcd " ldx prompth output
the prompt "Enter hours" jsr puts2lcd
" waith tst tready is new hour info.
ready? beq waith " movb PTAD1,1,y save
hour info. in buffer movb 0,tready ldaa 80
set LCD cursor to the upper left
corner jsr cmd2lcd
50 ldx promptmi output the prompt "Enter
minutes" jsr puts2lcd " waitmi tst tready
is new minute info. ready? beq waitmi " movb
PTAD1,1,y save hour info. in
buffer movb 0,tready ldaa 80 set LCD
cursor to the upper left corner jsr cmd2lcd
" ldx prompts output the prompt "Enter
seconds" jsr puts2lcd " waits tst tready
is new second info. ready? beq waits " movb
PTAD1,1,y save second info. in
buffer movb 0,tready puly pulx rts include
"c\miniIDE\lcd_util_ SSE256.asm" include
"c\miniIDE\delay.asm" prompts fcc "Enter
seconds" dc.b 0 promptmi fcc "Enter
minutes" dc.b 0
51promptmi fcc "Enter minutes" dc.b 0 prompth fcc
"Enter hours" dc.b 0 promptd fcc "Enter
day" dc.b 0 prompte fcc "Enter
date" dc.b 0 promptm fcc "Enter
month" dc.b 0 prompty fcc "Enter year" dc.b 0
interrupt service routine for PJ0
pin PJ_ISR movb 1,tready set tready flag to
1 movb 1,PIFJ clear the PIFJ0 flag rti
52- Example 11.5 Write a function to send the time
and calendar information to the DS1307. - The time and calendar information is pointed to
by X. The device ID and the starting - register address are passed in A and B,
respectively. X points to the value of year and
the - seconds value is located at X6.
- Solution
sendTime jsr sendSlaveID send out device ID of
the DS1307 brclr IBSR,RXAK,sndTimeOK1 did
DS1307 acknowledge? ldab FF return error
code -1 if not acknowledged rts sndTimeOK1 stab I
BDR send out register address for
seconds brclr IBSR,IBIF, wait until seconds'
address has been shifted out movb IBIF,IBSR
clear the IBIF flag brclr IBSR,RXAK,sndTimeOK2
did 1307 acknowledge? ldab FF return error
code -1 if not acknowledged rts sndTimeOK2 ldy 7
byte count tfr X,D set X to point to
seconds value addd 6 tfr D,X sndloop m
ovb 1,x-,IBDR send out one byte and decrement
pointer brclr IBSR,IBIF, movb IBIF,IBSR brclr
IBSR,RXAK,sndTimeOK3 did DS1307 acknowledge?
53 ldab FF return error code -1 if not
acknowledged rts sndTimeOK3 dbne y,sndloop
continue until all bytes have been sent
out bclr IBCR,MSSL generate a stop
condition. ldab 0 return normal return code
0 rts
54char sendTime (char ptr, char ID) char
i sendSlaveID(0xD0) / send ID to
DS1307 / if(IBSR RXAK) / did
DS1307 acknowledge? / return -1
IBDR 0x00 / send out seconds
register address / while(!(IBSR IBIF))
IBSR IBIF / clear IBIF flag /
if(IBSR RXAK) return -1 for(i
6 i gt 0 i--) / send year first, send second
last / IBDR (ptri)
while(!(IBSRIBIF)) IBSR IBIF
if(IBSR RXAK) return -1
return 0
55- Example 11.6 Write a C function to read the time
of day from the DS1307 and save it in - the array cur_time06.
- Solution
char readTime(char cx) char i, temp
sendSlaveID(0xD0) / generate a start
condition and send DS1307's ID / if (IBSR
RXAK) return -1 / if DS1307 did not
respond, return error code IBDR cx
/ send address of seconds register /
while(!(IBSR IBIF)) IBSR IBIF /
clear the IBIF flag / if (IBSR RXAK)
return -1 / if DS1307 did not respond,
return error code / IBCR RSTA /
generate a restart condition / IBDR
0xD1 / send ID and set R/W flag to read /
while(!(IBSR IBIF)) IBSR IBIF
if (IBSR RXAK) return -1 / if
DS1307 did not respond, return error code /
56 IBCR (TXRX TXAK) / prepare to
receive and acknowledge / temp IBDR
/ a dummy read to trigger 9 clock pulses /
for (i 0 i lt 5 i)
while(!(IBSR IBIF)) / wait for a byte to
shift in / IBSR IBIF / clear the IBIF flag
/ cur_timei IBDR / save the
current time in buffer /
/ also initiate the next read /
while (!(IBSR IBIF)) / wait for the receipt
of cur_time5 / IBSR IBIF / clear IBIF
flag / IBCR TXAK / not to
acknowledge cur_time6 / cur_time5
IBDR / save cur_time5 and initiate next
read / while (!(IBSR IBIF)) IBSR
IBIF IBCR MSSL / generate stop
condition / cur_time6 IBDR
return 0
57- Example 11.7 Write a function to format the time
information stored in the array - cur_time0..6 so that it can be displayed on the
LCD. - Solution
- - Store the converted time and calendar
information in two arrays hms011 and - mdy011.
- - hms holds hours, minutes, and seconds
- - mdy holds month, date, and year
- Time information display format for 24-hour
mode - hhmmssxx
- mmddyy
- Time information display format for 12-hour
mode - hhmmssZM
- xxmmddyy
58void formatTime(void) char temp3
temp3 cur_time3 0x07 / extract
day-of-week / if (cur_time2 0x40) /
if 12-hour mode is used / hms0 0x30
((cur_time2 0x10) gtgt 4) / tens hour digit
/ hms1 0x30 (cur_time2 0x0F)
/ ones hour digit / hms2 ''
hms3 0x30 (cur_time1 gtgt 4) /
tens minute digit / hms4 0x30
(cur_time1 0x0F) / ones minute digit /
hms5 '' hms6 0x30
((cur_time0 0x70) gtgt 4) / tens second digit
/ hms7 0x30 (cur_time0
0x0F) / ones second digit / hms8
'' if (cur_time2 0x20)
hms9 'P' else hms9
'A' hms10 'M' hms11
0 / terminate the string with a NULL /
59 switch(temp3) / convert to day of week /
case 1 mdy0 'S'
mdy1 'U' break
case 2 mdy0 'M'
mdy1 'O' break
case 3 mdy0 'T'
mdy1 'U' break
case 4 mdy0 'W'
mdy1 'E' break
case 5 mdy0 'T'
mdy1 'H' break
case 6 mdy0 'F'
mdy1 'R' break
case 7 mdy0 'S'
mdy1 'A' break
60 default mdy0 0x20 / space /
mdy1 0x20
break mdy2 ''
mdy3 0x30 (cur_time5 gtgt 4)
/ month / mdy4 0x30
(cur_time5 0x0F) mdy5 ''
mdy6 0x30 (cur_time4 gtgt 4)
/ date / mdy7 0x30
(cur_time4 0x0F) mdy8 ''
mdy9 0x30 (cur_time6 gtgt 4)
/ year / mdy10 0x30
(cur_time6 0x0F) mdy11 0
/ NULL character / else /
24-hour mode / hms0 0x30
((cur_time2 0x30)gtgt4) / hours /
hms1 0x30 (cur_time2 0x0F)
hms2 '' hms3 0x30
(cur_time1 gtgt 4) / minutes /
hms4 0x30 (cur_time1 0x0F)
hms5 ''
61 hms6 0x30 ((cur_time0 0x70)gtgt4) /
seconds / hms7 0x30 (cur_time0
0x0F) hms8 ''
switch(temp3) / convert to day of week /
case 1 hms9 'S'
hms10 'U' break
case 2 hms9 'M'
hms10 'O' break
case 3 hms9 'T'
hms10 'U'
break case 4 hms9 'W'
hms10 'E'
break case 5 hms9
'T' hms10 'H'
break case 6
hms9 'F' hms10
'R' break
62 case 7 hms9 'S'
hms10 'A'
break default hms9 0x20
/ space / hms10
0x20 break
hms11 0 / NULL character /
mdy0 0x30 (cur_time5 gtgt 4) /
month / mdy1 0x30 (cur_time5
0x0F) mdy2 '' mdy3
0x30 (cur_time4 gtgt 4) / date /
mdy4 0x30 (cur_time4 0x0F)
mdy5 '' mdy6 0x30
(cur_time6 gtgt 4) / year /
mdy7 0x30 (cur_time6 0x0F)
mdy8 0 / NULL character /
63- Example 11.8 Write a function to display the
current time and calendar information on - the LCD.
- Solution
void displayTime (void) cmd2lcd(0x83)
/ set cursor to row 1 column 3 /
puts2lcd(hms) / output hours, minutes, and
seconds / cmd2lcd(0xC3) / set cursor
to row 2 column 3 / puts2lcd(mdy) /
output month, date, and year /
- Example 11.9 Write the interrupt service
routine that reads the time from the DS1307, - format the time and calendar information, and
display them on the LCD. - Solution
void INTERRUPT irqISR (void)
readTime(0x00) / read all time registers
starting from seconds / formatTime()
/ format time info into two strings /
displayTime() / display the time on LCD
/
64Digital Thermometer and Thermostat DS1631A (1 of
2)
- Mainly used to warn the possible overheat of the
embedded system to prevent system failure. - When the ambient temperature exceeds the trip
point, the DS1631A asserts the TOUT signal.
65Digital Thermometer and Thermostat DS1631A (2 of
2)
- DS1631A converts temperature into 9-, 10-, 11-,
or 12-bit readings over a range of -55ºC to
125ºC. - TOUT is asserted whenever the converted ambient
temperature is equal to or higher than the value
stored in the TH register. - Once asserted, the TOUT output will stay high
until the temperature drops below the value
stored in the TL register. - Negative temperatures are represented in twos
complement format.
66DS1631A Registers
- Config, TH, TL, and Temperature are DS1631A
internal registers. - The Config register is 8-bit.
- The Config register can be read from and written
into. - TH, TL, and Temperature registers are 16-bit.
67(No Transcript)
68Converting the Conversion Result to Temperature
- The conversion result cannot be higher than
0x7D00 or lower than 0xC900. - Table 11.8 shows the a sample temperature
reading. - Positive Conversion Result
- Step 1
- Truncate the lowest four bits.
- Step 2
- Divide the upper 12 bits by 16.
- Negative Conversion Result
- Step 1
- Compute the twos complement of the conversion
result. - Step 2
- Truncate the lowest 4 bits.
- Step 3
- Divide the upper 12 bits of the twos complement
of the conversion result by 16.
69DS1631A Command Set
- Start Convert T (0x51)
- Stop Convert T (0x22)
- Read Temperature (0xAA)
- Access TH (0xA1)
- Access TL (0xA2)
- Access Config (0xAC)
- Software POR (0x54)
70Circuit Connection
71DS1631A Control Byte (Device ID)
- Example 11.10 Write a function to configure the
DS1631A in Figure 11.34 to operate in continuous
conversion mode and set the TOUT polarity to
active high. Assume that the I2C has only one
master and there is no possibility in getting bus
collision. - Solution
- Call the openDS1631 function on the next slide
with the configuration byte of 0xE0 - ldab E0
- jsr openDS1631
72openDS1631 ldaa 92 jsr sendSlaveID brclr IBSR,
RXAK,openOK0 did DS1631A acknowledge? ldab F
F return error code -1 rts openOK0 movb AC,IB
DR send the "Access Config" command brclr IBSR,
IBIF, movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,openOK1 did DS1316A
acknowledge? ldab FF rts openOK1 stab IBDR
sends configuration data brclr IBSR,IBIF,
wait until the byte has been shifted
out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,openOK2 did DS1316A
acknowledge? ldab FF rts openOK2 bclr IBCR,MSS
L generate a stop condition ldab 0 normal
return code rts
73C Function to Initialize the DS1631A
char openDS1631(char cy)
sendSlaveID(0x92) / generate a start
condition and send ID / if (IBSR RXAK)
return -1 / error code when
DS1631 did not acknowledge / IBDR 0xAC
/ send command "Access Config" /
while(!(IBSR IBIF)) IBSR IBIF / clear
the IBIF flag / if (IBSR RXAK)
return -1 / error code when DS1631 did
not acknowledge / IBDR cy /
send configuration byte / while(!(IBSR
IBIF)) IBSR IBIF if (IBSR RXAK)
return -1 / error code when DS1631
did not acknowledge / IBCR MSSL
/ generate a stop condition / return 0
/ normal return code /
74- Example 11.11 Write a function to command the
DS1631A to start temperature conversion. - Solution
startConv ldaa 92 jsr sendSlaveID generate a
start condition and send DS1631's
ID brclr IBSR,RXAK,startOK0 did DS1631A
acknowledge? ldab FF return error code
-1 rts startOK0 movb 51,IBDR send "Start
Convert T" command brclr IBSR,IBIF, wait
until the byte is shifted out movb IBIF,IBSR
clear the IBIF flag brclr IBSR,RXAK,startOK1
did DS1631A acknowledge? ldab FF rts startOK1
bclr IBCR,MSSL generate a stop
condition ldab 0 normal return code rts
75- Example 11.12 Write a function to set the high
thermostat temperature. The upper and lower bytes
of the high thermostat temperatures are passed in
stack. - Solution
THhi equ 2 THlo equ 3 setTH ldaa 92 jsr sendSla
veID brclr IBSR,RXAK,setTHok1 did DS1631A
acknowledge? ldab FF return error code
-1 rts setTHok1 movb A1,IBDR send out access
TH command / brclr IBSR,IBIF, wait until
command is shifted out movb IBIF,IBSR clear
IBIF flag brclr IBSR,RXAK,setTHok2 did DS1631A
acknowledge? ldab FF rts setTHok2 ldaa THhi,sp
get the upper byte of TH from
stack staa IBDR send out TH high
byte brclr IBSR,IBIF, movb IBIF,IBSR clear
the IBIF flag brclr IBSR,RXAK,setTHok3 did
DS1631A acknowledge? ldab FF rts
76setTHok3 ldaa THlo,sp get the lower byte of TH
from stack staa IBDR brclr IBSR,IBIF, movb IB
IF,IBSR clear the IBIF flag brclr IBSR,RXAK,set
THok4 did DS1631A acknowledge? ldab FF rts s
etTHok4 bclr IBCR,MSSL generate the stop
condition ldab 0 normal return code rts
- Example 11.14 Write a subroutine to read the
converted temperature and return the upper and
lower bytes in double accumulator D. Assume that
the temperature conversion has been started but
this function needs to make sure that the
converted temperature value is resulted from the
most recent Start Convert T command. - Solution
77readTemp ldx 0 initialize return error
code rdLoop jsr readConf is temperature
conversion done yet? cmpb -1 is there any
error? beq rdErr " andb 80 check DONE
bit bpl rdLoop conversion not done
yet? ldaa 92 generate a start condition and
send out jsr sendSlaveID the DS1631A
ID brclr IBSR,RXAK,rdTempok1 did DS1631A
acknowledge? ldx -1 rts rdTempok1
movb AA,IBDR sends "Read Temperature
command" brclr IBSR,IBIF, movb IBIF,IBSR b
rclr IBSR,RXAK,rdTempok2 did DS1631A
acknowledge? ldx -1 rts rdTempok2
bset IBCR,RSTA generate a restart
condition movb 93,IBDR send DS1631A's ID
with R/W set to 1 brclr IBSR,IBIF, movb IBIF,I
BSR brclr IBSR,RXAK,rdTempok3 did DS1631A
acknowledge? ldx -1 rts
78rdTempok3 bclr IBCR,TXRXTXAK prepare to
receive and ACK ldaa IBDR perform a dummy read
brclr IBSR,IBIF, wait for high byte of
temperature to shift in movb IBIF,IBSR
bset IBCR,TXAK prepare send NACK for the last
read ldaa IBDR place the high byte of
Temperature in A brclr IBSR,IBIF, wait for
the low byte read to complete movb IBIF,IBSR
clear the IBIF flag bclr IBCR,MSSL generate a
stop condition ldab IBDR place the low byte of
temperature in B ldx 0 correct return
code rts rdErr ldx -1 rts
79Serial EEPROM 24LC08B
- 1 KB capacity
- Divided into 4 blocks of 256 bytes
- I2C interface
- Baud rate 400 Kbps
- Address input A2, A1, and A0 are not used
8024LC08B Device Address
- The B1 and B0 bits are block addresses of the
location to be accessed. - For any access, the master needs to send in the
8-bit address in addition to the EEPROMs control
byte. This address is an address pointer inside
the 24LC08B.
81Write Operation
- 24LC08B supports byte write and page write
operations. - The 24LC08B has an internal address pointer.
- The address pointer increments by 1 after each
internal access operation.
82Acknowledge Polling (1 of 2)
- The 24LC08B has a buffer to hold the data to be
written into the memory. - The 24LC08B initiates the internal write
operation after the stop condition. - Before the internal operation is complete, the
24LC08B will not accept any new write command. It
will not acknowledge any control byte transfer. - The user can send in the restart condition and
the device ID to determine if the internal write
operation is complete by checking the RXAK bit of
the IBSR register. - The algorithm is illustrated in Figure 11.39.
83Acknowledge Polling (2 of 2)
84Read Operation
- There are three possible read operations
- Current address read
- Random read
- Sequential read
85Current Address Read
- Allows the master to read the byte immediately
following the location accessed by the previous
read or write operation. - On receipt of the slave address with R/W bit set
to 1, the 24LC08B issues an acknowledgement and
transmit an 8-bit data byte. - The master does not acknowledge the transfer, but
asserts a STOP condition and the 24LC08B
discontinues transmission.
86Random Read
- Allow the master to read any memory location in a
random manner. - The master must send the address of the memory
location to be read in addition to the device ID.
87The Procedure of Random Read
- Step 1
- Master asserts a START condition and control byte
with the R/W bit set to 0 to the 24LC08B. - Step 2
- The 24LC08B acknowledges the control byte.
- Step 3
- The master sends the address of the byte to be
read to the 24LC08B. - Step 4
- The 24LC08B acknowledges the byte address.
- Step 5
- The master asserts a Restart condition.
- Step 6
- The master sends the control byte with R/W 1.
- Step 7
- The 24LC08B acknowledges the control byte and
sends data to the master. - Step 8
- The master asserts NACK to the 24LC08B.
- Step 9
- The master asserts the STOP condition.
88Circuit Connection for the 24LC08B
- Example 11.15 Write a function to read a byte
from the 24LC08B. Pass the control byte and
address in accumulators A and B to this
subroutine. Return the data byte and error code
in A and B, respectively. This function should
check the error that the EEPROM did not
acknowledge (implies that 24LC08B may have
failed). - Solution
89EErandomRead jsr sendSlaveID send out 24LC08B
ID and block address brclr IBSR,RXAK,ranRdok0
does EEPROM acknowledge? ldab FF return -1,
if EEPROM does not ack rts ranRdok0 stab IBDR
send out EEPROM memory address brclr IBSR,IBIF,
wait until the address is shifted
out movb IBIF,IBSR clear IBIF
flag brclr IBSR,RXAK,ranRdok1 does EEPROM
acknowledge? ldab FF return -1, if EEPROM
does not ack rts ranRdok1 bset IBCR,RSTA
generate restart condition oraa 01 set R/W
bit for read staa IBDR resend the device
ID brclr IBSR,IBIF, wait until the EEPROM ID
is sent out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,ranRdok2 does EEPROM
acknowledge? ldab FF return -1, if EEROM
does not ack rts
90ranRdok2 bset IBCR,TXAK prepare sent
NACK bclr IBCR,TXRX perform reception ldaa IBD
R dummy read to initiate reception brclr IBSR,I
BIF, wait for a byte to shift
in movb IBIF,IBSR clear the IBIF
flag bclr IBCR,MSSL generate a stop
condition ldaa IBDR get the data
byte ldab 0 normal read status rts
91The C Function to Perform Random Read to the
24LC08B (1 of 2)
char EErandomRead(char ID, char addr)
char dummy SendSlaveID(ID) if
(IBSR RXAK) return -1 IBDR
addr / send out EEPROM address /
while(!(IBSR IBIF)) / wait until the
address is shifted out / IBSR IBIF
/ clear IBIF flag /
92The C Function to Perform Random Read to the
24LC08B (2 of 2)
if (IBSR RXAK) return -1 IBCR
RSTA / generate restart condition /
IBDR ID 0x01 / prepare to read /
while (!(IBSR IBIF)) IBSR IBIF
if (IBSR RXAK) return -1 IBCR
TXAK / prepare to send NACK / IBCR
TXRX / perform reception / dummy
IBDR / dummy read to trigger 9 clock pulses
/ while(!(IBSR IBIF)) / wait for data
to shift in / IBSR IBIF IBCR
MSSL / generate a stop condition /
return IBDR
93- Example 11.16 Write a subroutine that writes a
byte into the 24LC08B. The device ID, memory
address, and data to be written are passed to
this routine in the stack. - Solution
EE_ID equ 5 stack offset for EE_ID EE_addr equ 4
stack offset for EE_addr EE_dat equ 3 stack
offset for EE_data EEbyteWrite psha ldaa EE_ID,s
p get the EEPROM ID from stack jsr sendSlaveID
generate start condition, send EEPROM ID
brclr IBSR,RXAK,bywriteok1 does EEPROM
acknowledge? ldab FF return -1 as the error
code pula rts bywriteok1 ldaa EE_addr,sp get
the address to be accessed from the
stack staa IBDR send address to I2C
bus brclr IBSR,IBIF, wait until address is
shifted out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,bywriteok2 does EEPROM
acknowledge? ldab FF return -1 as the error
code pula rts
94Assembly subroutine to perform byte write
(continued) bywriteok2 ldaa EE_dat,sp get the
data byte to be written from the
stack staa IBDR send out the data
byte brclr IBSR,IBIF, wait until data byte is
shifted out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,bywriteok3 does EEPROM
acknowledge? ldab FF return -1 as the error
code pula rts bywriteok3 bclr IBCR,MSSL
generate stop condition ldab 0 return error
code 0 pula rts
95C function to Perform Byte Write to 24LC08B
char EEbyteWrite(char ID, char addr, char
data) SendSlaveID(ID) if (IBSR
RXAK) / error if EEPROM does not respond /
return -1 IBDR addr / send
out address of the location to be written /
while(!(IBSR IBIF)) IBSR IBIF
/ clear the IBIF flag / if (IBSR RXAK)
/ error if EEPROM does not respond /
return -1 IBDR data / send out
the data byte / while(!(IBSRIBIF))
IBSR IBIF / clear the IBIF flag /
if (IBSR RXAK) / error if EEPROM does not
respond / return -1 IBCR
MSSL / generate a stop condition /
return 0 / normal write code /
96- Example 11.17 Write a function that performs a
pagewrite operation. The control byte, starting
address of destination and the pointer to the
data in RAM to be written are passed to this
function. - Solution
- - It writes a block of up to 16 bytes of data to
the 24LC08B. - - The block of data to be written is pointed to
by X. - - The 24LC08B control byte is passed in A.
- - The starting address of the page is passed in
B. - - The number of bytes to be written is passed in
Y. - - The error code is returned in B.
EEpageWrite jsr sendSlaveID generate start
condition and send out slave ID brclr IBSR,RXAK,p
writeok1 does the EEPROM acknowledge? ldab FF
return error code -1 rts pwriteok1 stab IBDR
send out the starting address to be
written brclr IBSR,IBIF, wait until the byte
is shifted out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,w_loop does the EEPROM
acknowledge? ldab FF return error code
-1 rts
97w_loop cpy 0 beq done_EEwrite byte count is
0, done movb 1,x,IBDR send out one
byte brclr IBSR,IBIF, wait until the byte is
shifted out movb IBIF,IBSR clear the IBIF
flag brclr IBSR,RXAK,okNxt receive
ACK? ldab FF rts okNxt dey decrement byte
count bra w_loop done_EEwrite bclr IBCR,MSSL
generate a stop condition ldab 0 return error
code 0 rts
98char EEpageWrite(char ID, char addr, char
ByteCnt, char ptr) SendSlaveID(ID) /
send out EEPROM ID / if (IBSR RXAK)
return -1 / return -1 if EEPROM did not
respond / IBDR addr / send out
starting address of page write /
while(!(IBSR IBIF)) / wait until the
address is shifted out / IBSR IBIF
/ clear IBIF flag / if (IBSR RXAK)
return -1 / return -1 if EEPROM did
not respond / while(ByteCnt)
IBDR ptr / send out one byte of data /
while(!(IBSR IBIF)) IBSR
IBIF if (IBSR RXAK)
return -1 / return -1 if EEPROM did not
respond / ByteCnt-- IBCR
MSSL / generate a stop condition /
return 0
99- Example 11.18 Write a C function to implement
the algorithm described in Figure 11.38. - Solution
- This function will poll the 24LC08B until it
completes the internal write operation before it
returns.
void eeAckPoll (char ID)
SendSlaveID(ID) while(IBSR RXAK)
IBCR RSTA / generate a restart
condition / IBDR ID / send
out EEPROM ID / while(!(IBSR IBIF))
IBSR IBIF / clear the IBIF flag
/ / continue if EEPROM did not
acknowledge / IBCR MSSL / generate a
stop condition--indispensable /