📄 i2c.s
字号:
.module I2C.c
.area text(rom, con, rel)
.dbfile E:\MyWorks\SOFT\I2C_E2PROM\I2C.c
.dbfunc e Init_I2C _Init_I2C fV
.even
_Init_I2C::
.dbline -1
.dbline 22
; // *************** I2C driver V 1.0 ***************
; // *** Written By P. Fletcher-Jones ***
; // *** Written on 16/11/01 ***
; // *** Last MOD 21/11/01 ***
; // *** Compiled using ImageCraft C Comiler ***
; // *******************************************************
;
; #include <iom1281v.h>
; #include <MACROS.h>
;
; #include "DC_Defines.h"
;
;
; #include "I2C.h"
;
;
; // ******************************************** //
; // *** This routine will setup the I2C Port *** //
; // ******************************************** //
;
; void Init_I2C(void)
; {
.dbline 23
; SETBIT(I2C_DIR,SCL); // Set SCL to output
sbi 0xa,0
.dbline 24
; SETBIT(I2C_DIR,SDA ); // Set SDA to output
sbi 0xa,1
.dbline 26
;
; SETBIT(I2C_PORT,SCL); // Set SCL high
sbi 0xb,0
.dbline 27
; SETBIT(I2C_PORT,SDA ); // Set SDA high
sbi 0xb,1
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e I2C_Start _I2C_Start fV
.even
_I2C_Start::
.dbline -1
.dbline 37
; }
;
;
;
; // ************************************************ //
; // *** This routine will send the I2C Start Bit *** //
; // ************************************************ //
;
; void I2C_Start (void)
; {
.dbline 38
; SETBIT(I2C_PORT,SCL); // Set SCL High
sbi 0xb,0
.dbline 39
; SETBIT(I2C_PORT,SDA); // Set SDA High
sbi 0xb,1
.dbline 41
;
; SETBIT(I2C_DIR,SDA); // Set SDA to output
sbi 0xa,1
.dbline 42
; CLEARBIT(I2C_PORT,SDA); // Clear SDA
cbi 0xb,1
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbend
.dbfunc e I2C_Stop _I2C_Stop fV
.even
_I2C_Stop::
.dbline -1
.dbline 51
; }
;
;
; // *********************************************** //
; // *** This routine will send the I2C Stop Bit *** //
; // *********************************************** //
;
; void I2C_Stop (void)
; {
.dbline 53
;
; SETBIT(I2C_DIR,SDA); // Set SDA to output
sbi 0xa,1
.dbline 55
;
; CLEARBIT(I2C_PORT,SCL); // Clear SCL
cbi 0xb,0
.dbline 56
; CLEARBIT(I2C_PORT,SDA); // Clear SDA
cbi 0xb,1
.dbline 58
;
; SETBIT(I2C_PORT,SCL); // Set SCL High
sbi 0xb,0
.dbline 59
; SETBIT(I2C_PORT,SDA); // Set SDA High
sbi 0xb,1
.dbline -2
L3:
.dbline 0 ; func end
ret
.dbend
.dbfunc e I2C_Clock _I2C_Clock fV
.even
_I2C_Clock::
.dbline -1
.dbline 71
; }
;
;
;
;
;
; // ************************************************** //
; // *** This routine will send the I2C clock pulse *** //
; // ************************************************** //
;
; void I2C_Clock (void)
; {
.dbline 72
; SETBIT(I2C_PORT,SCL); // Set SCL high
sbi 0xb,0
.dbline 73
; NOP(); // Small Delay
nop
.dbline 74
; CLEARBIT(I2C_PORT,SCL); // Set SCL low
cbi 0xb,0
.dbline -2
L4:
.dbline 0 ; func end
ret
.dbend
.dbfunc e Write_I2C_Byte _Write_I2C_Byte fV
; i -> R20
; byte -> R22
.even
_Write_I2C_Byte::
st -y,R20
st -y,R22
mov R22,R16
.dbline -1
.dbline 85
; }
;
;
;
;
; // ******************************************************** //
; // *** This routine will write a byte to the I2C device *** //
; // ******************************************************** //
;
; void Write_I2C_Byte(unsigned char byte)
; {
.dbline 88
; unsigned char i;
;
; SETBIT(I2C_DIR,SDA); // Set SDA to output
sbi 0xa,1
.dbline 89
; CLEARBIT(I2C_PORT,SCL);
cbi 0xb,0
.dbline 91
;
; for (i = 0; i < 8; i++){ // Loop for our 8 bits
clr R20
xjmp L9
L6:
.dbline 91
.dbline 94
;
; // Set or Clear SDA pin
; if((byte & 0x80) == 0x80) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R22
andi R24,128
cpi R24,128
brne L10
X0:
.dbline 94
sbi 0xb,1
xjmp L11
L10:
.dbline 95
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L11:
.dbline 97
;
; SETBIT(I2C_PORT,SCL); // Set SCL High, Clock data
sbi 0xb,0
.dbline 99
;
; byte = byte << 1; // Shift data in buffer right one
lsl R22
.dbline 101
;
; CLEARBIT(I2C_PORT,SCL); // Clear SCL
cbi 0xb,0
.dbline 102
; }
L7:
.dbline 91
inc R20
L9:
.dbline 91
cpi R20,8
brlo L6
X1:
L12:
.dbline 105
;
;
; while(I2C_Ackn() ); // Check for acknowledge from I2C device
L13:
.dbline 105
xcall _I2C_Ackn
tst R16
brne L12
X2:
.dbline -2
L5:
.dbline 0 ; func end
ld R22,y+
ld R20,y+
ret
.dbsym r i 20 c
.dbsym r byte 22 c
.dbend
.dbfunc e Read_I2C_Byte _Read_I2C_Byte fc
; i -> R22
; buff -> R20
.even
_Read_I2C_Byte::
st -y,R20
st -y,R22
.dbline -1
.dbline 117
; }
;
;
;
;
;
; // ********************************************************* //
; // *** This routine will read a byte from the I2C device *** //
; // ********************************************************* //
;
; unsigned char Read_I2C_Byte(void)
; {
.dbline 118
; unsigned char i,buff = 0;
clr R20
.dbline 120
;
; for (i = 0; i < 8; i++){
clr R22
xjmp L19
L16:
.dbline 120
.dbline 122
;
; buff = buff << 1;
lsl R20
.dbline 124
;
; CLEARBIT(I2C_DIR,SDA); // Set SDA to input
cbi 0xa,1
.dbline 126
;
; SETBIT(I2C_PORT,SCL); // Set SCL High,Clock bit out
sbi 0xb,0
.dbline 129
;
; // Read data on SDA pin
; if ( CHECKBIT( I2C_IN,SDA ) ) buff = buff | 0x01;
sbis 0x9,1
rjmp L20
X3:
.dbline 129
ori R20,1
L20:
.dbline 131
;
; CLEARBIT(I2C_PORT,SCL); // Clear SCL
cbi 0xb,0
.dbline 132
; }
L17:
.dbline 120
inc R22
L19:
.dbline 120
cpi R22,8
brlo L16
X4:
.dbline 136
;
; // *** No ACK *** //
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 138
;
; return buff; // Return our I2C byte
mov R16,R20
.dbline -2
L15:
.dbline 0 ; func end
ld R22,y+
ld R20,y+
ret
.dbsym r i 22 c
.dbsym r buff 20 c
.dbend
.dbfunc e I2C_Ackn _I2C_Ackn fc
; Ackn -> R16
.even
_I2C_Ackn::
.dbline -1
.dbline 149
; }
;
;
;
;
; // *********************************************************************** //
; // *** This routine returns a 0 if the I2C device sends an acknowledge *** //
; // *********************************************************************** //
;
; unsigned char I2C_Ackn(void)
; {
.dbline 150
; unsigned char Ackn = 0; // Temp RAM for Ackn flag
clr R16
.dbline 152
;
; CLEARBIT(I2C_PORT,SCL);
cbi 0xb,0
.dbline 153
; CLEARBIT(I2C_DIR,SDA); // Set SDA to input
cbi 0xa,1
.dbline 155
;
; SETBIT(I2C_PORT,SCL); // Clock the ACK bit
sbi 0xb,0
.dbline 157
;
; if ( CHECKBIT( I2C_IN,SDA ) ) Ackn = 1; // Check the ACK bit on SDA
sbis 0x9,1
rjmp L23
X5:
.dbline 157
ldi R16,1
L23:
.dbline 159
;
; CLEARBIT(I2C_PORT,SCL); // Clear the clock
cbi 0xb,0
.dbline 161
;
; return Ackn; // Return our ACK bit
.dbline -2
L22:
.dbline 0 ; func end
ret
.dbsym r Ackn 16 c
.dbend
.dbfunc e Write_I2C_Control _Write_I2C_Control fV
; RW -> y+2
; H_ADD -> R20
; D_Code -> R22
.even
_Write_I2C_Control::
st -y,R20
st -y,R22
mov R20,R18
mov R22,R16
.dbline -1
.dbline 175
; }
;
;
;
;
;
; // ***************************************************** //
; // *** This routine will write the I2C device code, *** //
; // *** set the device chip select bits, *** //
; // *** and set or clear the I2C R/W bit *** //
; // ***************************************************** //
;
; void Write_I2C_Control(unsigned char D_Code,unsigned char H_ADD,unsigned char RW)
; {
.dbline 179
;
; // *** Send the I2C device Control code *** //
;
; CLEARBIT(I2C_PORT,SCL); // Clear SCL clock
cbi 0xb,0
.dbline 181
;
; if( (D_Code & 0x08) == 0x08) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R22
andi R24,8
cpi R24,8
brne L26
X6:
.dbline 181
sbi 0xb,1
xjmp L27
L26:
.dbline 182
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L27:
.dbline 184
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 186
;
; if( (D_Code & 0x04) == 0x04) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R22
andi R24,4
cpi R24,4
brne L28
X7:
.dbline 186
sbi 0xb,1
xjmp L29
L28:
.dbline 187
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L29:
.dbline 189
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 191
;
; if( (D_Code & 0x02) == 0x02) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R22
andi R24,2
cpi R24,2
brne L30
X8:
.dbline 191
sbi 0xb,1
xjmp L31
L30:
.dbline 192
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L31:
.dbline 194
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 196
;
; if( (D_Code & 0x01) == 0x01) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R22
andi R24,1
cpi R24,1
brne L32
X9:
.dbline 196
sbi 0xb,1
xjmp L33
L32:
.dbline 197
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L33:
.dbline 199
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 205
;
;
;
; // *** Send the I2C Control byte chip selects bits *** //
;
; if( (H_ADD & 0x04) == 0x04) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R20
andi R24,4
cpi R24,4
brne L34
X10:
.dbline 205
sbi 0xb,1
xjmp L35
L34:
.dbline 206
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L35:
.dbline 208
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 210
;
; if( (H_ADD & 0x02) == 0x02) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R20
andi R24,2
cpi R24,2
brne L36
X11:
.dbline 210
sbi 0xb,1
xjmp L37
L36:
.dbline 211
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L37:
.dbline 213
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 215
;
; if( (H_ADD & 0x01) == 0x01) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
mov R24,R20
andi R24,1
cpi R24,1
brne L38
X12:
.dbline 215
sbi 0xb,1
xjmp L39
L38:
.dbline 216
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L39:
.dbline 218
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
.dbline 222
;
; // *** Set or Clear the read / write bit for I2C control *** //
;
; if(RW) SETBIT(I2C_PORT,SDA); // Set I2C SDA PIN
ldd R0,y+2
tst R0
breq L40
X13:
.dbline 222
sbi 0xb,1
xjmp L41
L40:
.dbline 223
; else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
cbi 0xb,1
L41:
.dbline 225
;
; I2C_Clock(); // Clock I2C bit
xcall _I2C_Clock
L42:
.dbline 227
;
; while(I2C_Ackn() ); // Check for acknowledge from I2C device
L43:
.dbline 227
xcall _I2C_Ackn
tst R16
brne L42
X14:
.dbline -2
L25:
.dbline 0 ; func end
ld R22,y+
ld R20,y+
ret
.dbsym l RW 2 c
.dbsym r H_ADD 20 c
.dbsym r D_Code 22 c
.dbend
; }
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -