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

📄 csi24wc02.s

📁 Easyarm实验开发平台
💻 S
字号:
;******************************************************************************	
; File:CSI24WC02.S
; 功能:使用LPC210x模拟EEPROM器件CSI24WC02。LPC210x具有硬件I2C接口,使用其从方式进行
;      I2C器件模拟,本例使用了256字节的RAM作为存储单元。
; 说明:将跳线器JP12断开,然后与主机连接。
;******************************************************************************	
		        INCLUDE     LPC2106.INC
		
CSI24WC02       EQU 	0xA1                            ; 定义从要地址,忽略通用地址
EEPROM          EQU     0x40003000                      ; 定义EEPROM存储单元,地址为0x40003000--0x400030FF
ADRPOINT        EQU     0x40003100                      ; 定义EEPROM读写操作指针
SLARCV          EQU     0x40003104                      ; 定义子地址接收标志,为1时表示己接收从机地址

		
		        AREA   	EEPROMC,CODE,READONLY 
		        ENTRY		
		    
                ; 异常向量   
Vectors         LDR     PC, ResetAddr
                LDR     PC, UndefinedAddr
                LDR     PC, SWI_Addr
                LDR     PC, PrefetchAddr
                LDR     PC, DataAbortAddr
                NOP
                LDR     PC, IRQ_Addr
                LDR     PC, FIQ_Addr

ResetAddr       DCD     Reset
UndefinedAddr   DCD     Undefined
SWI_Addr        DCD     SoftwareInterrupt
PrefetchAddr    DCD     PrefetchAbort
DataAbortAddr   DCD     DataAbort
Nouse           DCD     0
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler

; 中断服务程序
Undefined
SoftwareInterrupt
PrefetchAbort
DataAbort
FIQ_Handler
                B       .


