?? i2c.inc
字號:
;******************************************************************************
; I2C.INC
; 標準80C51模擬I2C總線程序(主模式)
; Copyright (c) 2006,廣州周立功單片機發展有限公司
; All rights reserved.
; 本程序僅供學習參考,不提供任何可靠性方面的擔保;請勿用于商業目的
;******************************************************************************
;******************************************************************************
;模擬I2C總線基本用法:
; 用$INCLUDE(I2C.INC)命令包含本文件,或者直接復制并插入本文件全部內容
; 在主程序開始處,應當調用一次I2C_Init()
; 發送和接收數據請直接使用I2C_Puts()和I2C_Gets()
; I2C總線管腳以及延時等參數請根據實際情況修改
;******************************************************************************
;******************************************************************************
;模擬I2C總線的管腳定義
;******************************************************************************
I2C_SCL BIT P1.6 ;定義I2C總線時鐘信號
I2C_SDA BIT P1.7 ;定義I2C總線數據信號
;******************************************************************************
;函數:void I2C_Delay()
;功能:模擬I2C總線延時
;說明:請根據具體情況調整延時值
;******************************************************************************
I2C_Delay:
PUSH 0x02
MOV R2, #10
DJNZ R2, $
POP 0x02
RET
;******************************************************************************
;函數:void I2C_Init()
;功能:I2C總線初始化,使總線處于空閑狀態
;說明:在主程序的開始處,應當執行一次本函數
;******************************************************************************
I2C_Init:
SETB I2C_SCL
CALL I2C_Delay
SETB I2C_SDA
CALL I2C_Delay
RET
;******************************************************************************
;函數:void I2C_Start()
;功能:產生I2C總線的起始條件
;說明:
; SCL處于高電平期間,當SDA出現下降沿時啟動I2C總線
; 本函數也用來產生重復起始條件
;******************************************************************************
I2C_Start:
SETB I2C_SDA
CALL I2C_Delay
SETB I2C_SCL
CALL I2C_Delay
CLR I2C_SDA
CALL I2C_Delay
CLR I2C_SCL
CALL I2C_Delay
RET
;******************************************************************************
;函數:void I2C_Write(byte dat)
;功能:向I2C總線寫1個字節的數據
;參數:dat(R7)是要寫到總線上的數據
;******************************************************************************
I2C_Write:
PUSH 0x02
MOV R2, #8
MOV A, R7
I2C_Write_Loop:
MOV C, ACC.7
MOV I2C_SDA, C
ADD A, ACC
SETB I2C_SCL
CALL I2C_Delay
CLR I2C_SCL
CALL I2C_Delay
DJNZ R2, I2C_Write_Loop
POP 0x02
RET
;******************************************************************************
;函數:byte I2C_Read()
;功能:從從機讀取1個字節的數據
;返回:ACC = 讀取的1個字節數據
;******************************************************************************
I2C_Read:
PUSH 0x02
MOV R2, #8
SETB I2C_SDA ;在讀取數據之前,要把SDA拉高,使之處于輸入狀態
I2C_Read_Loop:
SETB I2C_SCL
CALL I2C_Delay
ADD A, ACC
JNB I2C_SDA, I2C_Read_Next
INC A
I2C_Read_Next:
CLR I2C_SCL
CALL I2C_Delay
DJNZ R2, I2C_Read_Loop
POP 0x02
RET
;******************************************************************************
;函數:bit I2C_GetAck()
;功能:讀取從機應答位(應答或非應答),用于判斷:從機是否成功接收主機數據
;返回:
; CY = 0:從機應答
; CY = 1:從機非應答
;說明:從機在收到每一個字節后都要產生應答位,主機如果收到非應答則應當終止傳輸
;******************************************************************************
I2C_GetAck:
SETB I2C_SDA
CALL I2C_Delay
SETB I2C_SCL
CALL I2C_Delay
MOV C, I2C_SDA
CLR I2C_SCL
CALL I2C_Delay
RET
;******************************************************************************
;函數:void I2C_PutAck(bit ack)
;功能:主機產生應答位(應答或非應答),用于通知從機:主機是否成功接收從機數據
;參數:
; ack(CY) = 0:主機應答
; ack(CY) = 1:主機非應答
;說明:主機在收到每一個字節后都要產生應答,在收到最后一個字節后,應當產生非應答
;******************************************************************************
I2C_PutAck:
MOV I2C_SDA, C
CALL I2C_Delay
SETB I2C_SCL
CALL I2C_Delay
CLR I2C_SCL
CALL I2C_Delay
RET
;******************************************************************************
;函數:void I2C_Stop()
;功能:產生I2C總線的停止條件
;說明:SCL處于高電平期間,當SDA出現上升沿時停止I2C總線
;******************************************************************************
I2C_Stop:
CLR I2C_SDA
CALL I2C_Delay
SETB I2C_SCL
CALL I2C_Delay
SETB I2C_SDA
CALL I2C_Delay
;延時程序段(對于某些器件來說在下一次產生Start之前額外增加一定的延時是必須的)
PUSH 0x00
MOV R0, #15
I2C_Stop_Loop:
NOP
NOP
DJNZ R0, I2C_Stop_Loop
POP 0x00
;返回
RET
;******************************************************************************
;函數:I2C_Puts(byte SlaveAddr, byte SubAddr, byte size, byte *dat)
;功能:主機通過I2C總線向從機發送多個字節的數據
;參數:
; SlaveAddr(R7):從機地址(高7位是從機地址,最低位是讀寫標志)
; SubAddr(R6):從機的子地址
; size(R5):數據大?。ㄒ宰止澯嫞?; *dat(R4):要發送的數據
;返回:
; CY = 0:發送成功
; CY = 1:在發送過程中出現異常
;******************************************************************************
I2C_Puts:
;確保從機地址最低位是0
ANL 0x07, #0xFE
;啟動I2C總線
CALL I2C_Start
;發送從機地址并判斷應答位
CALL I2C_Write
CALL I2C_GetAck
JNC I2C_Puts_LB1
CALL I2C_Stop
SETB C
RET
I2C_Puts_LB1:
;發送子地址并判斷應答位
MOV A, R6
MOV R7, A
CALL I2C_Write
CALL I2C_GetAck
JNC I2C_Puts_LB2
CALL I2C_Stop
SETB C
RET
I2C_Puts_LB2:
;發送數據(每發送一個字節都要判斷一次應答位)
PUSH 0x00
MOV A, R4
MOV R0, A
I2C_Puts_Loop:
MOV A, @R0
INC R0
MOV R7, A
CALL I2C_Write
CALL I2C_GetAck
JNC I2C_Puts_LB3
CALL I2C_Stop
SETB C
POP 0x00
RET
I2C_Puts_LB3:
DJNZ R5, I2C_Puts_Loop
POP 0x00
;發送完畢,停止I2C總線,返回
CALL I2C_Stop
CLR C
RET
;******************************************************************************
;函數:I2C_Gets(byte SlaveAddr, byte SubAddr, byte size, byte *dat)
;功能:主機通過I2C總線從從機接收多個字節的數據
;參數:
; SlaveAddr(R7):從機地址(高7位是從機地址,最低位是讀寫標志)
; SubAddr(R6):從機的子地址
; size(R5):數據大?。ㄒ宰止澯嫞?; *dat(R4):保存接收到的數據
;返回:
; CY = 0:接收成功
; CY = 1:在接收過程中出現異常
;******************************************************************************
I2C_Gets:
;確保從機地址最低位是0
ANL 0x07, #0xFE
;啟動I2C總線
CALL I2C_Start
;發送從機地址并判斷應答位
CALL I2C_Write
CALL I2C_GetAck
JNC I2C_Gets_LB1
CALL I2C_Stop
SETB C
RET
I2C_Gets_LB1:
;發送子地址并判斷應答位
PUSH 0x07
MOV A, R6
MOV R7, A
CALL I2C_Write
POP 0x07
CALL I2C_GetAck
JNC I2C_Gets_LB2
CALL I2C_Stop
SETB C
RET
I2C_Gets_LB2:
;發送重復起始條件
CALL I2C_Start
;發送從機地址并判斷應答位
INC R7 ;從機地址(R7)的讀寫位置1,即準備讀數據
CALL I2C_Write
CALL I2C_GetAck
JNC I2C_Gets_LB3
CALL I2C_Stop
SETB C
RET
I2C_Gets_LB3:
;接收數據
PUSH 0x00
MOV A, R4
MOV R0, A
I2C_Gets_Loop:
CALL I2C_Read
MOV @R0, A
INC R0
DJNZ R5, I2C_Gets_LB4
SETB C
CALL I2C_PutAck
SJMP I2C_Gets_EndLoop
I2C_Gets_LB4:
CLR C
CALL I2C_PutAck
SJMP I2C_Gets_Loop
I2C_Gets_EndLoop:
;接收完畢,停止I2C總線,返回
CALL I2C_Stop
CLR C
POP 0x00
RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -