?? i2c24xx.asm
字號:
;=============================================================================
;軟件模擬I2C總線對24XX01/02/04/08/16/32/64系列串行EEPROM進行讀寫程序
;說明:24XX01的頁操作緩沖區是8字節,24XX02/04/08/16的頁操作緩沖區是16字節
; 24XX32/64的頁操作緩沖區是32字節
;=============================================================================
SCL BIT P1.0 ;24系列串行EEPROM的時序控制端
SDA BIT P1.1 ;24系列串行EEPROM的數據控制端
WP BIT P1.2 ;24系列串行EEPROM的數據寫操作使能控制端
;
EEPROM_ACK_LABL BIT MAIN_LABL0.0 ;24系列串行EEPROM寫應答標志位,“0”表示正確應答
RCV_RUN_LABL BIT MAIN_LABL0.1 ;24系列串行EEPROM讀請求標志位,“0”表示允許讀數據
I2C_24XX_TYPE_LABL BIT MAIN_LABL0.2 ;24系列串行EEPROM的器件類型標志位,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
;
I2C_24XX_SLAVE_ADDR EQU 10100000B ;24系列串行EEPROM的器件從設備當前地址
;
;=============================================================================
; 延時子程序
;=============================================================================
DELAY5US: MOV R5,#3
DJNZ R5,$
RET
;=============================================================================
;發送I2C起始位程序
;=============================================================================
START_I2C: SETB SDA ;發送起始條件的數據信號
NOP
SETB SCL ;發送起始條件的時鐘信號
CALL DELAY5US
CLR SDA ;發送起始信號
CALL DELAY5US
CLR SCL ;鉗住I2C總線準備發送或接收數據
RET
;=============================================================================
;發送I2C停止位程序
;=============================================================================
STOP_I2C: CLR SDA ;發送停止條件的數據信號
NOP
SETB SCL ;發送停止條件的時鐘信號
CALL DELAY5US
SETB SDA ;發送I2C總線停止信號
CALL DELAY5US
RET
;
;=============================================================================
;發送一個字節數據或地址給被控器(24XX01/02/04/08/16/32/64系列串行EEPROM)程序
;入口:待發送的數據在ACC中(被控制器的地址當前已指定)
;出口:標志位EEPROM_ACK_LABL=0表示發送數據正常,EEPROM_ACK_LABL=1表示發送數據失敗、被控器無應答或損壞
;=============================================================================
SENT_BYTE: MOV R7,#08H ;要傳送的數據長度為8位
SENT_BYTE_01: RLC A ;要發送的數據左移,發送位入C
JC SENT_BYTE_02 ;發送位為“1”轉發送數據位“1”
CLR SDA ;發送數據位“0”
JMP SENT_BYTE_03 ;轉發送數據位
SENT_BYTE_02: SETB SDA ;發送數據位“1”
NOP
SENT_BYTE_03: NOP
SETB SCL ;置時鐘線為高通知被控器開始接收數據位
CALL DELAY5US
CLR SCL ;鉗住總線準備接收下一個數據位
DJNZ R7,SENT_BYTE_01 ;8位沒發送完繼續發送
CLR EEPROM_ACK_LABL ;預先清發送數據狀態標志
MOV R6,#6
SENT_BYTE_04: NOP
NOP
SETB SDA ;8位發送完后釋放數據線準備收應答位
NOP
NOP
SETB SCL ;開始接收應答信號
NOP
NOP
JNB SDA, SENT_BYTE_END ;判斷是否接收到應答信號正常轉SENT_BYTE_END
DJNZ R6,SENT_BYTE_04
SETB EEPROM_ACK_LABL ;未收到應答置位錯誤標志
SENT_BYTE_END: NOP
CLR SCL ;發送結束鉗住總線準備下一步發送或接收數據或進行其它處理
RET
;
;=============================================================================
;從被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)讀取一個字節數據程序
;入口:RCV_RUN_LABL為是否允許后續再次讀取數據標志位(被控制器的地址當前已指定)
;出口:讀取的數據存放在ACC中
;=============================================================================
RCV_BYTE: SETB SDA ;置數據線為輸入方式
MOV R7,#08H ;要傳送的數據長度為8位
RCV_BYTE_01: NOP
CLR SCL ;置時鐘線為低準備接收數據位
CALL DELAY5US
SETB SCL ;置時鐘線為高使數據線上數據有效
CALL DELAY5US
CLR C ;準備將接收的數據位放入ACC中
JNB SDA,RCV_BYTE_02 ;讀數據位若為“0”則置C=0并轉RCV_BYTE_02接收數據位
SETB C ;讀數據位若為“1”則置C=1
RCV_BYTE_02: RLC A ;接收的數據位放入ACC中
NOP
NOP
DJNZ R7,RCV_BYTE_01 ;8位沒收完繼續接收
CLR SCL ;8位接收完置時鐘線和數據線為低準備發送應答或非應答信號
NOP
NOP
NOP
CLR SDA
JNB RCV_RUN_LABL,RCV_BYTE_03 ;判斷是否需要繼續接收字節數據若需要則轉RCV_BYTE_03發送應答位
SETB SDA ;發送非應答信號
RCV_BYTE_03: NOP ;以下程序發送應答位
NOP
SETB SCL ;置時鐘線為高使應答位有效
CALL DELAY5US
CLR SCL ;清時鐘線鉗住I2C總線以便繼續接收字接數據或發送停止條件
CLR RCV_RUN_LABL ;清接收非應答標志
NOP
NOP
CLR SDA
RET
;
;=============================================================================
;向被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)寫入多個字節數據程序
;入口:DPTR為待寫入的數據的首地址,R0為待寫入數據的存儲緩存區首地址,R2為待寫入數據的字節數,
; I2C_24XX_TYPE_LABL為當前24系列串行EEPROM的器件類型,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
;出口:數據寫入正常,標志位EEPROM_ACK_LABL=0;否則EEPROM_ACK_LABL=1
;說明:24XX01的頁操作緩沖區是8字節,24XX02/04/08/16的頁操作緩沖區是16字節
; 24XX32/64的頁操作緩沖區是32字節
; 一次此操作過程只能對本頁內地址進行數據的寫入且字節數不能超過該器件頁緩沖區的字節數。
;=============================================================================
WR_24XX_DATA: CLR WP ;寫數據使能允許
CALL START_I2C ;發送I2C 總線起始條件
JB I2C_24XX_TYPE_LABL,WR_24XX_DATA_01;判斷當前24系列串行EEPROM的器件類型,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
MOV A,DPH ;待寫入數據的高位地址
ANL A,#0FH ;屏蔽高位地址中的無效數據
CLR C ;確定寫操作命令標志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址,帶寫入數據的高位地址及寫命令
CALL SENT_BYTE ;發送被控器總線地址及數據高位地址及命令
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
SJMP WR_24XX_DATA_02
WR_24XX_DATA_01:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址
CLR C ;確定寫操作命令標志
MOV ACC.0,C ;確定被控器總線地址及寫命令
CALL SENT_BYTE ;發送被控器總線地址及命令
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
MOV A,DPH ;待寫入數據的高位地址
CALL SENT_BYTE ;發送待寫入數據的高位地址
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_02:MOV A,DPL ;待寫入的數據首字節地址低位字節
CALL SENT_BYTE ;發送待寫入數據的低位地址
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_03:MOV A,@R0
CALL SENT_BYTE ;發送待寫入的數據字節
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
INC R0
DJNZ R2,WR_24XX_DATA_03
CALL STOP_I2C ;發送I2C 總線停止條件
MOV R7,#28H ;延時10ms,等待數據寫完
MOV R6,#00H
WR_24XX_DATA_04:DJNZ R6,WR_24XX_DATA_04
DJNZ R7,WR_24XX_DATA_04
WR_24XX_DATA_END:
SETB WP ;寫數據使能禁止
RET
;
;=============================================================================
;從被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)中讀取多個字節數據程序
;入口:DPTR為預讀取的數據的首地址,R2為需要讀取數據的字節數
; I2C_24XX_TYPE_LABL為當前24系列串行EEPROM的器件類型,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
;出口:R0為讀取的數據存儲緩存區
;說明:24XX01的頁操作緩沖區是8字節,24XX02/04/08/16的頁操作緩沖區是16字節
; 24XX32/64的頁操作緩沖區是32字節
; 一次此操作過程只能對本頁內地址進行數據的讀取且字節數不能超過該器件頁緩沖區的字節數。
;=============================================================================
RD_24XX_DATA: CALL START_I2C ;發送I2C 總線起始條件
JB I2C_24XX_TYPE_LABL,RD_24XX_DATA_01;判斷當前24系列串行EEPROM的器件類型,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
MOV A,DPH ;待寫入數據的高位地址
ANL A,#0FH ;屏蔽高位地址中的無效數據
CLR C ;確定寫操作命令標志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址,帶寫入數據的高位地址及寫命令
CALL SENT_BYTE ;發送被控器總線地址及數據高位地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
SJMP RD_24XX_DATA_02
RD_24XX_DATA_01:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址
CLR C ;確定寫操作命令標志
MOV ACC.0,C ;確定被控器總線地址及寫命令
CALL SENT_BYTE ;發送被控器總線地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
MOV A,DPH ;待寫入數據的高位地址
CALL SENT_BYTE ;發送待寫入數據的高位地址
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
RD_24XX_DATA_02:MOV A,DPL ;待寫入的數據首字節地址低位字節
CALL SENT_BYTE ;發送地址低位字節
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
CALL START_I2C ;重復發送I2C 總線起始條件
JB I2C_24XX_TYPE_LABL,RD_24XX_DATA_03;判斷當前24系列串行EEPROM的器件類型,“0”表示為24XX01/02/04/08/16,“1”表示為24XX32/64
MOV A,DPH ;待讀取數據的高位地址
ANL A,#0FH ;屏蔽高位地址中的無效數據
SETB C ;確定讀操作命令標志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址,帶寫入數據的高位地址及寫命令
SJMP RD_24XX_DATA_04
RD_24XX_DATA_03:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器總線地址
SETB C ;確定讀操作命令標志
MOV ACC.0,C ;確定被控器總線地址及寫命令
RD_24XX_DATA_04:CALL SENT_BYTE ;發送被控器總線地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
CLR RCV_RUN_LABL ;預設置允許后續繼續接收數據
RD_24XX_DATA_05:DJNZ R2,RD_24XX_DATA_06
SETB RCV_RUN_LABL ;設置禁止后續繼續接收數據
CALL RCV_BYTE ;接收數據
MOV @R0,A
INC R0
CALL STOP_I2C ;發送I2C 總線停止條件
SJMP RD_24XX_DATA_END
RD_24XX_DATA_06:CALL RCV_BYTE ;接收數據
MOV @R0,A
INC R0
SJMP RD_24XX_DATA_05
RD_24XX_DATA_END:
RET
;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -