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

📄 0335程序.txt

📁 基于MSP430单片机的虚拟I2C总线程序
💻 TXT
字号:
VIIC_M1.0软件包

⑴	MSP430各寄存器的定义:

;*************************************
;定义TP0.0--TP0.5各端口的各种控制寄存器
;*************************************
;
TPD      		.set    		004EH			;TP端口数据寄存器
TPE      		.set    		004FH			;TP端口输出允许寄存器

TP.0           	.set    		01H
TP.1          	.set    		02H
TP.2           	.set    		04H
TP.3           	.set    		08H
TP.4           	.set    		10H
TP.5           	.set    		20H
	
;*************************************************
;定义P0.0--P0.7各端口的各种控制寄存器
;*************************************************
;
P0IN            .set    		0010H			;P0端口输入寄存器
P0OUT           .set    		0011H			;P0端口输出寄存器
P0DIR           .set    		0012H			;P0端口方向寄存器

P0.0          	.set    		01H
P0.1          	.set    		02H
P0.2          	.set    		04H
P0.3          	.set    		08H
P0.4          	.set    		10H
P0.5          	.set    		20H
P0.6          	.set    		40H
P0.7          	.set    		80H
;
CODE			.EQU			0A0H			;从器件编码
SLAR/W			.EQU			1H				;读时为1,写时为0
A0				.EQU			2H				;器件地址位
A1				.EQU			4H				;器件地址位
A2				.EQU			8H				;器件地址位

VSDA	   		.set			80H				;P0.7
VSCL       		.set			02H				;TP.1

SLA				.EQU    		200h			;寻址字节存放单元
Num_byt			.EQU    		201h			;发送数据或接收数据的个数
I2C_R_Addr		.EQU    		202h			;EEPROM字节地址存放单元
;202h为高5位,低8位
MTD				.EQU    		210h			;发送缓冲区
MRD				.EQU    		220h			;接收缓冲区

I2Cdata			.EQU    		R7				;数据暂存单元
Count			.EQU    		R8				;计数器
Mask			.EQU			R9    			;屏蔽字

Subaddr			.EQU			0xxxxh			;EEPROM字节地址
												;Subaddr_H:高5位,Subaddr_L:低8位
N				.EQU			0yyh			;发送或接收的字节数
;
	⑵	子程序集

	①	时序模拟子程序

;ⅰ.开始条件:启动总线
;
I2C_Sta			bis.b      	#VSDA,&P0DIR        ;设置VSDA为输出
     			bis.b     	#VSDA,&P0OUT        ;VSDA输出为高
     			bis.b		#VSCL,&TPE          ;VSCL输出允许
     			bis.b		#VSCL,&TPD          ;VSCL输出为高
     			nop
     			nop
     			bic.b   	#VSDA,&P0OUT        ;VSDA输出为低
    			nop
     			nop
          		bic.b   	#VSCL,&TPD			;VSCL输出为低
    			ret
;
;ⅱ.停止条件:停止数据传送
;
I2C_Stop   		bis.b     	#VSDA,&P0DIR        ;设置VSDA为输出
     			bic.b    	#VSDA,&P0OUT        ;VSDA输出为低
         		bis.b    	#VSCL,&TPD			;VSCL输出为高 
     			nop
     			nop
     			bis.b    	#VSDA,&P0OUT    	;VSDA输出为高
     			nop
     			nop
     			bic.b     	#VSCL,&TPD   		;VSCL输出为低
     			bic.b		#VSCL,&TPD          ;VSCL输出禁止
     			ret
;
;ⅲ.发送应答位
;
I2C_Mack		bis.b   	#VSDA,&P0DIR      	;设置VSDA为输出
     			bic.b    	#VSDA,&P0OUT      	;VSDA输出为低
     			bis.b    	#VSCL,&TPD			;VSCL输出为高
     			nop
     			nop
     			bic.b    	#VSDA,&P0OUT      	;VSDA输出为低
    			bic.b  		#VSCL,&TPD      	;VSCL输出为低
    			bis.b   	#VSDA,&P0OUT		;VSDA输出为高
    			ret
;
;ⅳ.发送非应答位
;
I2C_MNack		bis.b    	#VSDA,&P0DIR    	;设置VSDA为输出
    			bis.b   	#VSDA,&P0OUT		;VSDA输出为高
     			bis.b     	#VSCL,&TPD     		;VSCL输出为高
   				nop
    			nop
    			bic.b    	#VSCL,&TPD			;VSCL输出为低
    			bic.b     	#VSDA,&P0OUT    	;VSDA输出为低
    			ret

	②	操作模拟子程序
;
; ⅰ.检查应答位
; 应答位在进位位(Carry)中
;
I2C_Ackn		bis.b     	#VSCL,&TPD     		;VSCL输出为高,使VSDA上数据有效 
				nop
				nop
      			bic.b     	#VSDA,&P0DIR    	;设置VSDA为输入
				bit.b     	#VSDA,&P0IN			;读数据进近位位(Carry)
												;(Acknowledge bit)
				nop
				nop
    			bic.b    	#VSCL,&TPD			;VSCL输出为低
				nop
    				ret

