?? csi24wc02.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 + -