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

📄 i2cdemo.asm

📁 本程序是一块I2C电路演示板的演示程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
LOOP:	MOV A,@R0
		CLR C
		RRC A
		MOV @R0,A
		INC R0
		MOV A,@R0
		RRC A
		MOV @R0,A
		DEC R0
		DJNZ R3,LOOP
		RET


    
SENDCMD:       	MOV	SLA,#ZLG7290			;指定器件地址
               	MOV	SUBA,#07H			;指定子地址
	       	MOV	NUMBYTE,#02H			;发送2个字节的命令字节数据
	       	LCALL    IWRNBYTE			;调用写n字节数据程序
               	NOP
               	NOP
               	NOP
               	NOP
  	       	RET
SENDCMD1:	MOV	SLA,#ZLG7290	;指定器件地址
		MOV	SUBA,#0CH		;指定子地址
		MOV	NUMBYTE,#01H	;发送2字节数据
		LCALL IWRNBYTE		;调用写n字节数据程序
		RET

;--------------------------------------------------------------------------------------------------------
;		  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两个子程序,
;这两个子程序用于主从通讯上及一此特殊器件的读写操作较为方便.
;					  更新时间:2002.06.04
;--------------------------------------------------------------------------------------------------------

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

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

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

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

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

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


        CLR SCL
        SJMP WLP1

;读取字节子程序                    
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号 
RDBYTE: MOV R0,#08H
RLP:    SETB SDA
        NOP
        SETB SCL         		 	;时钟线为高,接收数据位
        NOP
        NOP
		NOP					;+1
		NOP					;+1
		NOP					;+1
		NOP					;+1
		NOP					;+1
        MOV C,SDA        		 	;读取数据位
        MOV A,R2
        CLR SCL          		 	;将SCL拉低,时间大于4.7us
        RLC A            		 	;进行数据位的处理
        MOV R2,A
        NOP
        NOP
		NOP
        NOP					;+1
		NOP					;+1
		NOP					;+1
		NOP					;+1
		NOP					;+1
        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
;出口参数:  接收数据缓冲区MTD
;占用: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
	   ;NOP					;+1
	   ;NOP					;+1	
           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
;出口参数:  接收数据缓冲区MTD
;占用:A、 R0、 R1、 R2、 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

          END
          
          








⌨️ 快捷键说明

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