; ⅱ. 发送数据字节
;
;发送的数据在I2CData中
;占用Mask,I2CData
;
I2C_WR_BYT		mov.b		#80H,Mask			;位屏蔽:MSB 在先
I2C_WR_BYT1		bit.b      	Mask,I2CData		;信息位进进位位(Carry)
      			jc       	I2C_WR_BYT2
				bis.b   	#VSDA,&P0DIR  		;信息位是0
      			bic.b     	#VSDA,&P0OUT    	;VSDA输出为低
      			bis.b     	#VSCL,&TPD       	;VSCL输出为高
   				nop
    			nop
      			bic.b    	#VSCL,&TPD			;VSCL输出为低
      			jmp      	I2C_WR_BYT3
;
I2C_WR_BYT2		bis.b    	#VSDA,&P0DIR 		;信息位是 1
     			bis.b     	#VSDA,&P0OUT		;VSDA输出为高
      			bis.b     	#VSCL,&TPD       	;VSCL输出为高
  				nop
    			nop
     			bic.b   	#VSCL,&TPD			;VSCL输出为低
      			bic.b     	#VSDA,&P0OUT		;VSDA输出为低
;    
I2C_WR_BYT3		clrc
     			rrc.b   	Mask				;指向下一位
     			jnc     	I2C_WR_BYT1			;进位位为0,继续
  				nop
    			nop
     			ret
;
;ⅲ. 接收数据字节
;
;接收的数据在I2CData中
;占用I2CData,Count
;
I2C_RD_BYT		clr          I2CData
      			mov.b		#8,Count   			;设置接收数据字节的移位次数
;
I2C_RD_BYT1		bic.b     	#VSDA,&P0DIR    	;设置VSDA为输入
				bis.b        #VSCL,&TPD       	;VSCL输出为高,使VSDA上数据有效
      			nop
      			bit.b        #VSDA,&P0IN      	;读入的位在C中,是"1"或是"0"?
      			rlc.b        I2CData        	;从进位位开始左移
      			nop
      			nop
      			bic.b        #VSCL,&TPD         ;设置VSCL输出为低,可继续接收数据位
      			nop
      			nop
      			dec         Count
      			jnz         I2C_RD_BYT1  		;8位数据没有移完,则继续移位
				ret

	③ 数据读写子程序
;
;ⅰ.发送N字节数据
;	--从当前地址开始发送
;
;数据在MTD中
;SLA中为SLAW
;字节数在Num_byt中
;占用R6
;调用:I2C_Sta,I2C_WR_BYT,I2C_Ackn,I2C_Stop
;数列格式: S,SLA+W,A,DATA1,A,DATA2,A,....,DATAn,A,P
;
I2C_WR_Nbyte
		
WR_Conrol_byte
				CALL		#I2C_Sta
      			mov.b   	SLA,I2CData			;送出SLAW
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			WR_Conrol_byte		;C=0,继续
WR_Nbyte
				clr			R6
WR_Nbyte1
				MOV.B		MTD(R6),I2CData
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			WR_Nbyte
				inc			R6
				cmp.b		Num_byt,R6
				JNZ			WR_Nbyte1
				CALL		#I2C_Stop
				RET
;
;ⅱ. 接收N字节数据
;	--从当前地址开始读
;
;数据存放在MRD中
;接收的字节数在Num_byt中
;数列格式: S,SLA+R,A,DATA1,A,DATA2,A,....,DATAn,/A,P
;
I2C_RD_Nbyte

RD_Conrol_byte
				CALL		#I2C_Sta
      			mov.b  		SLA,I2CData			;送出SLAR
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			RD_Conrol_byte		;检查应答位
RD_Nbyte
				clr			R6
RD_Nbyte1
				CALL		#I2C_RD_BYT
				MOV.B		I2CData,MRD(R6)
				inc			R6
				cmp.b		Num_byt,R6
				JNZ			RD_Nbyte2
				CALL		#I2C_MNack			;N字节数据读完,送出非应答位
				CALL		#I2C_Stop			;送出Stop
				RET
RD_Nbyte2		CALL		#I2C_Mack			;送出应答位
				JMP			RD_Nbyte1
;
;ⅲ. 向EEPROM发送数据单元地址
;
;EEPROM中字节地址在I2C_R_Addr(高),I2C_R_Addr+1(低)中
;数列格式:S,SLA+W,A,Subaddr_H,A,Subaddr_L,A
;
I2C_WR_Addr
WR_Addr			CALL		#I2C_Sta
      			mov.b    	SLA,I2CData			;送出SLAW
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			WR_Addr
				MOV.b		I2C_R_Addr,I2CData	;送出字节地址的高5位
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			WR_Addr
				MOV.b		I2C_R_Addr+1,I2Cdata	;送出字节地址的低8位
				CALL		#I2C_WR_BYT
				CALL		#I2C_Ackn
				JC			WR_Addr
				RET

⌨️ 快捷键说明

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