; IRQ中断处理(I2C中断处理)
IRQ_Handler
                STMFD   SP!,{R0-R12,LR}                 ; 现场保护
                
                ; 读取状态码,然后进行分析及控制
                LDR     R0,=I2C_BASE
                LDR     R1,[R0,#0x04]
                AND     R1,R1,#0xF8
                
                CMP     R1,#0x60                        ; 判断是否接收到自身SLA+W                                             
                CMPNE   R1,#0x68                       
                BEQ     SLAWR                           ; 接收到自身SLA+W 
                
                CMP     R1,#0xA8                        ; 判断是否接收到自身SLA+R
                CMPNE   R1,#0xB0
                BEQ     SLARD                           ; 接收到自身SLA+R
                
                CMP     R1,#0x80
                BEQ     RCV_DAT                         ; 前一次寻址接收到自身SLA+W,己接收数据,并返回ACK
                
                CMP     R1,#0xB8
                BEQ     SEND_DAT
                
                CMP     R1,#0xC0                        ; 己发送数据,并接收到非应答信号  
                BEQ     STOP_BUS
                
                CMP     R1,#0xA0                        ; 接收到停止条件或重复起动条件A0H
                BEQ     STOP_BUS
                 
                ; 接收其它状态值,则设置SI=0,AA=1,然后退出
OTHER_STA       MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        ; 退出中断(会清除SI位)
                
;******************************************************************************		
; 从接收状态,即接收到SLA+W。
; 将子地址接收标志置0,然后退出。
;****************************************************************************** 
SLAWR           MOV     R1,#0
                LDR     R2,=SLARCV
                STR     R1,[R2]                         ; 子地址接收标志置0
                MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        ; 退出中断(会清除SI位)      
                
;******************************************************************************		
; 从发送状态,即接收到SLA+R,或已发送数据并接收到ACK位。
; 发送当前读写指针的一字节数据,并将读写指针自动加1。
;******************************************************************************                
SLARD           
SEND_DAT        LDR     R1,=EEPROM                      ; 取得E2PROM操作实际地址
                LDR     R2,=ADRPOINT
                LDR     R2,[R2]
                ADD     R2,R2,R1
                LDRB    R1,[R2]                         ; 读出数据
                AND     R1,R1,#0xFF
                STR     R1,[R0,#0x08]                   ; 发送数据
                LDR     R2,=ADRPOINT                    ; 读写指针加1
                LDR     R1,[R2]
                ADD     R1,R1,#1
                AND     R1,R1,#0xFF
                STR     R1,[R2] 
                MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        
 
 
;******************************************************************************		
; 接收主要发送的数据。
; 程序先判断是否接收子地址,若没有接收,则接收并设置读写指针及该标志;
; 若程序已接收子地址,则开始接收数据,并将读写指针自动加1。
;******************************************************************************  
RCV_DAT         LDR     R2,=SLARCV                      ; 判断SLARCV是否为0
                LDR     R1,[R2]
                CMP     R1,#0
                BEQ     RCVSLA                          ; 若是,则接收子地址  
                
RCVDATA         LDR     R1,=EEPROM                      ; 取得E2PROM操作实际地址
                LDR     R2,=ADRPOINT
                LDR     R2,[R2]
                ADD     R2,R2,R1
                LDR     R1,[R0,#0x08]                   ; 接收数据,写入模拟E2PROM
                AND     R1,R1,#0xFF
                STRB    R1,[R2]
                LDR     R2,=ADRPOINT                    ; 读写指针加1
                LDR     R1,[R2]
                ADD     R1,R1,#1
                AND     R1,R1,#0xFF
                STR     R1,[R2] 
                MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        ; 退出中断
                
                
RCVSLA          LDR     R1,[R0,#0x08]                   ; 读取接收到的数据I2DAT
                LDR     R2,=ADRPOINT
                STR     R1,[R2]                         ; 设置读写指针ADRPOINT
                MOV     R1,#1
                LDR     R2,=SLARCV                     
                STR     R1,[R2]                         ; 设置SLARCV标志为1
                MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        ; 退出中断
                
;******************************************************************************		
; 结束总线,设置SI=0,AA=1。
;******************************************************************************
STOP_BUS        MOV     R1,#0x04
                STR     R1,[R0]                         ; 设置AA=1
                B       EXIT_IRQ                        ; 退出中断(会清除SI位)                 
                                
EXIT_IRQ        MOV     R1,#0x38
                STR     R1,[R0,#0x18]                   ; 清除标I2C标志位,STA、STO、SI
                LDMFD   SP!,{R0-R12,LR}                 ; 恢复现场
                SUBS    PC,LR,#4



;******************************************************************************		
; 主程序,进行I2C从机设置,并初始化EEPROM操作指针。
;******************************************************************************
Reset           MSR     CPSR_c,#0xd2                    ; 切换到IRQ模式
                LDR     R0,=0x40003F00                  ; 设置IRQ模式的堆栈,0x40003E00-0x40003EFF
                MOV     SP,R0                           
                MSR     CPSR_c,#0x53                    ; 切换到管理模式并开放IRQ中断                
                LDR     R0,=0x40003FFF                  ; 设置管理模式的堆栈,0x40003F00-0x40003FFF
                MOV     SP,R0
                
                LDR     R0,=MEMMAP                      ; REMAP操作。(若使用0地址写入到FLASH,则不要使用REMAP)                                     
                MOV     R1,#0x02
                STR     R1,[R0]
                          
                LDR     R0,=ADRPOINT          
                MOV     R1,#0
                STR     R1,[R0]                         ; 初始化读写指针为0
                LDR     R0,=SLARCV
                STR     R1,[R0]                         ; 子地址接收标志置0
                
                ; 设置为从机方式
                LDR	    R0,=PINSEL0		                ; 设置I2C控制口有效
		        MOV	    R1,#0x50		
		        STR	    R1,[R0] 
		        
		        LDR     R0,=I2C_BASE	        
		        MOV     R1,#CSI24WC02
		        STR     R1,[R0,#0x0C]                   ; 设置从机地址,I2ADR=CSI24WC02
		        
		        MOV     R1,#0x44
		        STR     R1,[R0]                         ; I2C配置为从机模式,I2CONSET=0x44
		        
		        ; 允许I2C中断(设置为非向量IRQ)
		        LDR     R0,=VIC_BASE_ADDR
		        MOV     R1,#0x00
		        STR     R1,[R0,#0x0C]                   ; 所有中断设置为IRQ中断,VICIntSelect=0x00
		        MOV     R1,#0x0200
		        STR     R1,[R0,#0x10]                   ; 允许I2C中断,VICIntEnable=0x0200
		        
		        B       .                               ; 等待I2C中断
		                              
                END
                
                
                
                
		    
		    
		

⌨️ 快捷键说明

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