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

📄 hi2c_asm.inc

📁 飞利浦高性能单片机IIC总线通用通信协议
💻 INC
字号:
;			P89LPC932硬件I2C软件包(主)
;
; 1  使用I2C总线软件包时P1.2,P1.3切勿写为0,并要设置为开漏输出。
; 2  总线定义为P1.2=SCL,P1.3=SDA,需外接上拉电阻2-10k。
; 3  相应寄存器:
;    地址寄存器  I2ADR   用于存放自身从地址(从方式时才有用)
;    数据寄存器  I2DAT   接收/发送数据用
;    控制寄存器  I2CON   用于硬件I2C的设置、使能、启动、结束,
;                        应答控制,中断标志等。
;    状态寄存器  I2STAT  指示I2C总线的操作状态码,高5位有效,
;                        若I2C中断志置位,可查询此寄存器判断
;                        总线情况。
;    SCL占空比寄存器  I2SCLH、I2SCLL  设置SCL的频率发生。
;                        
;    此软件包是以查询方式完成各种总线操作的,在使用前应对总线进行检查,并
;使用看门狗,以防等待总线而造成死机。
;                                  更新时间:2002.11.05
;


;申请总线
;功能:进行I2C总线的初始化--包括时钟选择,I2C使能,发送起始信号等等。
;      I2EN为1,设置为主机;CRSEL位为0,使用内部SCL发生器。
GETBUS:
       MOV   	I2SCLH,#15	;设置SCL高电平的PCLK周期数
       MOV		I2SCLL,#15	;设置SCL低电平的PCLK周期数,6MHz时为100Kbit/S
       MOV   	I2CON,#64H   	;使用内部SCL发生器,I2EN和AA置位,起动总线
       JNB   	SI,$         	;等待起始信号的发送
       RET


;发送数据函数
;功能:用于向总线发送数据
;入口参数:ACC   待发送的数据
SENDBYTE:
       	MOV  	I2DAT,A     	;发送数据
       	MOV  	I2CON,#44H  	;清除SI位等等
      	JNB  	SI,$        	;等待数据的发送
       	RET


;===================================================================================
;		      用户接口子程序

;进行无子地址写单字节
;入口参数:ACC,SLA
;出口参数:ACK为1时表明操作正确 
;R7
IWRBYTE:
     	CLR   	ACK
      	ACALL 	GETBUS       	;启动总线
;      	PUSH  	ACC           	;先保护待发送的数据
	MOV	R7,A
       	MOV   	A,SLA         	;器件寻址        
       	ACALL 	SENDBYTE
        MOV   	A,I2STAT
        CJNE  	A,#18H,IWRBEND	;发送器件地址,若无应答则退出操作(18H是总线状态码)
;       POP   	ACC 
	MOV	A,R7       
        ACALL 	SENDBYTE      	;发送数据
        MOV   	A,I2STAT
        CJNE  	A,#28H,IWRBEND
        SETB  	ACK           	;设置出口标志位
IWRBEND:MOV   	I2CON,#54H   	;结束总线               
        RET        



;进行随机地址多字节写
;入口参数:器件从地址SLA 子地址SUBA  发送数据区MTD  写入字节数NUMBYTE
;出口参数:ACK    为1时操作正确。
;占用R0,R1,ACC
IWRNBYTE: 
       	CLR   	ACK
       	MOV   	R0,#MTD
       	MOV   	R1,NUMBYTE
       	ACALL 	GETBUS         	;启动总线
       	MOV   	A,SLA
       	ACALL 	SENDBYTE 
       	MOV   	A,I2STAT
       	CJNE  	A,#18H,IWRNEND
       	MOV   	A,SUBA
       	ACALL 	SENDBYTE
       	MOV   	A,I2STAT
        CJNE  	A,#28H,IWRNEND	;无应答则退出
         
IWRN_L1:MOV   	A,@R0
       	ACALL 	SENDBYTE       	;发送数据
        MOV   	A,I2STAT
        CJNE  	A,#28H,IWRNEND  ;无应答则退出
        INC   	R0
        DJNZ  	R1,IWRN_L1          
        SETB  	ACK             ;置标志位
IWRNEND:MOV	I2CON,#54H
        RET                  


;进行无子地址多字节写
;入口参数:器件从地址SLA  发送数据区MTD  读入字节数NUMBYTE
;出口参数:ACK    为1时操作正确。
;占用R0,R1,ACC
IWRNBYTEEXT: 
         CLR   	ACK
         MOV   	R0,#MTD
         MOV   	R1,NUMBYTE
         ACALL 	GETBUS        	;启动总线
         MOV   	A,SLA
         ACALL 	SENDBYTE 
         MOV   	A,I2STAT
         CJNE  	A,#18H,IWRNEEND
         
IWRNE_L1:MOV   	A,@R0
         ACALL 	SENDBYTE        ;发送数据
         MOV   	A,I2STAT
         CJNE  	A,#28H,IWRNEEND	;无应答则退出
         INC   	R0
         DJNZ  	R1,IWRNE_L1          
         SETB  	ACK             ;置标志位
IWRNEEND:MOV   	I2CON,#54H
         RET                  



;进行立即地址单字节读
;出口参数:读出值在ACC
;出口参数:ACK    为1时操作正确。
;注:SLA要为写的地址,因为此子程序会自动加1
IRDBYTE:
        CLR   	ACK
        ACALL 	GETBUS
        MOV   	A,SLA
        INC   	A               ;读操作的器件寻址
        ACALL 	SENDBYTE
        MOV   	A,I2STAT
        CJNE  	A,#40H,IRDBEND
        MOV   	I2CON,#40H     	;接收一字节数据即发送非应答位
        JNB   	SI,$            ;等待接收数据
        MOV   	A,I2STAT
        CJNE  	A,#58H,IRDBEND
        MOV   	A,I2DAT         ;读取数据
        SETB  	ACK
