📄 wreeprom.s
字号:
;******************************************************************************
; 文件名:WREEPROM.S
; 功能:使用硬件I2C对CSI24WC02进行读写操作。若操作失败,则进行报警。
; 使用查询方式操作I2C。
; 说明:将跳线器JP9、J4_LED4短接。
;******************************************************************************
INCLUDE LPC2294.INC
EXPORT MAIN
I2C_BASE EQU 0xE001C000
LEDCON EQU (1<<25) ; LED4控制,用于报警显示
CSI24WC02 EQU 0xA0 ; 定义CSI24WC02从地址
RDBUF EQU 0x40002F00 ; 数据接收缓冲区
AREA WREEPROMC,CODE,READONLY
CODE32
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 DCD 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,#0x2C
STR R1,[R0,#0x18] ; 清除标志位STA,SI。(I2CONCLR=0x2C)
MOV R1,#0x50
STR R1,[R0] ; 发送结束总线信号
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 + -