Chinaunix首页 | 论坛 | 博客
  • 博客访问: 815142
  • 博文数量: 321
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 936
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-23 11:25
文章分类

全部博文(321)

文章存档

2017年(1)

2016年(10)

2015年(61)

2014年(187)

2013年(62)

分类: 嵌入式

2014-05-14 23:17:43

三、IIC----EEPROM(每次在读写之前都要初始化!!!!!!!!!!!!!!!!!!!!!!!非常重要,否则会出现连续读第二次就读不出来)电可擦除的可编程存储芯片。

在项目中是用数组,不用指针,因为当前读的时候,指针是指向我们之前写的位置,而我们并不知道之前写的地址写到哪,所以不知道指针在哪。故用数组指定地址。

E2PROM地址:1010  p2p1p0 r/w(r=1,w=0)我们是2408  8k是位,1k字节,p2p1p0代表页码或者的E2PROM的地址,如果多个E2PROM,则区别到底哪一个E2PROM2401代码最多能挂8E2PROM,即P2P1P0全部用来做地址线,而我们现在8K的只有P2代码地址线P1P0代码页码,所以最多能挂两个(0 1)若是16K的只能挂一个P2P1P0不接。此时的P1P0代表大页的地址。所以我们写为1010 0 00 0   1010 0 01 0    1010 0 10 0    

1010 0 11 0p1p0为大页的标签,有四大页,每个大页有16个小页,每个小页16个字节

最后一位是读写方向位,1读,0写。

 

补充:

1、是一种通讯协议,类似串口。数据的传输都会有一个同步时钟。

2、上升沿是用来写,下降沿用来读。

3、总共有10位表示地址,前两位2位表示页码,大页,后8位表示页内地址。

4、E2PROM都是以八位的为一帧来传输,后面接着低电平的ACK信号,在第九个时钟周期。

5、若是写的话,其实我们写的东西先放在缓存中,当收到停止条件的时候,则进入写周期,从BUFFER里面写入E2PROM。所以若我们写的时候,收到停止条件就马上结束的话,有可能写不进去。但是我们的写周期时间的多大呢。。??我们采用不停的呼叫(发送启动条件和设备地址),若有应答ACK的话,则说明写完,若没写完,则不会应答。

6、时钟线为低的话,数据线可以切换,代表数据的传输,若SCL为高,切换数据则是起始或停止条件。

7、写:

 

解释:字节写:

1设备地址接着启动信号。设备地址:1010   A2没用(因为此时就只有一块E2PROM,当两块E2PROM时,0 - 1来区别哪一块),A1A0为页码,最后一位是读或写。0,为写。应答信号:ACK,对应数据线为低电平

2、内存地址:八位。再接应答信号:ACK

3、传输数据:八位数据,再产生ACK

4、最后停止信号。数据线为高电平

5、再进入写周期。写周期期间,所有输入都是无效的,E2PROM不会反应

6、

解释:页写:

1、设备地址接着启动信号。设备地址:1010   A2没用(因为此时就只有一块E2PROM,当两块E2PROM时,0 - 1来区别哪一块),A1A0为页码,最后一位是读或写。0,为写。应答信号:ACK,对应数据线为低电平

2、内存地址,ACK

3、发送数据,ACK。。。。发送数据。。。ACK

4、注:虽然与上字节写看似差不多,其实不是:区别:每发完一帧数据,即产生ACK信号后,要先进入写周期,即发个停止信号进入写周期,写完后再继续发生数据,不停的查询ACK,如何才能产生ACK,方法:通过发送一个启动信号和设备地址。

5记住,发送最后一个数据与读不一样,他是有产生ACK信号的

6、页写,若写了大于16个字节(因为一小页为16个字节,16*16=256,一个大页等于16个小页),则出现卷耀,即覆盖0地址的地方。即写不能跨页(小页)。只能在内部的小页卷耀。

 

8读:

 

字节读:与写操作一样,就一位读写方向位不同。

最大区别在这:在cpu收到数据后,是发送NOACK,即把SDA拉为高电平。

读,一般都是指定地址读,不用当前地址读。读可以跨页,整个大页。

 

随即读:

1、先产生启动信号,设备地址,写伪写,产生ACK

2、内存地址,ACK

3、再启动,发送设备地址,读的。

4、发送数据,产生ACK,当收到ACK信号时,就知道还要接着读,紧接着就再发送数据,直到当最后一个要读出来的时候,不用发送ACK信号,其实那就是NOACK信号,硬件决定。就是直接收到一个高电平,紧接着就有个停止信号

5、连续读:即当前地址读+随即读。。

 

 

9、谁发出同步信号,谁就是主设备。

10、数据都是MSB发送的。。就是高位先发送。没发八位,都要有个应答信号,有接收方发送。

11、CPU呼叫从设备,就把数据(地址)发在SDA线上,所有挂在线上的设备都要跟自己的地址比较。如果收到的地址就是自己的地址,则要回答ACK信号。

12、这边的移位寄存器是双缓冲,先放在IICDS上,在一位位移位到shift register上,再一位位移到SDA线上。

13、四种模式:主传输,主接收,从传输,从接收。

