📄 i2cdisp.s
字号:
;******************************************************************************
; 文件名:I2CDISP.S
; 功能:使用硬件I2C对ZLG7290进行操作,使用查询方式操作。
; 说明:将跳线器JP5短接。
;******************************************************************************
INCLUDE LPC2294.INC
EXPORT MAIN
I2C_BASE EQU 0xE001C000
ZLG7290 EQU 0x70 ; 定义ZLG7290从地址
AREA I2CDISPC,CODE,READONLY
ENTRY
MAIN LDR SP,=0x40003F00 ; 设置堆栈指针SP
LDR R0,=PINSEL0 ; 设置I2C控制口有效
MOV R1,#0x50
STR R1,[R0]
BL SYSCLK_INI ; 设置系统时钟
; 设置I2C时钟为30KHz (Fpclk=11.0592MHz)
LDR R0,=I2C_BASE
MOV R1,#184
STR R1,[R0,#0x10] ; I2SCLH=184
STR R1,[R0,#0x14] ; I2SCLL=184
BL ZLG7290_DISP ; 显示"LPC2210F"
HALT B HALT
;******************************************************************************
; 名称:ZLG7290_DISP
; 功能:发送显示数据到ZLG7290显示。
; 入口参数:无
; 出口参数:无
; 占用资源:(R2、R3、R4、R5)
;******************************************************************************
ZLG7290_DISP
STMFD SP!,{R0-R7,LR}
MOV R2,#ZLG7290 ; 设置从机地址
MOV R3,#0x10 ; 指定子地址
LDR R4,=DISP_DAT ; 指定数据发送区
MOV R5,#8 ; 发送8个数据
BL IWRNBYTE ; 调用IWRNBYTE
LDMFD SP!,{R0-R7,PC}
; 定义特殊字模,字段格式:a b c d e f g h
Sa EQU (1<<7)
Sb EQU (1<<6)
Sc EQU (1<<5)
Sd EQU (1<<4)
Se EQU (1<<3)
Sf EQU (1<<2)
Sg EQU (1<<1)
Sh EQU (1<<0)
CHAR_L EQU (Sd|Se|Sf)
CHAR_P EQU (Sa|Sb|Se|Sf|Sg)
CHAR_C EQU (Sa|Sd|Se|Sf)
CHAR_2 EQU (Sa|Sb|Sd|Se|Sg)
CHAR_1 EQU (Sb|Sc)
CHAR_0 EQU (Sa|Sb|Sc|Sd|Se|Sf)
CHAR_F EQU (Sa|Se|Sf|Sg)
; 显示数据定义,"LPC2210F"
DISP_DAT DCD CHAR_F, CHAR_0, CHAR_1, CHAR_2, CHAR_2, CHAR_C, CHAR_P, CHAR_L, 0x00
;******************************************************************************
; 名称: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
;******************************************************************************
; 名称: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 + -