|
;24c08操作时序为:起始信号sclk拉高情况下sda由高变低,表示起始
; 结束信号sclk拉高情况下sda由低变高,表示结束
; 字节由高位向低位依次发送
; 第一个字节是地址和读写控制,第二个是存储地址,第三个是数据,每个数据结束器件都会发送 ack应答信号;
; I2C 总线协议
;I2C 总线协议定义如下
;1 只有在总线空闲时才允许启动数据传送
;2 在数据传送过程中当时钟线为高电平时数据线必须保持稳定状态不允许有跳变时钟线
;为高电平时数据线的任何电平变化将被看作总线的起始或停止信号
;起始信号
;时钟线保持高电平期间数据线电平从高到低的跳变作为I2C 总线的起始信号
;停止信号
;时钟线保持高电平期间数据线电平从低到高的跳变作为I2C 总线的停止信号
;
ORG 0000H
SCL EQU P2.6
SDA EQU P2.7
AJMP MAIN
ORG 00030H
MAIN:LCALL INIT ;主函数,
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 ;应答信号
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 ,相当于一个停止信号啊,所以U820受到后把总线禁止了,也难怪写不出了,哈哈哈又学一招
SETB SDA ;原来这么细微的变动都会是你的程序白搭,即使你其他的都是对的;
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: ;数据稳定
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单元读出数据
LCALL WRITE
LCALL ACK
LCALL START
MOV A,#0A1H
LCALL WRITE
LCALL ACK
LCALL READ
LCALL STOP
RET
DELAY1: ;延时1S,在应用中这个可以是主程序啊哈哈,真他妈了噶比的爽老子也做出来了;爽啊
MOV R7,#0A7H
DL1:
MOV R6,#0ABH
DL0:
MOV R5,#10H
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
NOP
RET
END
|
|