Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Don Lekei
NII Norsat International Inc.
FIGURE 1:
I2C TIMING
SCL
INTRODUCTION
SDA
tSH
Start
tCL
tCH
Data Bit
More Bits
Stop
1 1 0 1 1 1 1 R/W A
SDA
SCL
MESSAGE FORMAT
A message is always initiated by the master, and begins
with a start condition, followed by a slave address
(7 MSbs) and direction bit (LSb = '1' for READ, '0' for
WRITE). The addressed slave must acknowledge this
byte if it is ready to communicate any data. If the slave
fails to respond, the master should initiate a stop condition and retry.
If the direction bit is '0' the next byte is considered the
sub-address (this is an extension to I2C used by most
multi-register devices). The sub-address selects which
"register" or function subsequent read or write
operations will affect. Any additional bytes will be received
and stored in consecutive locations until a stop is sent. If
the slave is unable to process more data, it could terminate transfer by not acknowledging the last byte.
DS00541E-page 1
AN541
If the direction bit is '1', the slave will transfer successive
bytes to the master (the master holds the line at '1'),
while the master acknowledges each byte with a '0' in
the ninth bit. The master can terminate the transfer by
not acknowledging the last byte, while the slave can
stop the transfer by generating a stop condition.
FIGURE 3:
Reset
Initialize I2C Ports
IMPLEMENTATION
FIGURE 2:
SDA and
SCL both High?
Yes
SCHEMATIC OF I2C
CONNECTIONS
1, 1
Test
SCL, SDA
1, 0
Stop
Clock in 8-bits
+5V
R2*
No
SDA
Slave
address correct?
Yes
SCL
Send ACK
+5V
U1
1
2
3
4
5
6
7
8
9
RA2
RA3
T0CKI
MCLR
VSS
RB0
RB1
RB2
RB3
RA1
RA0
OSC1
OSC2
VDD
RB7
RB6
RB5
RB4
18
17
16
15
14
13
12
11
10
PIC16C5X
No
Bit = 0?
Stop
Yes
Clock in 8-bits
100
Send ACK
Get sub-address
Send ACK
X1
20 MHz
Process Byte
15 pF
15 pF
Yes No
Stop?
DS00541E-page 2
No
Stop?
Yes
User Message
Cleanup Code
Clock in 8-bits
Send ACK
Get Sub-Address
Process Message
AN541
When the initial subaddress is 0, the flag B_ID is set.
This is used to indicate access to a special channel. In
this case, the data channel is used to return an ID
message, or output data to PORTB, however the
natural extension would be to use this as a data I/O
channel.
To make the basic device routines easily adaptable to a
variety of uses, macros are used to implement the
application specific code. This allows the developer the
option of using subroutine calls, or in-line code to avoid
the 4 clock cycle overhead and use of the precious
stack.
Macro
USER_MAIN
USER_Q
USER_MSG
USER_RECV
USER_XMIT
References:
DS00541E-page 3
AN541
Please check the Microchip BBS for the latest version of the source code. Microchips Worldwide Web Address:
www.microchip.com; Bulletin Board Support: MCHIPBBS using CompuServe (CompuServe membership not
required).
APPENDIX A: I2C.ASM
MPASM 01.40 Released
00000676
00000000
000001FF
01FF
01FF
01FF 0A0B
DS00541E-page 4
I2C.ASM
1-16-1997
14:51:28
PAGE
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
LIST
P=16C54, C=80, N=0, R=DEC
;
;*****************************************************************
;
;
Program:
I2C.ASM
;
Revision Date:
;
1-13-97
Compatibility with MPASMWIN 1.40
;
;***************************************************************
;
CPU
EQU
1654
SIM
EQU
0
;Change timing constants for simulator
IF
_RESVEC EQU
ENDIF
(CPU==1654) || (CPU==1655)
01FFH
;16c54 start address
IF
_RESVEC EQU
ENDIF
CPU==1656
03FFH
IF
_RESVEC EQU
ENDIF
CPU==1657
07FFH
_RESVEC
GOTO
INIT
RESVEC
;
;
;
;***********************************************************
;***********************************************************
;* Macros to set/clear/branch/skip on bits
;* These macros define and use synthetic bit labels
;* Bit labels contain the address and bit of a location
;*
;**********************************************************************
;*
Usage
Description
;*
----------------------- --------------------;*
BIT
label,bit,file ;Define a bit label
;*
SEB
label
;set bit using bit label
;*
CLB
label
;clear bit using bit label
;*
SKBS
label
;SKIP on bit set
;*
SKBC
label
;SKIP on bit clear
;*
BBS
label,address
;BRANCH on bit set
;*
BBC
label,address
;BRANCH on bit clear
;*
CBS
label,address
;CALL on bit set
;*
CBC
label,address
;CALL on bit clear
;*
;**********************************************************************
BIT
MACRO
label,bit,file
AN541
00000000
00000000
00000001
00000001
0000
0000
0001
0002
0003
00000300
00000301
00000302
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
M
00115
M
00116
M
00117
label
EQU
file<<8|bit
;(macro)
;
label
BSF
label>>8,label &7
;Set bit
;(macro)
;
label
BCF
label>>8,label &7
;Clear bit
;(macro)
;
label
BTFSS
label>>8,label &7
label
BTFSC
label>>8,label &7
ENDM
SEB
MACRO
ENDM
CLB
MACRO
ENDM
SKBS
MACRO
ENDM
SKBC
MACRO
ENDM
BBS
MACRO
label,address
BTFSC label>>8,label &7
GOTO
address
label,address
BTFSS label>>8,label &7
GOTO
address
label,address
CALL
label>>8,label
;
ENDM
BBC
MACRO
ENDM
CBS
MACRO
ENDM
CBC
MACRO
label,address
CALL
label>>8,label
&7
ENDM
EQU
EQU
EQU
EQU
0
0
1
1
;For
;For
;For
;For
file,W
file,W
file,F
file,F
;*******************************************************************
;* REGISTER DECLARATIONS
;*******************************************************************
ind
TMR0
PC
STATUS
ORG
RES
RES
RES
RES
1
1
1
1
BIT
B_C,0,STATUS
EQU
STATUS<<8|0
B_DC,1,STATUS
EQU
STATUS<<8|1
B_Z,2,STATUS
EQU
STATUS<<8|2
B_PD,3,STATUS
;Carry
;(macro)
;Half carry
;(macro)
;Zero
;(macro)
;Power down
DS00541E-page 5
AN541
00000303
00000304
00000305
00000306
00000307
0004
0005
0006
0007
00000700
00000701
00000702
00000703
0008
0009
000A
0000000B
000B
0000000C
000C
0000000D
000D
0000000E
000E
0000000F
000F
00000010
0010
00000011
0011
00000012
0012
DS00541E-page 6
M
00118
M
00119
M
00120
M
00121
M
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
M
00136
M
00137
M
00138
M
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
B_PD
BIT
B_TO
BIT
B_PA0
BIT
B_PA1
BIT
B_PA2
EQU
STATUS<<8|3
B_TO,4,STATUS
EQU
STATUS<<8|4
B_PA0,5,STATUS
EQU
STATUS<<8|5
B_PA1,6,STATUS
EQU
STATUS<
B_PA2,7,STATUS
EQU
STATUS<<8|7
;(macro)
;Timeout
;(macro)
;Page select (56/57 only)
;(macro)
;Page select (56/57 only)
;(macro)
;GP flag
;(macro)
;4=file select reg 0-4 =indirect address
;5=port A I/O register (4 bits)
;6=port B I/O register
FSR
PORTA
PORTB
RES
RES
RES
1
1
1
PORTC
IF
RES
ENDIF
(CPU==1655)||(CPU==1657)
1
;7=I/O port C on 16C54/56 only
;**********************************************************************
;* 8 Pseudo registers accessed by sub-addresses 1-8
;* (address 0 accesses the ID string)
;* these are read-write registers
;**********************************************************************
I2CR0
EQU
RES
$
1
;Sub-address 8
;8 pseudo registers
I2CR1
EQU
RES
$
1
;Sub-address 1
I2CR2
EQU
RES
$
1
;Sub-address 2
I2CR3
EQU
RES
$
1
;Sub-address 3
I2CR4
EQU
RES
$
1
;Sub-address 4
I2CR5
EQU
RES
$
1
;Sub-address 5
I2CR6
EQU
RES
$
1
;Sub-address 6
I2CR7
EQU
RES
$
1
;Sub-address 7
AN541
000000D6
000000F7
000000F6
000000F7
00000500
00000501
00000000
000000FF
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
M
00193
M
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
0D6H
;**************************************************************
;** PORTA DEFINITIONS
;** I2C interface uses PORTA
;** note SDA goes to A0 for code efficiency
;**
;***************************************************************
TAREAD EQU
TAWRITE EQU
TAINIT EQU
BIT
B_SDA
BIT
B_SCL
;spare
;spare
B11110111
B11110110
TAREAD
B_SDA,0,PORTA
EQU PORTA<<8|0
B_SCL,1,PORTA
EQU PORTA<<8|1
B_???,2,PORTA
B_???,3,PORTA
;**************************************************************
;**
;** Port B definition (Parallel out)
;**
;****************************************************************
TBINIT EQU
B00000000
;Port B tris (all output)
PBINIT EQU
B11111111
;Port B init
;**********************************************************************
;* Macros to contain user POLL loop code.
;* These are implemented as macros to allow ease of modification,
;* especially in real-time applications. The functions could be coded
;* as in-line code or as subroutines depending on ROM/time tradeoffs.
;*
;* USER_MAIN:
Decision or code to perform at idle time
;*
;* USER_Q:
Quick code for use during transfer - max 8 s for
;*
full I2C Spec. More than 4s may result in I2C
;*
retries (at full spec speed.
;*
;* USER_MSG:
Code to execute at receipt of I2C command.
;*
;**********************************************************************
USER_MAIN
MACRO
;*** This would be user code for idle loop
ENDM
USER_Q
MACRO
;*** This would be quick user code
ENDM
USER_MSG
MACRO
;*** This would be user code to process a message
ENDM
USER_RECV
MACRO
;*** This would be user code to process a received byte
;*** example code sends sub-address 0 to port b
BBC
B_ID,_NXI_notid ;Channel 0! Bit set if INITIAL address was 0
MOVFW
I2CREG
;get received byte
DS00541E-page 7
AN541
0000
0000
0000 0209
0001 0E07
0002 01E2
0003
0004
0005
0006
0007
0008
0009
000A
0850
0849
0843
0849
0832
0843
0800
0800
DS00541E-page 8
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
MOVWF
PORTB
GOTO
IN_CONT
_NXI_notid
ENDM
USER_XMIT
MACRO
;*** This would be user code to prepare an output byte
;*** example code sends id string to output
BBC
B_ID,_NXO_notid ;Channel 0! Bit set if INITIAL address was 0
CALL
GETID
;get next byte from ID channel
GOTO
OUT_CONT
;and send it
_NXO_notid
ENDM
;*******************************************************************
; START OF CODE
;*******************************************************************
ORG
0
;*******************************************************************
;* Device ID Table (must be at start)
;* TABLE FOR UNIT ID returns next char in W
;*******************************************************************
GETID
MOVFW
I2CSUBA
;W=I2CSUBA
ANDLW
07H
;Limit to 8 locations
ADDWF
PC,F
;**********************************************************************
;* Device ID text: read starting at sub-address 0
;**********************************************************************
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
P
I
C
I
2
C
0
0
;**********************************************************************
;* I2C Device routines
;*
;* Enable must be HIGH, else state goes to 0
;* write is to me, read is from me.
;*
;*
<============== first byte / subsequent writes =====> <end>
;*
;* SDA
--|X-----X-----X-----X-----X-----X-----X-----X---X------| |-;*
|---X-----X-----X-----X-----X-----X-----X-----X---X******|--|
;* (bit)
s
7
6
5
4
3
2
1
0
ackout
;* SCL -----| |--| |--| |--| |--| |--| |--| |--| |--|
;*
|--| |--| |--| |--| |--| |--|--| |--| |--|
;*
;* STATE: 0 1 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 4 5 6 2 3 0
;*
;*
<============== subsequant reads ===================>
;*
;* SDA
X-----X-----X-----X-----X-----X-----X-----X----X------X----;*
--X-----X-----X-----X-----X-----X-----X-----X----X******X----;* (bit)ack
7
6
5
4
3
2
1
0
ackin
;* SCL --| |--| |--| |--| |--| |--| |--| |--| |--| |--| |-;*
|--| |--| |--| |--| |--| |--| |--| |--| |--| |--|
;*
;* STATE: 7 8 7 8 7 8 7 8 7 8 7 8 7 8 7 8 9 A 7 8
AN541
000B
000B
000B
000C
000D
000E
000F
0010
0CF7
0005
0C00
0006
0CFF
0026
0011
0011 0004
0012 0427
0013 0447
0014 0407
0015
0015 0004
0016 0605
0017
0017 0725
0018 0A15
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
M
00353
M
00354
M
00355
00356
00357
00358
00359
M
00360
00361
M
00362
00363
M
00364
;*
;*
<============== Final READ =========================>
;*
;* SDA
X-----X-----X-----X-----X-----X-----X-----X----X-|**|------;*
--X-----X-----X-----X-----X-----X-----X-----X----X*|--|
;* (bit)ack
7
6
5
4
3
2
1
0
ackin
;* SCL --| |--| |--| |--| |--| |--| |--| |--| |--| |--------;*
|--| |--| |--| |--| |--| |--| |--| |--| |--|
;*
;* STATE: 7 8 7 8 7 8 7 8 7 8 7 8 7 8 7 8 9 A 0 0
;*
;* STATE B is an ignore bit state for non-addressed bits
;* STATE C indicates last sample had ENA low on rising
;* edge of ENA, DATA LOW = low voltage, DATA&CLOCK low = RESET
;*****************************************************************
;I2C interface uses PORTA
;note SDA must be on PORTA,0 for code efficiency
;*****************************************************************
;** INIT
;** Hardware reset entry point
;**
;*****************************************************************
INIT
;Power-on entry
;*****************************************************************
;** RESET
;** software reset entry point
;**
;*****************************************************************
RESET
;Soft reset
MOVLW
TRIS
MOVLW
TRIS
MOVLW
MOVWF
TAINIT
PORTA
TBINIT
PORTB
PBINIT
PORTB
;Init ports
;*****************************************************************
; Main wait loop while idle. POLL loop should be called here
;
;*****************************************************************
I2CWAIT
CLRWDT
CLB
BCF
CLB
BCF
CLB
BCF
B_UA
B_UA>>8,B_UA&7
B_SA
B_SA>>8,B_SA&7
B_RD
B_RD>>8,B_RD&7
loop1
CLRWDT
USER_MAIN
;Call user code while in idle state
;*** This would be user code for idle loop
SKBC
BTFSC
B_SDA
;Wait for SDA&SCL=H
B_SDA>>8,B_SDA&7 ;(macro)
SKBS
BTFSS
GOTO
B_SCL
B_SCL>>8,B_SCL&7
loop1
loop2
;
;(macro)
; No longer valid to wait for start!
DS00541E-page 9
AN541
0019 0004
001A 0625
001B 0605
001C 0A17
001D
001D 0605
001E 0A11
001F 0625
0020 0A1D
0021
0021 0004
0022 0C01
0023 0028
0024
0024
0024 0725
0025 0A24
0026
0027
0028
0029
0305
0368
0603
0A36
002A 0608
002B 0A31
002C
002C 0725
002D 0A24
002E 0705
002F 0A2C
0030
0030 0A11
0031 0705
0032 0A11
DS00541E-page 10
00365
00366
00367
00368
M
00369
00370
00371
M
00372
M
00373
00374
00375
00376
00377
M
M
00378
M
M
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
M
00394
00395
M
M
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
M
M
00407
M
00408
00409
00410
M
00411
00412
00413
M
M
CLRWDT
USER_MAIN
;Call user code while in idle state
;*** This would be user code for idle loop
;** wait for start **
SKBC
B_SCL
BTFSC B_SCL>>8,B_SCL&7
SKBC
B_SDA
BTFSC B_SDA>>8,B_SDA&7
GOTO
loop2
NEXTBYTE
CLRWDT
MOVLW
MOVWF
1
I2CREG
;*Shift bits! external poll may be executed during low clock cycle only!
;*ENABLE line is checked for loss of enable ONLY during HIGH CLOCK
;*** CLOCK IS LOW -- DATA MAY CHANGE HERE
;*** We have at least 4 s before any change can occur
loop4
USER_Q
;*** This would
loop4A
BBC
BTFSS
GOTO
I2CREG,0
ii_1
BBC
BTFSS
GOTO
SKBS
BTFSS
GOTO
B_SCL,loop4
B_SCL>>8,B_SCL&7
loop4
B_SDA
B_SDA>>8,B_SDA&7
ii_0
ii_0
I2CSTOP
USER_MSG
;process completed message!
;*** This would be user code to process a message
GOTO
I2CWAIT
;back to main loop
ii_1
BBC
BTFSS
GOTO
B_SDA,I2CWAIT
B_SDA>>8,B_SDA&7
I2CWAIT
AN541
0033 0725
0034 0A24
0035 0A31
0036
0036 0727
0037 0A8B
0038 0647
0039 0A97
003A
003B
003C
003D
003E
003F
0767
0A3F
0208
0026
0A47
003F
0040
0041
0042
0043
0044
0045
0046
0C07
0169
0C0B
01C9
02A9
0024
0208
0020
0047
0047
0047 0625
0048 0A47
0049 0405
004A 0CF6
004B 0005
004C 0405
004D
004D 0725
004E 0A4D
004F
004F 0625
00414
M
M
00415
00416
00417
00418
M
M
00419
M
M
00420
00421
00422
00423
00424
00425
00426
00427
M
M
M
M
M
M
M
M
M
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
M
M
00442
00443
M
00444
00445
00446
M
00447
00448
00449
00450
M
00451
M
M
00452
00453
00454
M
00455
M
BBC
BTFSS
GOTO
GOTO
B_SCL,loop4
B_SCL>>8,B_SCL&7
loop4
ii_1
low
BBC
BTFSS
GOTO
BBS
BTFSC
GOTO
B_UA,ACK_UA
B_UA>>8,B_UA&7
ACK_UA
B_SA,ACK_SA
B_SA>>8,B_SA&7
ACK_SA
ACK_I2C
;****
;** Do what must be done with new data bytes here (before ACKloop)
;** Dont ack if byte cant be processed!
;****
;-------USER_RECV
;*** This would be user code to process a received byte
;*** example code sends sub-address 0 to port b
BBC
B_ID,_NXI_notid ;Channel 0! Bit set if INITIAL address was 0
BTFSS
B_ID>>8,B_ID&7
;(macro)
GOTO
_NXI_notid
;(macro)
MOVFW
I2CREG
;get received byte
MOVWF
PORTB
;and write it on portb
GOTO
IN_CONT
_NXI_notid
MOVLW
ANDWF
MOVLW
ADDWF
INCF
MOVWF
MOVFW
MOVWF
07H
I2CSUBA,f
I2CR0
I2CSUBA,W
I2CSUBA, F
FSR
I2CREG
ind
IN_CONT
;Register count
;Limit register count
;Pseudo-registers
;Offset from buffer start
;Next sub-address
;Indirect address
;Put data into register
;continue point for intercepted bytes
ACKloop
BBS
BTFSC
GOTO
B_SCL,ACKloop
B_SCL>>8,B_SCL&7
ACKloop
CLB
BCF
MOVLW
TRIS
CLB
BCF
B_SDA
B_SDA>>8,B_SDA&7
TAWRITE
PORTA
B_SDA
B_SDA>>8,B_SDA &7
;Set ACK
;(macro)
ACKloop2
USER_Q
;*** This would
BBC
BTFSS
GOTO
ACKloop3
USER_Q
;*** This would be quick user code
BBS
B_SCL,ACKloop3
;Wait for clock low
BTFSC
B_SCL>>8,B_SCL&7 ;(macro)
DS00541E-page 11
AN541
0050 0A4F
0051 0CF7
0052 0005
0053 0707
0054 0A21
0055
0055
0056
0057
0058
0059
0767
0A59
0900
0A60
0059
005A
005B
005C
005D
005E
005F
0C07
0169
0C0B
01C9
02A9
0024
0200
0060
0060 0028
0061 0C08
0062 002A
0063
0063 0368
0064 0603
0065 0A79
0066 0405
0067 0CF6
0068 0005
0069 0405
DS00541E-page 12
M
00456
00457
00458
00459
00460
M
M
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
M
M
M
M
M
M
M
M
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
M
00506
00507
00508
M
GOTO
ACKloop3
;(macro)
MOVLW
TRIS
TAREAD
PORTA
;End ACK
BBC
BTFSS
GOTO
B_RD,NEXTBYTE
B_RD>>8,B_RD&7
NEXTBYTE
;*********************************************************************
; I2C Readback (I2C read request)
; Application specific code to get bytes to send may be added here.
; This routine gets data from location pointed to by I2CSUBA and
; sends it to I2C. Subsequent reads get sequential addresses. This
; version ANDs the register # with 7 to limit to 8 registers (for
; speed). Thiscould be modified to do a comparison to an Absolute
; number.
;*********************************************************************
NEXTOUT
;*** <<< PUT NEXT BYTE INTO I2CREG HERE NOW! >>> ***
USER_XMIT
;*** This would be user code to prepare an output byte
;*** example code sends id string to output
BBC
B_ID,_NXO_notid ;Channel 0! Bit set if INITIAL address was 0
BTFSS
B_ID>>8,B_ID&7 ;(macro)
GOTO
_NXO_notid
;(macro)
CALL
GETID
;get next byte from ID channel
GOTO
OUT_CONT
;and send it
_NXO_notid
MOVLW
ANDWF
MOVLW
ADDWF
INCF
MOVWF
MOVFW
07H
I2CSUBA,f
I2CR0
I2CSUBA,W
I2CSUBA, F
FSR
ind
;Register count
;Limit register count
;Pseudo-registers
;Offset from buffer start
;Next sub-address
;Indirect address
;Get data from register
OUT_CONT
MOVWF
I2CREG
;-- add code here to init I2CREG! when B_ID is clear!
MOVLW
8
;Bit counter
MOVWF
I2CBITS
;** OUT bits! -- external poll may be executed during low clock cycle,
;
but may also be executed during high cycle if necessary.
;* ENABLE line is checked for loss of enable ONLY during HIGH CLOCK
;*** CLOCK IS LOW -- CHANGE DATA HERE FIRST!
;*** loop 1: data was 1
iiOUT_loop_1
RLF
I2CREG,F
;Shift data out, MSB first
SKPNC
;1->0: change
GOTO
iiOUT_1
;Output another 1!
CLB
B_SDA
;Output 0
BCF
B_SDA>>8,B_SDA&7 ;(macro)
MOVLW
TAWRITE
TRIS
PORTA
CLB
B_SDA
;Set data (just in case docs are wrong)
BCF
B_SDA>>8,B_SDA&7 ;(macro)
AN541
006A
006A 0004
006B
006B 0725
006C 0A6B
006D
006D 0625
006E 0A6D
006F
0070
0071
0072
0073
02EA
0A74
0CF7
0005
0A80
0074
0074 0368
0075 0703
0076 0A6A
0077 0CF7
0078 0005
0079
0079 0004
007A
007A 0725
007B 0A7A
007C
007C 0625
007D 0A7C
007E 02EA
007F 0A63
0080
0080 02A9
0081
0081 0725
0082 0A81
00509
00510
00511
00512
00513
M
00514
00515
00516
M
M
00517
00518
M
00519
00520
00521
M
M
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
M
00542
00543
00544
M
M
00545
00546
00547
M
00548
00549
00550
M
M
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
M
M
iiOUT_0
CLRWDT
USER_Q
;*** This would be quick user code
iiOUT_loop_02
BBC
BTFSS
GOTO
USER_Q
;*** This would be quick user code
iiOUT_loop_03
BBS
BTFSC
GOTO
DECFSZ
GOTO
MOVLW
TRIS
GOTO
iiOUT_loop_0
RLF
SKPC
GOTO
MOVLW
TRIS
;Count bits
;Loop for last bit 0
;Done with last bit 0... Set to 1 for ACK
I2CREG,F
iiOUT_0
TAREAD
PORTA
;Get ACK
;Set to 1
iiOUT_1
CLRWDT
USER_Q
;*** This would be quick user code
iiOUT_loop_12
BBC
BTFSS
GOTO
USER_Q
;*** This would be quick user code
iiOUT_loop_13
BBS
BTFSC
GOTO
DECFSZ
GOTO
;Count bits
;Loop for last bit 1
;Next sub-address
DS00541E-page 13
AN541
00561
00562
0083 0605
M
0084 0A11
M
00563
00564
00565
0085
00566
00567
0085 0725
M
0086 0A55
M
00568
00569
0087 0605
M
0088 0A85
M
0089 0A11
00570
008A
00571
00572
008A 0A11
00573
00574
00575
00576
00577
00578
00579
008B
00580
00581
008B 0527
M
008C 0608
00582
00583
008D 0507
M
008E 0208
00584
008F 0EFE
00585
0090 0FD6
00586
0091 0743 0A11 00587
00588
0093 0607
M
0094 0A47
M
00589
0095 0547
M
0096 0A47
00590
00591
00592
00593
00594
00595
0097
00596
00597
0097 0447
M
00598
0098 0467
M
0099 0208
00599
009A 0643
00600
00601
009B 0567
M
009C 0029
00602
009D 0A47
00603
00604
00605
00606
DS00541E-page 14
BBS
BTFSC
GOTO
B_SDA,I2CWAIT
;No ACK --- wait for restart!
B_SDA>>8,B_SDA&7
;(macro)
I2CWAIT
;(macro)
B_SCL,NEXTOUT
;Wait for clock low - output next char!
B_SCL>>8,B_SCL&7
;(macro)
NEXTOUT
;(macro)
B_SDA,iiOUT_loop_a3
B_SDA>>8,B_SDA&7
iiOUT_loop_a3
I2CWAIT
I2CWAIT
;**********************************************************************
;* Unit address received - check for valid address
;*
;**********************************************************************
ACK_UA
SEB
B_UA
;Flag unit address received
BSF
B_UA>>8,B_UA&7
;(macro)
BTFSC
I2CREG,0
;Skip if data coming in
SEB
B_RD
;Flag - reading from slave
BSF
B_RD>>8,B_RD&7
;(macro)
MOVF
I2CREG,W
;Get address
ANDLW
0FEH
;Mask direction flage before compare
XORLW
DEVICE_ADDRESS
;Device address
BNZ
I2CWAIT
;Not for me! (skip rest of message)
BBS
B_RD,ACKloop
;Read - no secondary address
BTFSC
B_RD>>8,B_RD&7
;(macro)
GOTO
ACKloop
;(macro)
SEB
B_SA
;Next is secondary address
BSF
B_SA>>8,B_SA&7
;(macro)
GOTO
ACKloop
;Yes! ACK address and continue!
;**********************************************************************
;* Secondary address received - stow it!
;* SA = 0 is converted to 128 to facilitate ID read
;**********************************************************************
ACK_SA
CLB
B_SA
;Flag second address received
BCF
B_SA>>8,B_SA&7
;(macro)
CLB
B_ID
BCF
B_ID>>8,B_ID&7
;(macro)
MOVFW
I2CREG
;Get subaddress
SKPNZ
;Not 0
SEB
B_ID
;Flag - id area selected
BSF
B_ID>>8,B_ID&7
;(macro)
MOVWF
I2CSUBA
;Set subaddress
GOTO
ACKloop
END
AN541
MEMORY USAGE MAP (X = Used,
0000
0040
0080
01C0
:
:
:
:
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
- = Unused)
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXX-----------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
-------------------------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
------------------------------X
Errors
:
Warnings :
Messages :
0
0 reported,
0 reported,
159
353
0 suppressed
0 suppressed
DS00541E-page 15
AMERICAS (continued)
Corporate Office
Toronto
Singapore
Atlanta
Boston
Microchip Technology Inc.
5 Mount Royal Avenue
Marlborough, MA 01752
Tel: 508-480-9990 Fax: 508-480-8575
Chicago
Microchip Technology Inc.
333 Pierce Road, Suite 180
Itasca, IL 60143
Tel: 630-285-0071 Fax: 630-285-0075
Dallas
Microchip Technology Inc.
4570 Westgrove Drive, Suite 160
Addison, TX 75248
Tel: 972-818-7423 Fax: 972-818-2924
Dayton
Microchip Technology Inc.
Two Prestige Place, Suite 150
Miamisburg, OH 45342
Tel: 937-291-1654 Fax: 937-291-9175
Detroit
Microchip Technology Inc.
Tri-Atria Office Building
32255 Northwestern Highway, Suite 190
Farmington Hills, MI 48334
Tel: 248-538-2250 Fax: 248-538-2260
Los Angeles
Microchip Technology Inc.
18201 Von Karman, Suite 1090
Irvine, CA 92612
Tel: 949-263-1888 Fax: 949-263-1338
New York
Microchip Technology Inc.
150 Motor Parkway, Suite 202
Hauppauge, NY 11788
Tel: 631-273-5305 Fax: 631-273-5335
San Jose
Microchip Technology Inc.
2107 North First Street, Suite 590
San Jose, CA 95131
Tel: 408-436-7950 Fax: 408-436-7955
ASIA/PACIFIC
Hong Kong
ASIA/PACIFIC (continued)
Taiwan, R.O.C
Microchip Technology Taiwan
10F-1C 207
Tung Hua North Road
Taipei, Taiwan, ROC
Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
EUROPE
Beijing
United Kingdom
India
Denmark
Japan
France
Korea
Germany
Shanghai
Microchip Technology
RM 406 Shanghai Golden Bridge Bldg.
2077 Yanan Road West, Hong Qiao District
Shanghai, PRC 200335
Tel: 86-21-6275-5700 Fax: 86 21-6275-5060
Italy
11/15/99
All rights reserved. 1999 Microchip Technology Incorporated. Printed in the USA. 11/99
Information contained in this publication regarding device applications and the like is intended for suggestion only and may be superseded by updates. No representation or warranty is given and no liability is assumed
by Microchip Technology Incorporated with respect to the accuracy or use of such information, or infringement of patents or other intellectual property rights arising from such use or otherwise. Use of Microchips products
as critical components in life support systems is not authorized except with express written approval by Microchip. No licenses are conveyed, implicitly or otherwise, under any intellectual property rights. The Microchip
logo and name are registered trademarks of Microchip Technology Inc. in the U.S.A. and other countries. All rights reserved. All other trademarks mentioned herein are the property of their respective companies.