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

📄 wreeprom.s

📁 I2C总线的实例程序
💻 S
字号:
/******************************************************************************	
* 文件名:WREEPROM.S
* 功能:使用硬件I2C对CSI24WC02进行读写操作。若操作失败,则进行报警。
*      使用查询方式操作I2C。
* 说明:将跳线器JP9、J4_LED4短接。
*******************************************************************************/ 
			.INCLUDE		"LPC2294.INC"
			.global main

			.EQU	I2C_BASE,		0xE001C000

			.EQU	LEDCON,	    	(1<<25)			/* LED4控制,用于报警显示 */

			.EQU	CSI24WC02,	    0xA0			/* 定义CSI24WC02从地址 */

		    .EQU	RDBUF,		    0x40002F00      /* 数据接收缓冲区 */
		
		
		    .text
		    .arm 					
main: 		LDR	    SP,=0x40003000	/* 设置堆栈指针SP */
		    LDR	    R0,=PINSEL0		/* 设置I2C控制口有效 */
		    MOV	    R1,#0x50		
		    STR	    R1,[R0]

		    LDR	    R0,=IO0DIR		/* 设置LED4控制口为输出 */
		    MOV	    R1,#LEDCON
		    STR	    R1,[R0]	
		    
		    BL		SYSCLK_INI		/* 设置系统时钟 */
		    
		    LDR     R0,=I2C_BASE
		    MOV     R1,#14
		    STR     R1,[R0,#0x10]  /* I2SCLH=14 */
		    STR     R1,[R0,#0x14]  /* I2SCLL=14 */
		    
		
		    /* 写EEPROM */
		    MOV	    R2,#CSI24WC02	/* 器件从地址 */ 
		    MOV	    R3,#0x00		/* 存储地址 */
		    LDR	    R4,=WRDATA		/* 所要写的数据地址指针 */
		    MOV	    R5,#5			/* 设置写入EEPROM的数据个数 */
		    BL	    IWRNBYTE		/* 调用IWRNBYTE */
		    BL	    DELAYS			/* 延时,等待写周期结束 */
				
		    /* 读出并校验 */
		    MOV	    R2,#CSI24WC02	/* 器件从地址 */
		    MOV	    R3,#0x00		/* 存储地址 */
		    LDR	    R4,=RDBUF		/* 保存数据的缓冲区地址指针 */
		    MOV	    R5,#5			/* 读出数据个数 */
		    BL	    IRDNBYTE		/* 调用IRDNBYTE */
		    LDR	    R0,[R4]			/* 取出数据 */
		    CMP	    R0,#0x58
		    BLNE	EEPROM_ERR		/* 写出错,报警 */
		
		    LDR	    R0,=IO0CLR
		    MOV	    R1,#LEDCON	
		    STR	    R1,[R0]			/* LED4控制I/O复位,即LED4点亮 */
		    B	    .


/******************************************************************************		
* 名称:SYSCLK_INI
* 功能:设置系统时钟。(M值为4,P值为2)
* 入口参数:无
* 出口参数:无
* 占用资源:R0、R1		
******************************************************************************/
SYSCLK_INI:
			LDR		R0,=VPBDIV
			MOV		R1,#0x00
			STR		R1,[R0]					/* VPBDIV=0x00 */
			
			LDR		R0,=PLLCFG
			MOV		R1,#0x23
			STR		R1,[R0]					/* PLLCFG=0x23,设置M值为4,P值为2 */
			LDR		R0,=PLLCON
			MOV		R1,#0x01
			STR		R1,[R0]					/* PLLCON=0x01 */
			LDR		R0,=PLLFEED
			MOV		R1,#0xAA
			STR		R1,[R0]					/* PLLFEED=0xAA */
			MOV		R1,#0x55
			STR		R1,[R0]					/* PLLFEED=0x55 */
WAIT_OK:	LDR		R0,=PLLSTAT				
			LDR		R1,[R0]
			ANDS	R1,R1,#0x0400
			BEQ		WAIT_OK					/* 等待PLL锁定 */
			
			LDR		R0,=PLLCON
			MOV		R1,#0x03
			STR		R1,[R0]
			LDR		R0,=PLLFEED
			MOV		R1,#0xAA
			STR		R1,[R0]
			MOV		R1,#0x55
			STR		R1,[R0]	
			
			MOV		PC,LR
					    
		    
/******************************************************************************	
* 名称:EEPROM_ERR
* 功能:出错报警。本程序一直闪动LED报警。
* 入口参数:无
* 出口参数:无
* 占用资源:R0、R1、R7
******************************************************************************/
EEPROM_ERR:
EEPROMER_L1:MOV	    R1,#LEDCON		/* 设置GPIO控制参数 */
LEDSET:		LDR	    R0,=IO0SET			
		    STR	    R1,[R0]			/* LED4控制I/O置位,即LED4熄灭 */
		    BL	    DELAYS
		
LEDCLR:		LDR	    R0,=IO0CLR
		    STR	    R1,[R0]			/* LED4控制I/O复位,即LED4点亮 */
		    BL	    DELAYS
		    B	    EEPROMER_L1
		
		
/******************************************************************************		
* 名称:DELAYS
* 功能:软件延时
* 入口参数:无
* 出口参数:无
* 占用资源:R7
******************************************************************************/
DELAYS:
		    MOV	    R7,#0x000FF000	/* 延时参数 */
DELAYS_L1:	SUBS	R7,R7,#1		/* R7 = R7-1 */
		    BNE	    DELAYS_L1       /* 判断R7-1结果是否为0,若不为0则跳转 */
		    MOV	    PC,LR			/* 返回 */
		
		    .ALIGN				    /* 数据字对齐 */
		    .LTORG				    /* 声明文字池 */
		
		
WRDATA:	    .long  	0x58, 0x59, 0x60, 0x61, 0x62, 0x00			    
		


		
/******************************************************************************		
* 名称:START_I2C
* 功能:起动总线
* 入口参数:无
* 出口参数:无
* 占用资源:R0、R1		
******************************************************************************/
START_I2C:
		    LDR	    R0,=I2C_BASE
		
		    MOV	    R1,#0x2C
		    STR	    R1,[R0,#0x18]	/* 清除所有标志位(I2CONCLR=0x2C) */
		
		    MOV	    R1,#0x40
		    STR	    R1,[R0]			/* 设置为主机(I2CONSET=0x40) */
		    MOV	    R1,#0x60		
		    STR	    R1,[R0]			/* 起动总线,AA=0 */
START_I2CL1:LDR	    R1,[R0]			/* 等待SI为1 */
		    ANDS	R1,R1,#0x08
		    BEQ	    START_I2CL1
		
		    MOV	    PC,LR			/* 返回 */
	
	
/******************************************************************************		
* 名称:SENDBYTE			
* 功能:发送一字节数据
* 入口参数:R2	要发送的数据,低8位有效
* 出口参数:无
* 占用资源:R0、R1、R2
******************************************************************************/
SENDBYTE:
		    LDR	    R0,=I2C_BASE 
				
		    STR	    R2,[R0,#0x08]	/* 发送数据,I2DAT=data */
		    MOV	    R1,#0x28		
		    STR	    R1,[R0,#0x18]	/* 清除标志位STA,SI(I2CONCLR=0x28) */
		
SENDBYTE_L1:LDR	    R1,[R0]			/* 等待SI为1 */
		    ANDS	R1,R1,#0x08
		    BEQ	    SENDBYTE_L1
		
		    MOV	    PC,LR
	
	
/******************************************************************************		
* 名称:RCVBYTE_NA
* 功能;接上I2C总线上一字节数据,并发送非应答位
* 入口参数:无
* 出口参数:R2		读出的数据
* 占用资源;R0、R1、R2
******************************************************************************/ 
RCVBYTE_NA:
		    LDR	    R0,=I2C_BASE	
		
		    MOV	    R1,#0x0C
		    STR	    R1,[R0,#0x18]	/* 清零AA,即发送非应答位. 同时清除SI,允许接收数据(I2CONCLR=0x0C) */
			
RCVBYTE_NAL1:
            LDR	    R1,[R0]			/* 等待SI为1 */
		    ANDS	R1,R1,#0x08
		    BEQ	    RCVBYTE_NAL1
		    LDR	    R2,[R0,#0x08]	/* 读取接收到的数据 */
		
		    MOV	    PC,LR
		
		
/******************************************************************************		
* 名称:RCVBYTE_A
* 功能;接上I2C总线上一字节数据,并发送应答位
* 入口参数:无
* 出口参数:R2		读出的数据
* 占用资源;R0、R1、R2
******************************************************************************/ 
RCVBYTE_A:
		    LDR	    R0,=I2C_BASE	
		
		    /* 置位AA,即发送应答位. 同时清除SI,允许接收数据(I2CONCLR=0x08) */
		    MOV     R1,#0x04
		    STR		R1,[R0]
		    MOV	    R1,#0x08
		    STR	    R1,[R0,#0x18]	
			
RCVBYTE_AL1:LDR	    R1,[R0]			/* 等待SI为1 */
		    ANDS	R1,R1,#0x08
		    BEQ	    RCVBYTE_AL1
		    LDR	    R2,[R0,#0x08]	/* 读取接收到的数据 */
		
		    MOV	    PC,LR		
		

/******************************************************************************
* 名称:STOP_I2C
* 功能:结束总线
* 入口参数:无
* 出口参数:无
* 占用资源:R0、R1
******************************************************************************/
STOP_I2C:
		    LDR	    R0,=I2C_BASE	
		    
		    MOV	    R1,#0x50
		    STR	    R1,[R0]			/* 发送结束总线信号 */
		    MOV	    R1,#0x2C
		    STR	    R1,[R0,#0x18]	/* 清除标志位STA,SI。(I2CONCLR=0x2C) */
		
		    MOV	    PC,LR
		
			
/******************************************************************************		
* 名称:IWRBYTE
* 功能:向指定从机,发送一字节数据。(无子地址)
* 入口参数:R2		从要地址
*	   R3		所要发送的数据
* 出口参数:无
* 占用资源:R0、R1、R2、R3
******************************************************************************/ 
IWRBYTE:
		    STMFD	SP!,{R0-R7,LR}
		
		    BL	    START_I2C		/* 起动总线 */
		    BL	    SENDBYTE		/* 发送从机地址 */
		    MOV	    R2,R3
		    BL	    SENDBYTE		/* 发送数据 */
		    BL	    STOP_I2C		/* 结束总线 */
		
		    LDMFD	SP!,{R0-R7,PC}	/* 返回操作 */
		

/******************************************************************************
* 名称:IWRNBYTE
* 功能:向指定从机,发送多字节数据。
* 入口参数:R2		从要地址
*	   R3		子地址
*	   R4		要发送的数据的地址指针
* 	   R5		要发送的数据个数
* 出口参数:无
* 占用资源:R0、R1、R2、R3、R4、R5
******************************************************************************/
IWRNBYTE:
		    STMFD	SP!,{R0-R7,LR}
		    CMP	    R5,#0			/* 参数过滤,若发送个数为0,则直接退出 */
		    BEQ	    IWRNBYTE_END
		
		    BL	    START_I2C		/* 起动总线 */
		    BL	    SENDBYTE		/* 发送从机地址 */
		    MOV	    R2,R3
		    BL	    SENDBYTE		/* 发送子地址 */
		
IWRNBYTE_L1:LDR	    R2,[R4],#4		/* 读取要发送的数据,且R4 = R4 + 4 */
		    BL	    SENDBYTE		/* 发送数据 */
		    SUBS	R5,R5,#1
		    BNE	    IWRNBYTE_L1
		
		    BL	    STOP_I2C		/* 结束总线 */
		
IWRNBYTE_END:
            LDMFD	SP!,{R0-R7,PC}	/* 返回操作 */
		

/******************************************************************************		
* 名称:IRDBYTE
* 功能:向指定从机读取一字节数据。(无子地址)
* 入口参数:R2		从要地址
* 出口参数:R2		读出的数据
* 占用资源:R0、R1、R2
* 说明:本程序会对从机地址进行自动加1处理		
******************************************************************************/
IRDBYTE:
		    STMFD	SP!,{R0,R1,R3-R7,LR}
		
		    ADD	    R2,R2,#1		/* 设置为读操作 */
		    BL	    START_I2C		/* 起动总线 */
		    BL	    SENDBYTE		/* 发送从机地址 */
		    BL	    RCVBYTE_NA		/* 接收1字节数据,并发送非应答位 */
		    BL	    STOP_I2C		/* 结束总线 */
				
		    LDMFD	SP!,{R0,R1,R3-R7,PC}		/* 返回操作 */
		
		
/******************************************************************************		
* 名称:IRDNBYTE
* 功能:向指定从机读取多字节数据。
* 入口参数:R2		从要地址
*	   R3		子地址
*	   R4		要接收的数据的地址指针
* 	   R5		要发送的数据个数
* 出口参数:无
* 占用资源:R0、R1、R2、R3、R4、R5、R6
* 说明:本程序会对从机地址进行自动加1处理	
******************************************************************************/
IRDNBYTE:
		    STMFD	SP!,{R0-R7,LR}
		    CMP	    R5,#0			/* 入口参数过滤,若操作数据个数为0,直接退出 */
		    BEQ	    IRDNBYTE_END
		
		    BL	    START_I2C		/* 起动总线 */
		    BL	    SENDBYTE		/* 发送从机地址 */
		    MOV	    R6,R2			/* 暂存从机地址 */
		    MOV	    R2,R3
		    BL	    SENDBYTE		/* 发送子地址	*/
		    MOV	    R2,R6
				
		    BL	    START_I2C		/* 重新启动总线 */
		    ADD	    R2,R2,#1
		    BL	    SENDBYTE		/* 发送从机地址 */
		
IRDNBYTE_L2:CMP	    R5,#1
		    BLNE	RCVBYTE_A
		    BLEQ	RCVBYTE_NA
		    STR	    R2,[R4],#4		/* 保存读出的数据 */
		    SUBS	R5,R5,#1
		    BNE	    IRDNBYTE_L2		/* 判断是否读完毕 */
	
		    BL	    STOP_I2C		/* 结束总线 */
		
IRDNBYTE_END:
            LDMFD	SP!,{R0-R7,PC} 
		
		
		    .END

⌨️ 快捷键说明

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