IRDBEND:MOV   	I2CON,#54H
        RET




;进行随机地址多字节读
;入口参数:器件从地址SLA 子地址SUBA  接收数据区MRD  读入字节数NUMBYTE
;出口参数:ACK    为1时操作正确。
;占用R0,R1,ACC
IRDNBYTE:    
         CLR   	ACK
         MOV   	R0,#MRD
         MOV   	R1,NUMBYTE
         ACALL 	GETBUS
         MOV   	A,SLA
         ACALL 	SENDBYTE       	;器件寻址
         MOV   	A,I2STAT
         CJNE  	A,#18H,IRDNEND 	;无器件应答即退出
         MOV   	A,SUBA         	;写入器件子地址
         ACALL 	SENDBYTE
         MOV   	A,I2STAT
         CJNE  	A,#28H,IRDNEND 	;总线出错即退出
         MOV   	I2CON,#64H    	;重新启动总线
         JNB   	SI,$
         MOV   	A,SLA
         INC   	A              	;读操作的器件寻址
         ACALL 	SENDBYTE
         MOV   	A,I2STAT
         CJNE  	A,#40H,IRDNEND
         
IRDN_L1: DJNZ   R1,IRDN_L2
         MOV    I2CON,#40H   	;取最后一个数据后发送非应答位
         JNB    SI,$        
         MOV    A,I2STAT       	
         CJNE   A,#58H,IRDNEND
         MOV    A,I2DAT		;将数据取出
         MOV    @R0,A         	;数据存入MRD区中(R0指针指向MRD区)
         SETB   ACK
IRDNEND: MOV    I2CON,#54H
         RET           
IRDN_L2: MOV    I2CON,#44H   	;接收数据并发送应答位
         JNB    SI,$
         MOV    A,I2STAT
         CJNE   A,#50H,IRDNEND	;总线出错即退出
         MOV    A,I2DAT       	;取数据
         MOV    @R0,A         	;数据存入MRD区
         INC    R0
         SJMP   IRDN_L1


;进行无子地址多字节读
;入口参数:器件从地址SLA  接收数据区MRD  读入字节数NUMBYTE
;出口参数:ACK    为1时操作正确。
;占用R0,R1,ACC
IRDNBYTEEXT:    
         CLR   	ACK
         MOV   	R0,#MRD
         MOV   	R1,NUMBYTE

         ACALL 	GETBUS
         MOV   	A,SLA
         INC   	A
         ACALL 	SENDBYTE       	;器件寻址
         MOV   	A,I2STAT
         CJNE  	A,#40H,IRDNEEND
         
IRDNE_L1:DJNZ   R1,IRDNE_L2
         MOV    I2CON,#40H   	;取最后一个数据后发送非应答位
         JNB    SI,$        
         MOV    A,I2STAT       	
         CJNE   A,#58H,IRDNEEND
         MOV    A,I2DAT
         MOV    @R0,A         	;数据存入MRD区中(R0指针指向MRD区)
         SETB   ACK
IRDNEEND:MOV   	I2CON,#54H
         RET           
IRDNE_L2:MOV    I2CON,#44H   	;接收数据并发送应答位
         JNB    SI,$
         MOV    A,I2STAT
         CJNE   A,#50H,IRDNEEND	;总线出错即退出
         MOV    A,I2DAT       	;取数据
         MOV    @R0,A         	;数据存入MRD区
         INC    R0
         SJMP   IRDNE_L1
         
;使用前须在你的程序里要做以下定义:
;定义变量:  SLA 器件从地址  SUBA器件子地址  NUMBYTE读/写的字节数 ,位变量ACK 
;定义常量:  MTD 发送数据缓冲区首址    MRD 接收数据缓冲区首址
;
;定义LPC932的I2C相关寄存器的定义
;I2ADR	DATA	0DBH
;I2DAT	DATA	0DAH		
;I2CON	DATA	0D8H
;I2STAT	DATA	0D9H
;I2SCLH	DATA	0DDH
;I2SCLL	DATA	0DCH
;STA	BIT	I2CON.5
;SI	BIT	I2CON.3
;
;软件包接口
;(1)IRDBYTE  立即地址读单字节子程序
;       入口:器件从地址SLA
;       出口:读出数据ACC,应答位ACK。
;       占用资源:ACC,CY
;       
;(2)IRDNBYTE 随机地址读多字节子程序
;       入口:器件从地址SLA,器件子地址SUBA,读出字节数NUMBYTE
;       出口:读出数据依次放在MRD区,应答位ACK。
;       占用资源:R0,R1,ACC,CY
;
;(3)IWRBYTE  立即地址写单字节子程序
;       入口: 器件从地址SLA,写入的数据ACC
;       出口: 应答位ACK。
;       占用资源:ACC,CY,一字节堆栈
;
;(4)IWRNBYTE 立即地址写多字节子程序
;       入口: 器件从地址SLA,写入的数据依次放在MTD区
;       出口: 应答位ACK。
;       占用资源:R0,R1,ACC,CY
;(ACK为调试/测试位,ACK为0时表示无器件应答或总线出错)
;
;(5)IWRNBYTEEXT 进行无子地址多字节写
;       入口:器件从地址SLA  发送数据区MTD  读入字节数NUMBYTE
;       出口:ACK    为1时操作正确。
;       占用资源:R0,R1,ACC
;
;(6)IRDNBYTEEXT 进行无子地址多字节读
;	入口:器件从地址SLA  接收数据区MRD  读入字节数NUMBYTE
;	出口:ACK    为1时操作正确。
;	占用资源:R0,R1,ACC

         

⌨️ 快捷键说明

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