|
;24c08操作時序?yàn)椋浩鹗夹盘杝clk拉高情況下sda由高變低,表示起始
; 結(jié)束信號sclk拉高情況下sda由低變高,表示結(jié)束
; 字節(jié)由高位向低位依次發(fā)送
; 第一個字節(jié)是地址和讀寫控制,第二個是存儲地址,第三個是數(shù)據(jù),每個數(shù)據(jù)結(jié)束器件都會發(fā)送 ack應(yīng)答信號;
; I2C 總線協(xié)議
;I2C 總線協(xié)議定義如下
;1 只有在總線空閑時才允許啟動數(shù)據(jù)傳送
;2 在數(shù)據(jù)傳送過程中當(dāng)時鐘線為高電平時數(shù)據(jù)線必須保持穩(wěn)定狀態(tài)不允許有跳變時鐘線
;為高電平時數(shù)據(jù)線的任何電平變化將被看作總線的起始或停止信號
;起始信號
;時鐘線保持高電平期間數(shù)據(jù)線電平從高到低的跳變作為I2C 總線的起始信號
;停止信號
;時鐘線保持高電平期間數(shù)據(jù)線電平從低到高的跳變作為I2C 總線的停止信號
;
ORG 0000H
SCL EQU P2.6
SDA EQU P2.7
AJMP MAIN
ORG 00030H
MAIN:LCALL INIT ;主函數(shù),
LCALL WRITE2408
LCALL DELAY1
LCALL READ2408
MOV P0,A
AJMP $
INIT: SETB SCL ;初始化
LCALL DELAY
SETB SDA
LCALL DELAY
RET
START:SETB SDA ;起始信號
LCALL DELAY
SETB SCL
LCALL DELAY
CLR SDA
LCALL DELAY
RET
STOP:CLR SDA ; 停止信號
LCALL DELAY
SETB SCL
LCALL DELAY
SETB SDA
RET
ACK:SETB SCL ;應(yīng)答信號
LCALL DELAY
JB SDA,$
CLR SCL
LCALL DELAY
SETB SDA
LCALL DELAY
RET
WRITE: MOV R4,#08H ;寫
LOOP: CLR SCL
LCALL DELAY
RLC A
MOV SDA,C
LCALL DELAY
SETB SCL
LCALL DELAY
DJNZ R4,LOOP
CLR SCL ;哎呀吃大虧了,我說怎么就是寫一個A0算完了而且還有一個停止信號,娘了個逼我程序里不是這樣的啊,奧今天我才看透,原來A0的最低位是0
LCALL DELAY ;這里以前是先把SDA釋放,再拉低SCL ,相當(dāng)于一個停止信號啊,所以U820受到后把總線禁止了,也難怪寫不出了,哈哈哈又學(xué)一招
SETB SDA ;原來這么細(xì)微的變動都會是你的程序白搭,即使你其他的都是對的;
LCALL DELAY ;加油;2010年7月22日午與天津宿舍
RET ;EEPROM的成功讀取時很有意義的,嘿嘿
READ:MOV R4,#08H ;讀
SETB SDA
LCALL DELAY
LOP: CLR SCL
LCALL DELAY
SETB SCL
LCALL DELAY
MOV C,SDA
RLC A
DJNZ R4,LOP
CLR SCL
RET
DELAY: ;數(shù)據(jù)穩(wěn)定
NOP
NOP
NOP
NOP
NOP
RET
WRITE2408:LCALL START
MOV A,#0A0H
LCALL WRITE
LCALL ACK ;向U820的00H單元寫0x88;
MOV A,#00H
LCALL WRITE
LCALL ACK
MOV A,#88H
LCALL WRITE
LCALL ACK
LCALL STOP
RET
READ2408:LCALL START
MOV A,#0A0H
LCALL WRITE
LCALL ACK
MOV A,#00H ;從U820的00H單元讀出數(shù)據(jù)
LCALL WRITE
LCALL ACK
LCALL START
MOV A,#0A1H
LCALL WRITE
LCALL ACK
LCALL READ
LCALL STOP
RET
DELAY1: ;延時1S,在應(yīng)用中這個可以是主程序啊哈哈,真他媽了噶比的爽老子也做出來了;爽啊
MOV R7,#0A7H
DL1:
MOV R6,#0ABH
DL0:
MOV R5,#10H
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
NOP
RET
END
|
|