14、SCL时钟线保持低电平,则挂起,**。

15、当发送器收到ACK时钟脉冲时应该通过拉高SDA线来释放SDA线。

16、在SCL为低电平的时候才切换电平。发送:S3C2440A 应该等待中断来确定当前数据发送的完成。在CPU收到中断请求后,需要再次写一个新数据到 IICDS 寄存器中。 接收:S3C2440A 应该等待中断来确定当前数据接收的完成。在CPU收到中断请求后,需要从 IICDS 寄存器中读取数据。

17、IIC 总线中断发生在1)当完成了 字节发送或接收操作;2)当广播呼叫或从地址匹配发生时;)如果总线仲裁失败。 为了在 SCL 上升沿之前调整 SDA的建立时间,必须在清除 IIC 中断挂起位前写 IICDS 

18、EEPROM接口,  Rx 模式中为了产生停止条件在读取最后数据之前会禁止产生应答。 

19、每次产生ACK后,要进入写,所以一般查询中断挂起位,而不查询ACK,因为ACK不能保证已经写完了,而采用查询中断,则保证已经已经写完,如果两个都查询的话,就万无一失了。

 

 

 

 

1.串行数据线(SDA)和专用串行时钟线(SCL

2.释放时,空闲,SDASCL为高电平,即待机。SCL为低的时候,SDA改变数据,当SCL为高的时候,若是改变SDA则是启动或停止。(启动:高-->低,停止:低--->)

3.起始条件和结束条件都为主设备产生,这边cpu是主设备,E2PROM为从设备,因为E2PROM不会产生时钟。

4.由IICSDAIICSCL,可以确定GPE==(((U32)2<<30)|(2<<28));口,U32是为了消除警告

5.在读出去,和写进来之前,scl线都保持为低,直到读写完毕才释放

6.总线仲裁:(预防两个主机竞争),当主机产生从地址时,检测SDA线地址位,SDA线更趋向获得低电平的,从第一个地址到最后一个地址位,若都一样,则失败。

ICCON;先清除挂起enable ACK,prescaler IICCLK=PCLK/512=100KHZ(3.3v),enable interrupt,其中100KHZ,是从2401第一页,所以只能用50M/512最接近

6.因为E2PROM不能产生时钟,所以只能是从机,故rIICSTAT=(3<<6)|(1<<4)只能设置为主发送模式

7.IIC_READ

{设备地址=内存地址=设备地址=数据

1.rIICSTAT = 0XF0;先进行伪写,

2.rIICDS = devaddr0XA0,设备地址,从地址,其中IICDS为发送/接受移位寄存器

3等待while(rIICSTAT&0x1);//0为收到ack1未收到ack

while(!(rIICCON & 0X10));  //wait until interrupt pending第五位,0,无中断挂起,

5内存地址。注意:写(地址或者数据)要延时(for(i=0; i<100; i++);//差不750ns

6.rIICSTAT = 0XB0;  //真正的读状态rIICDS = devaddr|1; 

7. 写----设备地址//slave address可不用| 1,硬件 自己会转化,但是为更清除的表达意思, 或上1.

8.读,应答,中间有ack信号产生,就有中断,所以要清除中断,而且要延时,要等待 while,上面不完整,具体见代码iic

9.Rx模式中,读取最后一个数据的时候,要先disable ack,和清除挂起,因为最后一 个数据硬件自己知道,所以最后数据发送的时候要把ACK信号拉高。Disable

rIICCON &= ~((1<<7)|(1<<4));  //ack disable before reading last data, clear pending

10.读取数据从rIICDS,最好用数组, 用指针的话很容易指针最后不知道指到哪里去, 所以用数组比较不会出错。

11.再发停止信号 rIICSTAT = 0X90;

rIICCON &= ~(1<<4);

for(j=0; j<10000; j++);加个大延时,这些延时没有固定,都是硬件自己决 定。自己测试

}

8.IIC_WRITE

{

1.写设备地址rIICSTAT = 0XF0;  //(1)(1)(2)对调,则会出现第一个数据丢失。

  rIICDS = devaddr;  //slave address(2)

  while(!(rIICCON & 0X10));  //wait until interrupt pending

2.内存地址rIICDS = wordaddr;  //memory address

3.写的都要延时,同上,延时===》清除挂起===》等待while

4.页写,字节写=====页写:16个字节,超过则覆盖;

5.字节写,超过256,则覆盖,最好用字节写,比较不会出现错。

4.停止

5.清除挂起,(注意:要有个延时(很重要)for(i=0; i<10000; i++)这句话一定不能少。!!!

6.while(1)//呼叫

{

起始信号

写设备地址

清除挂起

注意:判断有没有ack

判断是否由中断挂起  (这两个就一个都不能少,因为产生中断挂起的情况有 很多种,不能判断是否写完)

break

}

7.写周期写完

8.发送停止信号

9.停止 rIICCON &= ~(1<<4);  //clear pending

for(j=0; j<10000;j++);

}

 

阅读(534) | 评论(0) | 转发(0) |
0

上一篇:6-buzzer

下一篇:9-字库

给主人留下些什么吧!~~