24C02 EEPROM 51汇编程序设计

最近在学习汇编完成常用芯片的控制,并预留一些接口。24C02是我购买的开发板上的芯片,故先从他入手。(更新中)

24C02数据手册理解

推荐的数据手册

24C02的开发商很多,数据手册的设计参差不齐,而我实在是不知道开发板上这个是哪个公司生产的,故浏览了一些厂商的数据手册,总的来说性能差异不太大。
故选择一个我认为将时序说的比较清楚的数据手册推荐给大家。
24C02数据手册-CSDN免积分下载

传输状态

  1. 开始传输状态
    SCL高,SDA下降沿。(时序4)
    开始传输波形
  2. 停止传输状态
    SCL高,SDA上升沿。(时序4)
    停止传输波形
  3. 数据传输状态
    SCL高,SDA保持。(时序3)
    位传输
  4. 主机等待响应
    先将SDA拉高,再置SCL高,等待SDA被从机拉低。(时序6)
    响应时序
    我观察到很多例程都对这个过程进行了包容处理,我认为应该认真对待,具体的会从程序中体现。
    总结:
    ①所有时间均为ns级,即51单片机无需延时。
    ②SCL可以理解为高电平敏感。
    SCL高电平、SDA保持至SCL置低,则为传输数据;
    SCL高电平、SDA变化则为控制信号,开始或停止。
    ③控制不能是连续的,所以设计了从机的响应机制,保证控制流的正确执行。
    主要是因为若向ROM写入数据,在传输完成后,ROM会进入写周期,此时无法响应总线控制,可从没有响应拉低电平的信号中得到是否处于该状态。

字节定义

  1. 器件地址+读写控制
D7D6D5D4D3D2D1D0
1010A2A1A0R/ W ‾ \overline W W

(1) 对于不同型号对D3-D1的定义不同,24C02是芯片地址,用于拓展。ROM接收该字节后,会与自己引脚数据比较,以确认自己是否为从机。
(2) D0是控制位,1表示读,0表示写。这个字节决定了往后的数据流控制的逻辑。

  1. 数据地址
    数据地址根据型号的不同表现也不相同。
    具体来说对于24C02其一页有8字节,故数据地址中低三位表示字节地址,前五位表示页地址。其他型号以此类推。
D7D6D5D4D3D2D1D0
AY4AY3AY2AY1AY0AZ2AZ1AZ0
  1. 数据
    常规的8位数据。
    总结:
    ①串行总线传输的数据总是先发送高位MSB再发送地位LSB。
    ②字节流以1字节对象+1位响应组成的9位帧组成。而对象无非是上述三者。为便于描述记ROM的地址设置为0x000,流依次称为控制读(0xA1)、控制写(0xA0)、地址流数据流
D8-D1D0
字节对象D7-D0响应ACK

芯片支持数据流

  1. 单地址写字节
    开始+控制写+地址流+数据流+停止
  2. 本页连续写字节
    开始+控制写+地址流+数据流×n+停止
    这种方法虽然对连续写入没有限制,但仅在输入地址的那一页循环。故写入过多会覆盖先前数据。
  3. 当前地址读字节
    开始+控制读+数据流+停止
    这个实际上是对ROM片内地址计数器的应用,计数器会记录上次访问的地址+1后的地址。也就是说通过该方法,可以分为独立过程读入连续的数据。当然仅限当前页循环读取。
  4. 单地址读字节
    开始+控制写+地址流+开始+控制读+数据流+停止
  5. 指定地址连续读字节
    该数据流是唯一一个需要主机应答ACK的流。需要主机应答的流用&标记。两种读作为起始都可以。
    (1)开始+控制读+数据流&+数据流&×n+数据流+停止
    (2)开始+控制写+地址流+开始+控制读+数据流&+数据流&×n+数据流+停止
  6. 询问状态
    这是我看到的例程都省略的一个很重要的流。还是会在程序中体现。
    开始+(控制写+等待应答)×n直到接收到应答+下一操作。
    注:这里的下一操作我尚未实验,我目前选择给一个停止后重新发送地址流。这是合理的,因为只要本次询问得到了ACK意味着此时ROM已结束写周期,故后面的ACK必定会响应,故给出一个等待响应的状态就行,连判断有没有拉低都不需要。

软件抽象数据流

  1. 写入字节流
    即无论是器件地址还是数据地址还是数据,其抽象模型就是字节流
  2. 读取数据流
    读取数据是ROM唯一的读取操作。
  3. 等待ROM空闲
    即询问状态的流,以决定是否进行下面的操作。

程序源码及接口

  1. 起始条件
	/*
	FUNC_NAME:EEPROM_IIC_START
	INPUT:NONE
	OUTPUT:NONE
	*/
	EEPROM_IIC_START:
	SETB SDA
	SETB SCL
	CLR SDA
	CLR SCL
	RET
  1. 停止条件
	/*
	FUNC_NAME:EEPROM_IIC_STOP
	INPUT:NONE
	OUTPUT:NONE
	*/
	EEPROM_IIC_STOP:
	CLR SDA
	SETB SCL
	SETB SDA
	RET
  1. 询问状态
	/*
	FUNC_NAME:EEPROM_IIC_ASK
	INPUT:R0<DEVICE_ADDR>
	OUTPUT:NONE
	*/
	EEPROM_IIC_ASK:
	LCALL EEPROM_IIC_START
	MOV A,R0
	PUSH FOR_I
	MOV FOR_I,#8
	LOOP_EEPROM_IIC_ASK_I:
	RLC A
	MOV SDA,C
	SETB SCL
	CLR SCL
	DJNZ FOR_I,LOOP_EEPROM_IIC_ASK_I
	SETB SDA
	SETB SCL
	POP FOR_I
	MOV C,SDA
	JC EEPROM_IIC_ASK
	CLR SCL
	LCALL EEPROM_IIC_STOP
	RET
  1. 发送字节
	/*
	FUNC_NAME:EEPROM_IIC_SEND_DATA
	INPUT:R0<DATA>
	OUTPUT:NONE
	*/
	EEPROM_IIC_SEND_DATA:
	MOV A,R0
	PUSH FOR_I
	MOV FOR_I,#8
	LOOP_EEPROM_IIC_SEND_DATA_I:
	RLC A
	MOV SDA,C
	SETB SCL
	CLR SCL
	DJNZ FOR_I,LOOP_EEPROM_IIC_SEND_DATA_I
	POP FOR_I
	SETB SCL
	MOV C,SDA
	CLR SCL
	RET
  1. 读取字节
	/*
	FUNC_NAME:EEPROM_IIC_READ_DATA
	INPUT:NONE
	OUTPUT:ACC
	*/
	EEPROM_IIC_READ_DATA:
	SETB SDA
	CLR A
	PUSH FOR_I
	MOV FOR_I,#8
	LOOP_EEPROM_IIC_READ_DATA_I:
	SETB SCL
	MOV C,SDA
	RLC A
	CLR SCL
	DJNZ FOR_I,LOOP_EEPROM_IIC_READ_DATA_I
	POP FOR_I
	RET

只需要将具体的数据送入寄存器,然后组合调用这些抽象函数,便可以实现具体的操作了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值