📄 i2c.s
字号:
.module I2C.C
.area text(rom, con, rel)
.dbfile E:\Steaven2000\AVR\AVR_Book\PROGRA~1\SOURCE~1\Code\I2C总线应用设计\I2C.C
.dbfunc e Delayms _Delayms fV
; time -> R16,R17
.even
_Delayms::
.dbline -1
.dbline 12
; //***************************************************************
; // File Name : I2C.C
; // Author : Steaven
; // Created : 2008-06-09
; // Modified :
; // Revision : V0.0
; //***************************************************************
;
; #include "includes.h"
;
; void Delayms(INT16U time)
; {
xjmp L3
L2:
.dbline 13
nop
L3:
.dbline 13
; while(time--) NOP();
movw R2,R16
subi R16,1
sbci R17,0
tst R2
brne L2
tst R3
brne L2
X0:
.dbline -2
.dbline 14
; }
L1:
.dbline 0 ; func end
ret
.dbsym r time 16 i
.dbend
.area data(ram, con, rel)
.dbfile E:\Steaven2000\AVR\AVR_Book\PROGRA~1\SOURCE~1\Code\I2C总线应用设计\I2C.C
_bI2C_Ack::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile E:\Steaven2000\AVR\AVR_Book\PROGRA~1\SOURCE~1\Code\I2C总线应用设计\I2C.C
.dbsym e bI2C_Ack _bI2C_Ack c
.area text(rom, con, rel)
.dbfile E:\Steaven2000\AVR\AVR_Book\PROGRA~1\SOURCE~1\Code\I2C总线应用设计\I2C.C
.dbfunc e I2C_Set_SDA _I2C_Set_SDA fV
; data -> R16
.even
_I2C_Set_SDA::
.dbline -1
.dbline 33
;
; //I2C操作状态位,反映操作是否成功
; INT8U bI2C_Ack = 0;
;
; //引脚属性定义,便于移植
; #define DIR_REG_I2C DDRB
; #define PORT_REG_I2C PORTB
; #define PIN_REG_I2C PINB
; #define SCL_BIT_I2C 0
; #define SDA_BIT_I2C 1
;
; //***************************************************************
; // Function : I2C_Set_SDA
; // Input : data - SDA Pin Level
; // Output : none
; // Description : Set SDA Pin Level.
; //***************************************************************
; void I2C_Set_SDA(INT8U data)
; {
.dbline 34
; if(data == 0)
tst R16
brne L6
.dbline 35
; {
.dbline 36
; PORT_REG_I2C &= ~(1 << SDA_BIT_I2C);
cbi 0x18,1
.dbline 37
; }
xjmp L7
L6:
.dbline 39
.dbline 40
sbi 0x18,1
.dbline 41
L7:
.dbline -2
.dbline 42
; else
; {
; PORT_REG_I2C |= (1 << SDA_BIT_I2C);
; }
; }
L5:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e I2C_Set_SCL _I2C_Set_SCL fV
; data -> R16
.even
_I2C_Set_SCL::
.dbline -1
.dbline 51
;
; //***************************************************************
; // Function : I2C_Set_SCL
; // Input : data - SCL Pin Level
; // Output : none
; // Description : Set SCL Pin Level.
; //***************************************************************
; void I2C_Set_SCL(INT8U data)
; {
.dbline 52
; if(data == 0)
tst R16
brne L9
.dbline 53
; {
.dbline 54
; PORT_REG_I2C &= ~(1 << SCL_BIT_I2C);
cbi 0x18,0
.dbline 55
; }
xjmp L10
L9:
.dbline 57
.dbline 58
sbi 0x18,0
.dbline 59
L10:
.dbline -2
.dbline 60
; else
; {
; PORT_REG_I2C |= (1 << SCL_BIT_I2C);
; }
; }
L8:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e I2C_Start_Condition _I2C_Start_Condition fV
.even
_I2C_Start_Condition::
.dbline -1
.dbline 69
;
; //***************************************************************
; // Function : I2C_Start_Condition
; // Input : none
; // Output : none
; // Description : Generate a START Condition.
; //***************************************************************
; void I2C_Start_Condition(void)
; {
.dbline 70
; I2C_Set_SDA(1);
ldi R16,1
xcall _I2C_Set_SDA
.dbline 71
; I2C_Set_SCL(1);
ldi R16,1
xcall _I2C_Set_SCL
.dbline 72
; I2C_Set_SDA(0);
clr R16
xcall _I2C_Set_SDA
.dbline 73
; I2C_Set_SCL(0);
clr R16
.dbline -2
.dbline 74
; }
L11:
.dbline 0 ; func end
xjmp _I2C_Set_SCL
.dbend
.dbfunc e I2C_Stop_Condition _I2C_Stop_Condition fV
.even
_I2C_Stop_Condition::
.dbline -1
.dbline 83
;
; //***************************************************************
; // Function : I2C_Stop_Condition
; // Input : none
; // Output : none
; // Description : Generate a STOP Condition.
; //***************************************************************
; void I2C_Stop_Condition(void)
; {
.dbline 84
; I2C_Set_SDA(0);
clr R16
xcall _I2C_Set_SDA
.dbline 85
; I2C_Set_SCL(1);
ldi R16,1
xcall _I2C_Set_SCL
.dbline 86
; I2C_Set_SDA(1);
ldi R16,1
.dbline -2
.dbline 87
; }
L12:
.dbline 0 ; func end
xjmp _I2C_Set_SDA
.dbend
.dbfunc e I2C_Send_Byte _I2C_Send_Byte fV
; cnt -> R20
; data -> R22
.even
_I2C_Send_Byte::
xcall push_gset2
mov R22,R16
.dbline -1
.dbline 96
;
; //***************************************************************
; // Function : I2C_Send_Byte
; // Input : data - data to be transmitted
; // Output : none
; // Description : Send a byte on I2C Bus with the MSB first.
; //***************************************************************
; void I2C_Send_Byte(INT8U data)
; {
.dbline 98
; INT8U cnt;
; for(cnt = 0;cnt < 8;cnt++)
clr R20
xjmp L17
L14:
.dbline 99
; {
.dbline 100
; if((data << cnt) & 0x80)
mov R16,R22
mov R17,R20
xcall lsl8
mov R24,R16
andi R24,128
breq L18
.dbline 101
; {
.dbline 102
; I2C_Set_SDA(1);
ldi R16,1
xcall _I2C_Set_SDA
.dbline 103
; }
xjmp L19
L18:
.dbline 105
; else
; {
.dbline 106
; I2C_Set_SDA(0);
clr R16
xcall _I2C_Set_SDA
.dbline 107
; }
L19:
.dbline 108
ldi R16,1
xcall _I2C_Set_SCL
.dbline 109
clr R16
xcall _I2C_Set_SCL
.dbline 110
L15:
.dbline 98
inc R20
L17:
.dbline 98
cpi R20,8
brlo L14
.dbline 111
; I2C_Set_SCL(1);
; I2C_Set_SCL(0);
; }
; I2C_Set_SDA(1);
ldi R16,1
xcall _I2C_Set_SDA
.dbline 112
; I2C_Set_SCL(1);
ldi R16,1
xcall _I2C_Set_SCL
.dbline 113
; DIR_REG_I2C &= ~(1 << SDA_BIT_I2C);
cbi 0x17,1
.dbline 114
; if(PIN_REG_I2C & (1 << SDA_BIT_I2C))
sbis 0x16,1
rjmp L20
.dbline 115
; {
.dbline 116
; bI2C_Ack = 0;
clr R2
sts _bI2C_Ack,R2
.dbline 117
; }
xjmp L21
L20:
.dbline 119
; else
; {
.dbline 120
; bI2C_Ack = 1;
ldi R24,1
sts _bI2C_Ack,R24
.dbline 121
; }
L21:
.dbline 122
; I2C_Set_SCL(0);
clr R16
xcall _I2C_Set_SCL
.dbline 123
; DIR_REG_I2C |= (1 << SDA_BIT_I2C);
sbi 0x17,1
.dbline 124
; Delayms(100);
ldi R16,100
ldi R17,0
xcall _Delayms
.dbline -2
.dbline 125
; }
L13:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r cnt 20 c
.dbsym r data 22 c
.dbend
.dbfunc e I2C_Receive_Byte _I2C_Receive_Byte fc
; cnt -> R20
; data -> R22
.even
_I2C_Receive_Byte::
xcall push_gset2
.dbline -1
.dbline 134
;
; //***************************************************************
; // Function : I2C_Receive_Byte
; // Input : none
; // Output : Receive a byte from I2C Bus
; // Description : Receive a byte on I2C Bus with the MSB first.
; //***************************************************************
; INT8U I2C_Receive_Byte(void)
; {
.dbline 135
; INT8U data = 0;
clr R22
.dbline 136
; INT8U cnt = 0;
clr R20
.dbline 137
; DIR_REG_I2C &= ~(1 << SDA_BIT_I2C);
cbi 0x17,1
.dbline 138
; PORT_REG_I2C |= (1 << SDA_BIT_I2C);
sbi 0x18,1
.dbline 139
; for(cnt = 0; cnt < 8;cnt++)
xjmp L26
L23:
.dbline 140
; {
.dbline 141
; I2C_Set_SCL(0);
clr R16
xcall _I2C_Set_SCL
.dbline 142
; I2C_Set_SCL(1);
ldi R16,1
xcall _I2C_Set_SCL
.dbline 143
; data = data << 1;
lsl R22
.dbline 144
; if(PIN_REG_I2C & (1 << SDA_BIT_I2C))
sbis 0x16,1
rjmp L27
.dbline 145
; {
.dbline 146
; data |= 0x01;
ori R22,1
.dbline 147
; }
L27:
.dbline 148
L24:
.dbline 139
inc R20
L26:
.dbline 139
cpi R20,8
brlo L23
.dbline 149
; }
; I2C_Set_SCL(0);
clr R16
xcall _I2C_Set_SCL
.dbline 150
; DIR_REG_I2C |= (1 << SDA_BIT_I2C);
sbi 0x17,1
.dbline 151
; return(data);
mov R16,R22
.dbline -2
L22:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r cnt 20 c
.dbsym r data 22 c
.dbend
.dbfunc e I2C_Ack _I2C_Ack fV
; ack -> R20
.even
_I2C_Ack::
xcall push_gset1
mov R20,R16
.dbline -1
.dbline 161
; }
;
; //***************************************************************
; // Function : I2C_Ack
; // Input : ack - Whether to ACK the transmitter
; // Output : none
; // Description : Acknowledge the transmitter with 0 or 1
; //***************************************************************
; void I2C_Ack(INT8U ack)
; {
.dbline 162
; if(ack == 0)
tst R20
brne L30
.dbline 163
; {
.dbline 164
; I2C_Set_SDA(0);
clr R16
xcall _I2C_Set_SDA
.dbline 165
; }
xjmp L31
L30:
.dbline 167
; else
; {
.dbline 168
; I2C_Set_SDA(1);
ldi R16,1
xcall _I2C_Set_SDA
.dbline 169
; }
L31:
.dbline 170
; I2C_Set_SCL(1);
ldi R16,1
xcall _I2C_Set_SCL
.dbline 171
; I2C_Set_SCL(0);
clr R16
xcall _I2C_Set_SCL
.dbline -2
.dbline 172
; }
L29:
xcall pop_gset1
.dbline 0 ; func end
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -