sbit SCL=P1^0;
sbit SDA=P1^1;
PUBLIC void start(void)
{
SDA=1;
SCL=1;
TIMING_STABLE();
SDA=0;
DELAY_WAIT();
SCL=0;
TIMING_STABLE();
}
PUBLIC void stop(void)
{
SDA=0;
SCL=1;
TIMING_STABLE();
SDA=1;
TIMING_STABLE();
SCL=0;
TIMING_STABLE();
}
PUBLIC void write_da(u8 send_byte) //写数据
{
XDATA u8 j=8;
for(;j> 0;j--)
{
send_byte < <=1;
SDA=CY;
DELAY_WAIT();
SCL=1;
TIMING_STABLE();
SCL=0;
TIMING_STABLE();
}
SDA=1;
}
PUBLIC void re_ack(void) //读ACK
{
XDATA u8 i=128;
do
{
CY=SDA;
i--;
}while(CY!=0 && i> 0);
SCL=1;
TIMING_STABLE();
SCL=0;
TIMING_STABLE();
PUBLIC u8 read_da(void) //读数据
{
XDATA u8 receivebyte=0;
XDATA u8 i=8;
while(i--)
{
receivebyte=(receivebyte < <1)|SDA;
DELAY_WAIT();
SCL=1;
TIMING_STABLE();
SCL=0;
TIMING_STABLE();
}
return(receivebyte);
}
PUBLIC void TIMING_STABLE(void) //延时
{
XDATA u8 i=1;
XDATA u8 j;
for(;i> 0;i--)
{
j=1;
for(;j> 0;j--)
{
_nop_();
}
}
}
PUBLIC void DELAY_WAIT(void) //延时
{
XDATA u8 j=1;
for(;j> 0;j--)
{
_nop_();
}
}
PUBLIC void read_from(u8 address,u8 *re_address) //读数据主程序段
{
start();
write_da(0xa0);
re_ack();
write_da(address);
re_ack();
start();
write_da(0xa1);
re_ack();
*re_address=read_da();
stop();
DELAY_WAIT();
}
E2_2: POP ACC
RET
E2R2: LCALL SRD
MOV @R0,A
LCALL SRDACK
INC R0
SJMP E2R3
E2W: MOV A,#0A0H
LCALL SWR
LCALL SWRACK
JB B_T0OV,E2RET
MOV A,E2ADDS
LCALL SWR
LCALL SWRACK
JB B_T0OV,E2RET
MOV R0,E2START
mov a,@r0
E2W1: LCALL SWR
LCALL SWRACK
JB B_T0OV,E2RET
INC R0
MOV A,@R0
DJNZ E2LONG,E2W1
SJMP E2RET
;*******************
SBEGIN: SETB SDA
SETB SCL
;nop
CLR SDA
CLR SCL
;nop
RET
;**************
;INCLUDE A,
SWR: MOV R7,#08H
;MOV A,#0A0H
SWR1: RLC A
MOV SDA,C
SETB SCL
;nop
CLR SCL
;nop
DJNZ R7,SWR1
RET
;*******************
SRD: MOV R7,#08H
SRD1: setb sda
SETB SCL
MOV C,SDA
RLC A
CLR SCL
DJNZ R7,SRD1
RET
;*****************
SEND: SETB CON2
CLR SDA
SETB SCL
;nop
SETB SDA
RET
;*****************
SWRACK: setb sda
SETB SCL
;nop
SWRACK3: JB SDA,SWRACK1
CLR SCL
;nop
SWRACK2: RET
SWRACK1: JB B_T0OV,SWRACK2
SJMP SWRACK3
;*****************
SRDACK: CLR SDA
SETB SCL
;nop
CLR SCL
;nop
RET
;**************
SRDNACK: SETB SDA
SETB SCL
;nop
CLR SCL
;nop
RET
;IIC bus data section define:
bit_cnt data 08h ;Bit counter for iic routines
slv_addr data 0ah ;Slave address for iic routines
flags data 28h ;Location for bit flags
no_ack bit flags.0 ;Iic no acknowledge flag
bus_fault bit flags.1 ;Iic bus fault flag
iic_busy bit flags.2 ;Iic bus is busy flag
eeprom_addr equ 0a6h ;The address of 24c02
;a write data to eeprom subprograming
wri_rom:
mov slv_addr,#eeprom_addr
call master
mov a,#18h
call send_byte
mov slv_addr,#eeprom_addr
call master
mov a,#01h
call send_byte
mov a,#01h
call send_byte
mov a,32h
call send_byte
mov a,33h
call send_byte
mov a,#02h
call send_byte
mov a,#02h
call send_byte
mov a,36h
call send_byte
mov a,37h
call send_byte
call send_stop
call delay10
ret
;iic bus operating subprograming
send_stop: clr sda_pin ;get sda ready for stop.
setb scl_pin ;set clock for stop.
jnb scl_pin,$
nop
nop
nop ;delay 3 cycles
setb sda_pin ;send iic stop.
;delay satisfied via software.
clr iic_busy ;clear iic busy status.
ret ;bus should now be released.
master: setb iic_busy ;indicate that 12c frame is in progress.
clr no_ack ;clear error status flags.
clr bus_fault
jnb scl_pin,fault ;check for bus clear.
jnb sda_pin,fault
clr sda_pin ;begin 12c start.
nop
nop
nop ;delay_3_cycles.
clr scl_pin ;completa 12c start.
nop
nop
nop ;delay_3_cycles.
mov a,slv_addr ;get slave address.
call send_byte ;send slave address.
ret
fault: setb bus_fault ;set fault status.
ret ;and return.
send_byte: mov bit_cnt,#8 ;set bit count value.
sb_loop: rlc a ;send one data bit.
mov sda_pin,c ;put data bit on pin.
setb scl_pin
jnb scl_pin,$ ;drive scl high.
nop
nop
nop ;delay_3_cycles.
clr scl_pin ;clear scl.
nop
nop
nop ;delay_3_cycles.
djnz bit_cnt,sb_loop;repeat until all bits sent.
setb sda_pin ;release data line for acknowledge.
setb scl_pin
jnb scl_pin,$ ;sent clock for acknowledge.
nop
nop
nop
nop ;delay_4_cycles.
jnb sda_pin,sb_ex ;cheek for valid acknowledge bit.
setb no_ack ;set status for no acknowledge.
sb_ex: clr scl_pin ;finish acknowledge bit.
nop
nop
nop ;delay_3_cycles.
ret ;return.
recv_byte: mov bit_cnt,#8 ;set bit count.
rb_loop: setb scl_pin
jnb scl_pin,$ ;read one data bit.
nop
nop
nop ;delay_3_cycles.
mov c,sda_pin ;get data bit from pin.
rlc a ;rotate bit into result byte.
clr scl_pin ;clear scl pin.
nop
nop
nop ;delay_3_cycles.
djnz bit_cnt,rb_loop;repeat accumulator.
push acc ;save accumulator.
mov a,byte_cnt ;copies byte count into a.
cjne a,#1,rb_ack ;check for last byte of frame.
setb sda_pin ;send no acknowledge on last byte.
sjmp rb_aclk ;no ack on last byte;jump to rb_aclk.
rb_ack: clr sda_pin ;send acknowledge bit.
rb_aclk: setb scl_pin
jnb scl_pin,$ ;send acknowledge clock.
pop acc ;restore accumulator.
nop
nop
nop ;delay_3_cycles.
clr scl_pin ;clear scl pin.
setb sda_pin ;clear ackonwledge bit.
nop
nop
nop
nop ;delay_4_cycles.
ret ;return from recv_byte.
;Delay subprograming
delay10: mov r7,#28
delay10_lp: mov r6,#8fh
djnz r6,$
djnz r7,delay10_lp
ret