I2C汇编程序:/*****;FileName: IicSMasU.a51;Describe: 51 系列模拟I2C 总线主控器驱动程序;Date: 2003/11/12;*****/$include (IicSMasU.inc)public _IicTxdRxdpublic SlvAddrpublic SubAddr/***************;Name: bit _IicTxdRxd(TxdByte,RxdByte,&IicDataBuf);Describe: 发送数据给被控器/接收来自被控器的数据;Input: TxdByte=要发送数据的字节数; RxdByte=要接收数据的字节数; IicDataBuf=发送/接收缓冲区的首字节; (SlvAddr(被控器地址),SubAddr(单元地址));Output: C(Retry=1):操作失败标志; IicDataBuf=接收到的数据的首字节(主接收时有效);调用说明:; A.现行地址写: SlvAddr(写) !!!(带SubAddr 的器件不能使用该子程序); TxdByte=(发送数据字节数(SubAddr 为第一个要发送的数据)); RxdByte=0; B.指定地址写: SlvAddr(写),SubAddr; TxdByte=(1+发送数据字节数); RxdByte=0; C.现行地址读: SlvAddr(读); TxdByte=0; RxdByte=要接收数据的字节数; D.指定地址读: SlvAddr(读),SubAddr; TxdByte=1; RxdByte=要接收数据的字节数;Nesting level: 1;Change: A,C,R1, R4~R7;*************************/BitSegIicSM SEGMENT BIT overlayableRSEG BitSegIicSMRetry: dbit 1 指明I2C 最后的数据传送失败应该重复操作BITEA: DBIT 1 存中断状态DataSegIicSM SEGMENT DATA overlayableRSEG DataSegIicSMSlvAddr: ds 1 被控器地址SubAddr: ds 1 单元地址TxdByte equ r7 要发送数据的字节数(第一传递参数)RxdByte equ r5 要接收数据的字节数(第二传递参数)WaitXTm macro X 延时X 个机器周期if X=0exitmendifif X=1nopendifif X=2nopnopendifif X=3nopnopnopendifif X>255error "the number of X is too much"elsemov r6,#X/2DJNZ r6,$endifendmCodeSegIicSM SEGMENT CODERSEG CodeSegIicSM_IicTxdRxd:SETB Retry 设置错误标志位/*****;发送起动条件;*****/SendStart:SETB SDASETB SCLWaitXTm IicDelayCLR SDA 产生起始信号WaitXTm IicDelayCLR SCL 结束起动条件/*****;送被控器地址地址,数据;*****/SendSlaAdr:MOV A,SlvAddrCJNE TxdByte,#0,SendSlaAdr1SETB ACC.0 TxdByte=0 时进行读操作SendSlaAdr1:SETB C 检测应答位时释放SDA 线CALL XmByteJC IicErr 无应答出错JB ACC.0,ReceiveData SlaAdr.0=1 时进行读操作;写操作MOV A,SubAddrSendData:SETB C 检测应答位时释放SDA 线CALL XmByteJC IicErr 无应答出错MOV A,@R1INC R1DJNZ TxdByte,SendDataDEC R1MOV A,RxdByteJNZ SendStart RxdByte>0 时进行读操作JMP SendStop/*****;Name: RcvByte;Describe: 接收1 字节数据(接收8 位,发送+1 位(非)应答位);Input: C=1:发送非应答位(通知slave 停止通信); C=0:发送应答位(通知slave 继续发送后续字节);Output: A=接收到的数据, C=(非)应答位;Use: A,R4,C,R6(WaitXTm);*****/RcvByte:MOV A,#0FFH 释放SDA 线允许输入/*****;Name: XmByte;Describe: 发送1 字节数据(发送8 位,接收1 位(非)应答位);Input: A=待发送的数据, C=1(检测应答位时释放SDA 线);Output: C=1:slave 非应答(slave 不响应); C=0:slave 应答(slave 接收成功);Use: A,R4,C,R6(WaitXTm)