📄 i2c.s
字号:
.module I2c.c
.area text(rom, con, rel)
.dbfile D:\avrmcu\AT980\I2C\I2c.c
.dbfunc s I2C_delay _I2C_delay fI
; i -> R16
.even
_I2C_delay::
.dbline -1
.dbline 22
; /***********************************************************************/
;
;
;
;
; #include <iom163.h>
;
; #include "..\io.h"
; #define TRUE 1
; #define FALSE 0
;
; #define I2C_MAX_WAIT 110 /* in microseconds */
;
; #define HOLDING_TIME 10
;
; /*
; * These local functions wait for the other end the set the bit to a
; * certain level.
; */
;
; void I2C_delay(void)
; {
.dbline 24
; unsigned char i;
; for(i=0;i<80;i++)
clr R16
xjmp L5
L2:
.dbline 25
.dbline 26
L3:
.dbline 24
inc R16
L5:
.dbline 24
cpi R16,80
brlo L2
.dbline -2
.dbline 27
; {
; }
; }
L1:
.dbline 0 ; func end
ret
.dbsym r i 16 c
.dbfunc s I2C_delay1 _I2C_delay1 fI
; i -> R20
; viod -> R16,R17
.even
_I2C_delay1::
xcall push_gset1
.dbline -1
.dbline 29
; void I2C_delay1(viod)
; {
.dbline 31
; unsigned char i;
; for(i=0;i<200;i++)
clr R20
xjmp L10
L7:
.dbline 32
.dbline 33
L8:
.dbline 31
inc R20
L10:
.dbline 31
cpi R20,200
brlo L7
.dbline 33
; {
; };
.dbline -2
.dbline 34
; }
L6:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r viod 16 I
.dbfunc s wait_sda_hi _wait_sda_hi fI
; i -> R20
.even
_wait_sda_hi:
xcall push_gset1
.dbline -1
.dbline 48
; /*static unsigned char wait_sda_lo(void)
; {
; int i = I2C_MAX_WAIT/5;
; sda_set_input();
; while(i && is_sda_hi()) {
; i--;
; I2C_delay();
; }
; sda_set_output();
; return i?TRUE:FALSE;
; }*/
;
; static unsigned char wait_sda_hi(void)
; {
.dbline 49
; unsigned char i = I2C_MAX_WAIT;
ldi R20,110
.dbline 50
; sda_set_input();
CBI 0x14,1
xjmp L13
L12:
.dbline 52
; while(i)
; {
.dbline 53
; if(is_sda_hi())
sbis 0x13,1
rjmp L15
.dbline 54
; {
.dbline 55
; sda_set_output();
SBI 0x14,1
.dbline 56
; return TRUE;
ldi R16,1
ldi R17,0
xjmp L11
L15:
.dbline 58
dec R20
.dbline 59
xcall _I2C_delay1
.dbline 60
L13:
.dbline 51
tst R20
brne L12
.dbline 61
; }
; i--;
; I2C_delay1();
; }
; sda_set_output();
SBI 0x14,1
.dbline 62
; return FALSE;
clr R16
clr R17
.dbline -2
L11:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbfunc s wait_scl_hi _wait_scl_hi fI
; i -> R20
.even
_wait_scl_hi:
xcall push_gset1
.dbline -1
.dbline 66
; }
;
; static unsigned char wait_scl_hi(void)
; {
.dbline 67
; unsigned char i = I2C_MAX_WAIT;
ldi R20,110
.dbline 69
;
; scl_set_input();
CBI 0x14,0
xjmp L19
L18:
.dbline 71
; while(i)
; {
.dbline 72
; if(is_scl_hi())
sbis 0x13,0
rjmp L21
.dbline 73
; {
.dbline 74
; scl_set_output();
SBI 0x14,0
.dbline 75
; return TRUE;
ldi R16,1
ldi R17,0
xjmp L17
L21:
.dbline 77
dec R20
.dbline 78
xcall _I2C_delay1
.dbline 79
L19:
.dbline 70
tst R20
brne L18
.dbline 80
; }
; i--;
; I2C_delay1();
; }
; scl_set_output();
SBI 0x14,0
.dbline 81
; return FALSE;
clr R16
clr R17
.dbline -2
L17:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbfunc s i2c_start _i2c_start fI
.even
_i2c_start::
.dbline -1
.dbline 92
; }
;
; /*
; * This function is called before an I2C transfer is started. A start
; * condition is signified with a high-to-low transition of SDA while SCL
; * is high.
; */
;
;
; unsigned char i2c_start(void)
; {
.dbline 94
;
; scl_set_output();
SBI 0x14,0
.dbline 95
; scl_hi();
SBI 0x15,0
.dbline 97
; // SEC LEE0216
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 98
; sda_set_output();
SBI 0x14,1
.dbline 99
; sda_hi();
SBI 0x15,1
.dbline 100
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 101
; scl_hi(); // SEC LEE0216
SBI 0x15,0
.dbline 102
; if (!wait_scl_hi())
xcall _wait_scl_hi
movw R2,R16
tst R2
brne L24
.dbline 103
; return FALSE;
clr R16
clr R17
xjmp L23
L24:
.dbline 105
;
; sda_lo(); /* this triggers the start */
CBI 0x15,1
.dbline 106
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 107
; scl_lo();
CBI 0x15,0
.dbline 108
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 109
; return TRUE;
ldi R16,1
ldi R17,0
.dbline -2
L23:
.dbline 0 ; func end
ret
.dbfunc s i2c_stop _i2c_stop fI
.even
_i2c_stop::
.dbline -1
.dbline 118
; }
;
; /*
; * The function is used to tell the device the the transmission is over.
; * The stop condition is signified by a low-to-high transition of SDA
; * while SCL is high.
; */
; unsigned char i2c_stop(void)
; {
.dbline 121
; //scl_lo();
; //I2C_delay();//HOLDING_TIME*3);
; sda_lo();
CBI 0x15,1
.dbline 122
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 123
; scl_hi();
SBI 0x15,0
.dbline 124
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 125
; if (!wait_scl_hi())
xcall _wait_scl_hi
movw R2,R16
tst R2
brne L27
.dbline 126
; return FALSE;
clr R16
clr R17
xjmp L26
L27:
.dbline 128
;
; sda_hi(); /* this triggers the stop */
SBI 0x15,1
.dbline 129
; if (!wait_sda_hi())
xcall _wait_sda_hi
movw R2,R16
tst R2
brne L29
.dbline 130
; return FALSE;
clr R16
clr R17
xjmp L26
L29:
.dbline 131
; scl_lo();
CBI 0x15,0
.dbline 133
;
; I2C_delay();//HOLDING_TIME*3);
xcall _I2C_delay
.dbline 135
;
; return TRUE;
ldi R16,1
ldi R17,0
.dbline -2
L26:
.dbline 0 ; func end
ret
.dbfunc s i2c_putc _i2c_putc fI
; ack -> R20,R21
; mask -> R22
; d -> R10
.even
_i2c_putc::
xcall push_gset3
mov R10,R16
.dbline -1
.dbline 144
; }
;
; /*
; * This function sends one byte on the I2C bus. The bits in the byte are
; * sent in the order of the high bit first and the lowest bit last.
; */
;
; unsigned char i2c_putc(unsigned char d)
; {
.dbline 149
; unsigned char mask;
; unsigned ack;
;
;
; for (mask = 0x80; mask; mask >>= 1)
ldi R22,128
xjmp L35
L32:
.dbline 150
; {
.dbline 151
; if (d & mask)
mov R2,R10
and R2,R22
tst R2
breq L36
.dbline 152
; sda_hi();
SBI 0x15,1
xjmp L37
L36:
.dbline 154
; else
; sda_lo();
CBI 0x15,1
L37:
.dbline 156
xcall _I2C_delay
.dbline 157
SBI 0x15,0
.dbline 158
xcall _I2C_delay
.dbline 159
CBI 0x15,0
.dbline 161
L33:
.dbline 149
lsr R22
L35:
.dbline 149
tst R22
brne L32
.dbline 164
;
; I2C_delay();//HOLDING_TIME); // SEC LEE0216
; scl_hi();
; I2C_delay();//HOLDING_TIME);
; scl_lo();
; //Idelay_us(5);//HOLDING_TIME);
; }
;
; //sda_hi(); /* ack handshake after every byte */
; sda_set_input();
CBI 0x14,1
.dbline 165
; I2C_delay();//HOLDING_TIME);
xcall _I2C_delay
.dbline 167
;
; scl_hi();
SBI 0x15,0
.dbline 168
; I2C_delay();//HOLDING_TIME);
xcall _I2C_delay
.dbline 170
;
; if (!is_sda_hi()) /* sda low means an ack */
sbic 0x13,1
rjmp L38
.dbline 171
; ack = TRUE;
ldi R20,1
ldi R21,0
xjmp L39
L38:
.dbline 173
; else
; ack = FALSE;
clr R20
clr R21
L39:
.dbline 175
;
; scl_lo();
CBI 0x15,0
.dbline 176
; I2C_delay();//HOLDING_TIME); // SEC LEE0216
xcall _I2C_delay
.dbline 177
; sda_set_output();
SBI 0x14,1
.dbline 178
; return ack;
mov R16,R20
clr R17
.dbline -2
L31:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r ack 20 i
.dbsym r mask 22 c
.dbsym r d 10 c
.dbfunc s i2c_getc _i2c_getc fI
; i -> R10
; d -> R20
; rdack -> R22,R23
.even
_i2c_getc::
xcall push_gset3
movw R22,R16
.dbline -1
.dbline 189
; }
;
; /*
; * This function is used to get data from another I2C device. The |rdack|
; * parameter is used to tell the device if we want to read more bytes. If
; * |rdack| is true then we want to receive the byte at the next address,
; * otherwise we don't want anymore bytes.
; */
;
; unsigned char i2c_getc(unsigned rdack)
; {
.dbline 194
; register unsigned char d;
; register unsigned char i;
;
; //sda_hi(); /* don't drive the data line */
; sda_set_input();
CBI 0x14,1
.dbline 195
; d=0;
clr R20
.dbline 196
clr R10
xjmp L44
L41:
.dbline 196
; for (i = 0; i < 8; i++) {
.dbline 197
; d <<= 1;
lsl R20
.dbline 199
;
; scl_hi(); /* drive clock high to get data */
SBI 0x15,0
.dbline 200
; I2C_delay();//HOLDING_TIME);
xcall _I2C_delay
.dbline 202
;
; if (!wait_scl_hi())
xcall _wait_scl_hi
movw R2,R16
tst R2
brne L45
.dbline 203
; return 0xFF; /* i2c error */
ldi R16,255
ldi R17,0
xjmp L40
L45:
.dbline 205
;
; if (is_sda_hi())
sbis 0x13,1
rjmp L47
.dbline 206
; d |= 1; /* bit is a one */
ori R20,1
L47:
.dbline 208
CBI 0x15,0
.dbline 209
xcall _I2C_delay
.dbline 210
L42:
.dbline 196
inc R10
L44:
.dbline 196
mov R24,R10
cpi R24,8
brlo L41
.dbline 212
;
; scl_lo(); /* drive clock back down */
; I2C_delay();//HOLDING_TIME);
; }
;
; sda_set_output();
SBI 0x14,1
.dbline 213
; if (rdack)
cpi R22,0
cpc R22,R23
breq L49
.dbline 214
; sda_lo(); /* send an ack */
CBI 0x15,1
L49:
.dbline 216
;
; scl_hi();
SBI 0x15,0
.dbline 218
;
; if (!wait_scl_hi())
xcall _wait_scl_hi
movw R2,R16
tst R2
brne L51
.dbline 219
; return 0xFF; /* i2c error */
ldi R16,255
ldi R17,0
xjmp L40
L51:
.dbline 220
; scl_lo();
CBI 0x15,0
.dbline 222
;
; if (rdack)
cpi R22,0
cpc R22,R23
breq L53
.dbline 223
; sda_hi(); /* release if set */
SBI 0x15,1
L53:
.dbline 225
;
; return d;
mov R16,R20
clr R17
.dbline -2
L40:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r i 10 c
.dbsym r d 20 c
.dbsym r rdack 22 i
.dbfunc s i2c_select_device _i2c_select_device fI
; subaddr -> R20
; addr -> R22
.even
_i2c_select_device::
xcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 230
; }
;
;
; unsigned char i2c_select_device( unsigned char addr, unsigned char subaddr )
; {
.dbline 231
; if (i2c_start())
xcall _i2c_start
movw R2,R16
tst R2
breq L56
.dbline 232
; {
.dbline 234
;
; if (i2c_putc(addr))
mov R16,R22
xcall _i2c_putc
movw R2,R16
tst R2
breq L58
.dbline 235
; {
.dbline 236
; if (i2c_putc(subaddr))
mov R16,R20
xcall _i2c_putc
movw R2,R16
tst R2
breq L60
.dbline 237
; {
.dbline 238
; return TRUE;
ldi R16,1
ldi R17,0
xjmp L55
L60:
.dbline 240
; }
; }
L58:
.dbline 241
L56:
.dbline 241
; };
.dbline 242
; return FALSE;
clr R16
clr R17
.dbline -2
L55:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r subaddr 20 c
.dbsym r addr 22 c
.dbfunc s i2c_write _i2c_write fI
; res -> R20
; dat -> y+4
; subaddr -> R22
; addr -> R20
.even
_i2c_write::
xcall push_gset2
mov R22,R18
mov R20,R16
.dbline -1
.dbline 254
; }
;
; /*
; * This function writes address, subaddr, and data on the I2C bus.
; * The bits in the byte are
; * sent in the order of the high bit first and the lowest bit last.
; */
;
; unsigned char i2c_write(unsigned char addr,
; unsigned char subaddr,
; unsigned char dat)
; {
.dbline 257
; unsigned char res;
;
; if (res = i2c_select_device( addr, subaddr ))
mov R18,R22
mov R16,R20
xcall _i2c_select_device
movw R2,R16
mov R20,R2
tst R2
breq L63
.dbline 258
; {
.dbline 259
; res = i2c_putc(dat);
ldd R16,y+4
xcall _i2c_putc
movw R2,R16
mov R20,R2
.dbline 260
L63:
.dbline 260
; };
.dbline 263
;
; /* <<< ZRN SH0125: Modified to return FALSE if an error occured */
; i2c_stop();
xcall _i2c_stop
.dbline 265
;
; return res;
mov R16,R20
clr R17
.dbline -2
L62:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r res 20 c
.dbsym l dat 4 c
.dbsym r subaddr 22 c
.dbsym r addr 20 c
.dbfunc s pt2320_write _pt2320_write fI
; res -> R20
; data -> R22
.even
_pt2320_write::
xcall push_gset2
mov R22,R16
.dbline -1
.dbline 351
; }
; /*
; unsigned char i2c_write_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
; {
; // int retry = 10; // SEC LEE0216
; // unsigned char retry = 10; // SEC LEE0216
;
; while (count&&ret){
; if (i2c_write(addr, subaddr, *data)){
; subaddr++;
; data++;
; count--;
; retry = 10;
; usleep(10000L);
; }
; else
; retry--;
; usleep(10000L); // sgjm wait 1ms(us_delay(1000L)-->wait 10ms(usleep(10000L)
; }
; return retry?TRUE:FALSE;
; }
; */
; /*
; unsigned char i2c_read_string( unsigned char addr, unsigned char subaddr, unsigned char count, unsigned char *data )
; {
;
; unsigned char res;
; if (res = i2c_select_device( addr, subaddr ))
; {
; if (!i2c_start()) // another start for read
; {
;
; return 0;
; }
; i2c_putc((unsigned char)(addr|1)); //set up for a read
; while (--count)
; *data++ = i2c_getc(1);
; *data = i2c_getc(0);
; }
; i2c_stop();
;
;
; return res;
; }
;
; */
;
;
; /*
; BOOL i2c_read_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
; {
; BYTE i ;
;
; // set up for reads starting at address 0
; if ( i2c_select_device( addr, subaddr ) ) {
; // send a second start
; i2c_start() ;
; if ( i2c_putc( addr | 1 ) ) {
; for ( i=0 ; i<count ; i++ ) {
;
; data[i] = ( i2c_getc() ) ;
; if ( i != (count-1) )
; i2c_ack() ;
; else {
; i2c_clock() ;
; i2c_stop() ;
; }
; }
; return ( TRUE ) ;
; }
; else {
; i2c_stop() ;
; return ( FALSE ) ;
; }
; }
; else
; i2c_stop() ;
; return ( FALSE ) ;
;
; }*/
;
; #define PT2320_ADD 0x88
;
;
; unsigned char pt2320_write(unsigned char data)
; {
.dbline 357
;
; register unsigned char res;
;
; //res=i2c_select_device(PT2314_ADD,data);
;
; if (res=i2c_start())
xcall _i2c_start
movw R2,R16
mov R20,R2
tst R2
breq L66
.dbline 358
; {
.dbline 359
; if (res=i2c_putc(PT2320_ADD))
ldi R16,136
xcall _i2c_putc
movw R2,R16
mov R20,R2
tst R2
breq L68
.dbline 360
; {
.dbline 362
;
; res=i2c_putc(data);
mov R16,R22
xcall _i2c_putc
movw R2,R16
mov R20,R2
.dbline 364
;
; }
L68:
.dbline 365
; }
L66:
.dbline 366
; i2c_stop();
xcall _i2c_stop
.dbline 367
; return res;
mov R16,R20
clr R17
.dbline -2
L65:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r res 20 c
.dbsym r data 22 c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -