⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vi2c_asm.inc

📁 i2c通信协议及程序。适合各种有需要的相关人士.
💻 INC
字号:
;--------------------------------------------------------------------------------------------------------
;		  MCS-51单片机模拟I2C软件包(V1.1)
;    文件名:VI2C_ASM.INC
;    功能说明:本模拟I2C软件包包含了I2C操作的底层子程序,使用前要定义
;好SCL和SDA。在标准8051模式(12 Clock)下,对主频要求是不高于12MHz(即1个
;机器周期1us);若Fosc>12MHz则要增加相应的NOP指令数。(总线时序符合I2C标
;准模式,100Kbit/S)
;    版本说明:本版新增了两个子程序,IWRNBYTEEXT,IRDNBYTEEXT两个子程序,
;这两个子程序用于主从通讯上及一此特殊器件的读写操作较为方便.
;					  更新时间:17:34 04-6-16
;--------------------------------------------------------------------------------------------------------

;----------------------------
N_NOP	MACRO				;宏定义,调节延时,以方便不同芯片间的移植
	NOP
	NOP
	NOP
	NOP
	ENDM

;----------------------------
;启动I2C总线子程序      
;----------------------------
START:  SETB  SDA
        N_NOP
        SETB  SCL     			;起始条件建立时间大于4.7us
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        CLR   SDA      
        N_NOP           		;起始条件锁定时大于4us
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        CLR   SCL     		 	;钳住总线,准备发数据
        N_NOP
        RET

;----------------------------
;结束总线子程序
;----------------------------
STOP:   CLR	SDA
	N_NOP
        SETB	SCL    			;发送结束条件的时钟信号
        N_NOP           		;结束总线时间大于4us
        N_NOP            
        N_NOP
        N_NOP
        N_NOP
        SETB	SDA    			;结束总线
        N_NOP          			;保证一个终止信号和起始信号的空闲时间大于4.7us
        N_NOP
        N_NOP
        N_NOP
        RET

;----------------------------
;发送应答信号子程序
;----------------------------
MACK:   CLR	SDA      		;将SDA置0 
        N_NOP
        N_NOP
        SETB 	SCL
        N_NOP            		;保持数据时间,即SCL为高时间大于4.7us
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        CLR  	SCL
        N_NOP
        N_NOP
        RET

;----------------------------
;发送非应答信号
;----------------------------
MNACK:  SETB 	SDA          		;将SDA置1 
        N_NOP
        N_NOP
        SETB 	SCL
        N_NOP
        N_NOP               		;保持数据时间,即SCL为高时间大于4.7us
        N_NOP
        N_NOP
        N_NOP
        CLR	SCL
        N_NOP
        N_NOP
        RET

;----------------------------
;检查应答位子程序
;返回值,ACK=1时表示有应答
;----------------------------
CACK:	SETB	SDA
        N_NOP
        N_NOP
        SETB	SCL
        CLR 	ACK
        N_NOP
        N_NOP
        MOV   	C,SDA
        JC    	CEND
        SETB 	ACK           		 ;判断应答位
CEND:	N_NOP
        CLR  	SCL
        N_NOP
        RET

;----------------------------
;发送字节子程序
;字节数据放入ACC       
;每发送一字节要调用一次CACK子程序,取应答位 
;----------------------------           
WRBYTE: MOV   	R0,#08H
WLP: 	RLC   	A              		;取数据位
        JC    	WR1
        SJMP  	WR0            		;判断数据位
WLP1:   DJNZ  	R0,WLP
        N_NOP
        RET
WR1:    SETB  	SDA            		;发送1
        N_NOP
        SETB  	SCL
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        CLR   	SCL
        SJMP  	WLP1
WR0:  	CLR   	SDA            		;发送0
        N_NOP
        SETB  	SCL
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        N_NOP
        CLR   	SCL
        SJMP  	WLP1

;----------------------------
;读取字节子程序                    
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号 
;----------------------------
RDBYTE: MOV   	R0,#08H
RLP:    SETB  	SDA
        N_NOP
        SETB  	SCL         		 ;时钟线为高,接收数据位
        N_NOP
        N_NOP
        MOV   	C,SDA        		 ;读取数据位
        MOV   	A,R2
        CLR   	SCL          		 ;将SCL拉低,时间大于4.7us
        RLC   	A            		 ;进行数据位的处理
        MOV   	R2,A
        N_NOP
        N_NOP
        N_NOP
        DJNZ  	R0,RLP        		 ;未够8位,再来一次
        RET


;========================================================================================
;       以下是用户接口子程序
;========================================================================================

;----------------------------
;无子地址器件写字节数据
;入口参数: 数据为ACC、器件从地址SLA              
;占用:  A、R0、CY
;----------------------------
IWRBYTE: PUSH   ACC
IWBLOOP: LCALL  START      			;起动总线
         MOV    A,SLA  
         LCALL  WRBYTE     			;发送器件从地址 
         LCALL  CACK
         JNB    ACK,RETWRB      		;无应答则跳转
         POP    ACC       			;写数据
         LCALL  WRBYTE
         LCALL  CACK
         LCALL  STOP
         RET
RETWRB:  POP    ACC
         LCALL  STOP
         RET

;----------------------------
;无子地址器件读字节数据
;入口参数: 器件从地址SLA
;出口参数: 数据为ACC    
;占用: A 、R0、R2 、CY
;----------------------------
IRDBYTE: LCALL  START
         MOV    A,SLA        			;发送器件从地址
         INC    A
         LCALL  WRBYTE
         LCALL  CACK
         JNB    ACK,RETRDB             
         LCALL  RDBYTE       			;进行读字节操作
         LCALL  MNACK          			;发送非应信号
RETRDB:  LCALL  STOP             		;结束总线
         RET

;----------------------------
;向器件指定子地址写N字节数据
;入口参数:  器件从地址SLA、器件子地址SUBA 、发送数据缓冲区MTD、发送字节数NUMBYTE
; 占用:  A 、R0 、R1 、R3 、CY 
;----------------------------
IWRNBYTE: MOV    A,NUMBYTE
          MOV    R3,A
          LCALL  START        			;起动总线
          MOV    A,SLA
          LCALL  WRBYTE       			;发送器件从地址      
          LCALL  CACK
          JNB    ACK,RETWRN	 		;无应答则退出
          MOV    A,SUBA       	 		;指定子地址 
          LCALL  WRBYTE
          LCALL  CACK
          MOV    R1,#MTD
WRDA:     MOV    A,@R1
          LCALL  WRBYTE       			;开始写入数据
          LCALL  CACK
          JNB    ACK,IWRNBYTE
          INC    R1
          DJNZ   R3,WRDA      			;判断写完没有
RETWRN:   LCALL  STOP
          RET

;----------------------------
;向器件指定子地址读取N字节数据
;入口参数:  器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数:  接收数据缓冲区RTD
;占用:A、 R0、 R1、 R2、 R3、 CY  
;----------------------------             
IRDNBYTE:  MOV    R3,NUMBYTE
           LCALL  START
           MOV    A,SLA
           LCALL  WRBYTE        		;发送器件从地址
           LCALL  CACK
           JNB    ACK,RETRDN
           MOV    A,SUBA        		;指定子地址    
           LCALL  WRBYTE
           LCALL  CACK  
           LCALL  START         		;重新起动总线
           MOV    A,SLA
           INC    A             		;准备进行读操作 
           LCALL  WRBYTE
           LCALL  CACK
           JNB    ACK,IRDNBYTE           
           MOV    R1,#MRD
RDN1:      LCALL  RDBYTE      			;读操作开始
           MOV    @R1,A
           DJNZ   R3,SACK
           LCALL  MNACK       			;最后一字节发非应答位               
RETRDN:    LCALL  STOP 				;并结束总线
           RET
SACK:      LCALL  MACK
           INC    R1
           SJMP   RDN1

;----------------------------
;无子地址器件写N字节数据
;入口参数:  器件从地址SLA、发送数据缓冲区MTD、发送字节数NUMBYTE
; 占用:  A 、R0 、R1 、R3 、CY 
;不发送子地址SUBA,直接发送多个数据.
;----------------------------
IWRNBYTEEXT:
          MOV    A,NUMBYTE
          MOV    R3,A
          LCALL  START        			;起动总线
          MOV    A,SLA
          LCALL  WRBYTE       			;发送器件从地址      
          LCALL  CACK
          JNB    ACK,RETWRNE	 		;无应答则退出
          MOV    R1,#MTD
WRDAE:    MOV    A,@R1
          LCALL  WRBYTE       			;开始写入数据
          LCALL  CACK
          JNB    ACK,RETWRNE
          INC    R1
          DJNZ   R3,WRDAE      			;判断写完没有
RETWRNE:  LCALL  STOP
          RET

;----------------------------

;无子地址器件读取N字节数据
;入口参数:  器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数:  接收数据缓冲区MRD
;占用:A、  R1、  R3、 CY  
;说明:此函数不发送子址,也不重新启动总线,而是直接读取多个数据.
;----------------------------
IRDNBYTEEXT:
           MOV    R3,NUMBYTE
           LCALL  START
           MOV    A,SLA
           INC    A  
           LCALL  WRBYTE        		;发送器件从地址
           LCALL  CACK
           JNB    ACK,RETRDNE
           MOV    R1,#MRD
RDNE1:     LCALL  RDBYTE      			;读操作开始
           MOV    @R1,A
           DJNZ   R3,SACKE
           LCALL  MNACK       			;最后一字节发非应答位               
RETRDNE:   LCALL  STOP 				;并结束总线
           RET
SACKE:     LCALL  MACK
           INC    R1
           SJMP   RDNE1

;*********************************************************************************************
;                        	请注意
;
;    占用内部资源:         R0,R1,R2,R3,ACC,Cy。
;    在你的程序里要做以下定义:
;    1、定义变量:  SLA 器件从地址  SUBA器件子地址  NUMBYTE读/写的字节数 ,位变量ACK 
;    2、定义常量:  SDA SCL 总线位  MTD 发送数据缓冲区首址    MRD 接收数据缓冲区首址
;
;   (ACK为调试/测试位,ACK为0时表示无器件应答或总线出错)
;
;    在使用本软件包时,请在你的程序的未尾加入$INCLUDE (VI2C_ASM.INC)即可。VI2C_ASM.INC文件
;复制到IDE包含文件所要求的目录(如:工作目录或INC目录)
;
;    用户可以对"用户接口子程序"进行裁减,即把自已不使用的接口子程序删掉,以节省程序空间。
;**********************************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -