📄 wreeprom.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 + -