?? vi2c_asm.inc
字號:
;--------------------------------------------------------------------------------------------------------
; MCS-51單片機模擬I2C軟件包(V1.1)
; 文件名:VI2C_ASM.INC
; 功能說明:本模擬I2C軟件包包含了I2C操作的底層子程序,使用前要定義
;好SCL和SDA。在標準8051模式(12 Clock)下,對主頻要求是不高于12MHz(即1個
;機器周期1us);若Fosc>12MHz則要增加相應的NOP指令數。(總線時序符合I2C標
;準模式,100Kbit/S)
; 版本說明:本版新增了兩個子程序,IWRNBYTEEXT,IRDNBYTEEXT兩個子程序,
;這兩個子程序用于主從通訊上及一此特殊器件的讀寫操作較為方便.
; 更新時間:2002.06.04
;--------------------------------------------------------------------------------------------------------
;啟動I2C總線子程序
START: SETB SDA
NOP
SETB SCL ;起始條件建立時間大于4.7us
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP ;起始條件鎖定時大于4us
NOP
NOP
NOP
NOP
CLR SCL ;鉗住總線,準備發數據
NOP
RET
;結束總線子程序
STOP: CLR SDA
NOP
SETB SCL ;發送結束條件的時鐘信號
NOP ;結束總線時間大于4us
NOP
NOP
NOP
NOP
SETB SDA ;結束總線
NOP ;保證一個終止信號和起始信號的空閑時間大于4.7us
NOP
NOP
NOP
RET
;發送應答信號子程序
MACK: CLR SDA ;將SDA置0
NOP
NOP
SETB SCL
NOP ;保持數據時間,即SCL為高時間大于4.7us
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;發送非應答信號
MNACK: SETB SDA ;將SDA置1
NOP
NOP
SETB SCL
NOP
NOP ;保持數據時間,即SCL為高時間大于4.7us
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;檢查應答位子程序
;返回值,ACK=1時表示有應答
CACK: SETB SDA
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判斷應答位
CEND: NOP
CLR SCL
NOP
RET
;發送字節子程序
;字節數據放入ACC
;每發送一字節要調用一次CACK子程序,取應答位
WRBYTE: MOV R0,#08H
WLP: RLC A ;取數據位
JC WR1
SJMP WR0 ;判斷數據位
WLP1: DJNZ R0,WLP
NOP
RET
WR1: SETB SDA ;發送1
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR0: CLR SDA ;發送0
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
;讀取字節子程序
;讀出的值在ACC
;每取一字節要發送一個應答/非應答信號
RDBYTE: MOV R0,#08H
RLP: SETB SDA
NOP
SETB SCL ;時鐘線為高,接收數據位
NOP
NOP
MOV C,SDA ;讀取數據位
MOV A,R2
CLR SCL ;將SCL拉低,時間大于4.7us
RLC A ;進行數據位的處理
MOV R2,A
NOP
NOP
NOP
DJNZ R0,RLP ;未夠8位,再來一次
RET
;========================================================================================
;========================================================================================
; 以下是用戶接口子程序
;
;無子地址器件寫字節數據
;入口參數: 數據為ACC、器件從地址SLA
;占用: A、R0、CY
IWRBYTE: PUSH ACC
IWBLOOP: LCALL START ;起動總線
MOV A,SLA
LCALL WRBYTE ;發送器件從地址
LCALL CACK
JNB ACK,RETWRB ;無應答則跳轉
POP ACC ;寫數據
LCALL WRBYTE
LCALL CACK
LCALL STOP
RET
RETWRB: POP ACC
LCALL STOP
RET
;無子地址器件讀字節數據
;入口參數: 器件從地址SLA
;出口參數: 數據為ACC
;占用: A 、R0、R2 、CY
IRDBYTE: LCALL START
MOV A,SLA ;發送器件從地址
INC A
LCALL WRBYTE
LCALL CACK
JNB ACK,RETRDB
LCALL RDBYTE ;進行讀字節操作
LCALL MNACK ;發送非應信號
RETRDB: LCALL STOP ;結束總線
RET
;向器件指定子地址寫N字節數據
;入口參數: 器件從地址SLA、器件子地址SUBA 、發送數據緩沖區MTD、發送字節數NUMBYTE
; 占用: A 、R0 、R1 、R3 、CY
IWRNBYTE: MOV A,NUMBYTE
MOV R3,A
LCALL START ;起動總線
MOV A,SLA
LCALL WRBYTE ;發送器件從地址
LCALL CACK
JNB ACK,RETWRN ;無應答則退出
MOV A,SUBA ;指定子地址
LCALL WRBYTE
LCALL CACK
MOV R1,#MTD
WRDA: MOV A,@R1
LCALL WRBYTE ;開始寫入數據
LCALL CACK
JNB ACK,IWRNBYTE
INC R1
DJNZ R3,WRDA ;判斷寫完沒有
RETWRN: LCALL STOP
RET
;向器件指定子地址讀取N字節數據
;入口參數: 器件從地址SLA、器件子地址SUBA、接收字節數NUMBYTE
;出口參數: 接收數據緩沖區MTD
;占用:A、 R0、 R1、 R2、 R3、 CY
IRDNBYTE: MOV R3,NUMBYTE
LCALL START
MOV A,SLA
LCALL WRBYTE ;發送器件從地址
LCALL CACK
JNB ACK,RETRDN
MOV A,SUBA ;指定子地址
LCALL WRBYTE
LCALL CACK
LCALL START ;重新起動總線
MOV A,SLA
INC A ;準備進行讀操作
LCALL WRBYTE
LCALL CACK
JNB ACK,IRDNBYTE
MOV R1,#MRD
RDN1: LCALL RDBYTE ;讀操作開始
MOV @R1,A
DJNZ R3,SACK
LCALL MNACK ;最后一字節發非應答位
RETRDN: LCALL STOP ;并結束總線
RET
SACK: LCALL MACK
INC R1
SJMP RDN1
;無子地址器件寫N字節數據
;入口參數: 器件從地址SLA、發送數據緩沖區MTD、發送字節數NUMBYTE
; 占用: A 、R0 、R1 、R3 、CY
;不發送子地址SUBA,直接發送多個數據.
IWRNBYTEEXT:
MOV A,NUMBYTE
MOV R3,A
LCALL START ;起動總線
MOV A,SLA
LCALL WRBYTE ;發送器件從地址
LCALL CACK
JNB ACK,RETWRNE ;無應答則退出
MOV R1,#MTD
WRDAE: MOV A,@R1
LCALL WRBYTE ;開始寫入數據
LCALL CACK
JNB ACK,RETWRNE
INC R1
DJNZ R3,WRDAE ;判斷寫完沒有
RETWRNE: LCALL STOP
RET
;無子地址器件讀取N字節數據
;入口參數: 器件從地址SLA、器件子地址SUBA、接收字節數NUMBYTE
;出口參數: 接收數據緩沖區MTD
;占用:A、 R0、 R1、 R2、 R3、 CY
;說明:此函數不發送子址,也不重新啟動總線,而是直接讀取多個數據.
IRDNBYTEEXT:
MOV R3,NUMBYTE
LCALL START
MOV A,SLA
INC A
LCALL WRBYTE ;發送器件從地址
LCALL CACK
JNB ACK,RETRDNE
MOV R1,#MRD
RDNE1: LCALL RDBYTE ;讀操作開始
MOV @R1,A
DJNZ R3,SACKE
LCALL MNACK ;最后一字節發非應答位
RETRDNE: LCALL STOP ;并結束總線
RET
SACKE: LCALL MACK
INC R1
SJMP RDNE1
;*********************************************************************************************
; 請注意
;
; 占用內部資源: R0,R1,R2,R3,ACC,Cy。
; 在你的程序里要做以下定義:
; 1、定義變量: SLA 器件從地址 SUBA器件子地址 NUMBYTE讀/寫的字節數 ,位變量ACK
; 2、定義常量: SDA SCL 總線位 MTD 發送數據緩沖區首址 MRD 接收數據緩沖區首址
;
; (ACK為調試/測試位,ACK為0時表示無器件應答或總線出錯)
;
; 在使用本軟件包時,請在你的程序的未尾加入$INCLUDE (VI2C_ASM.INC)即可。VI2C_ASM.INC文件
;復制到IDE包含文件所要求的目錄(如:工作目錄或INC目錄)
;
; 用戶可以對"用戶接口子程序"進行裁減,即把自已不使用的接口子程序刪掉,以節省程序空間。
;**********************************************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -