mini2440 IIC实验(读写EEPROM)

    下面,我就说说那个让我做了5天的实验吧。代码其实还有点问题,有待以后改进。

      实验目的:通过IIC总线读写EEPROM (AT24C08A)

      相关的内容见赵老师的博客:http://blog.csdn.net/zhaocj/article/details/5477152

      赵老师的程序是读写at24c02a,而我的板子上的是AT24C08A,但是原理是一样的。

      想要读写某一芯片就必须好好看看它的芯片手册,否则可能会出现很奇怪的问题

      我从芯片手册上得知AT24C08A的容量为8Kbits,换算成字节就是1KB,不过开发板的使用手册上说AT24C08A有256B容量。这是为什么呢?

      大家看看AT24C08A的芯片手册,原文有这么一句话:

      The AT24C08A only uses the A2 input for hardwire addressing and a total of two 8K devices maybe addressed on a single bus system. The A0 and A1 pins are no connects.

      这段话我翻译了一下,如下:

      AT24C08A只使用A2引脚用来硬接线寻址,在同一个总线上总共有两个8K的AT24C08A能被寻址。A0,A1引脚悬空。

      也就是说,当总线上有两片AT24C08A时,使用A2来决定选中哪一片。比如:A2=0时选中第一片,A2=1时选中第二片。

      但是,mini2440开发板上是这样连接AT24C08A芯片的:


      从图中可以看到:A2 A1 A0全部接地。

AT24C08A芯片手册中还有这么一句:

      The 8K is internally organized with 4 blocks of 256 pages of 4-bytes each.Random word addressing requires a 10 bit data word address.

大体意思是:AT24C08A分成4块,一块64页,一共256页,每一页4B。(所以一块的大小是256B),随机寻址需要10位的地址。

      其中我觉得A1 A0使用来选择哪一块的。但是mini2440开发板将A1 A0接地,所以只能寻址第一块的空间,所以才说AT24C08A容量有256B(其余的256B*3的空间没有使用)正确的解释看下面:

      好了,我在吧我修改的代码附上,其中我有疑问的用问号标注,希望有朋友能和我共同探讨。


===========2013-5-15==========

今天有看了看芯片手册,结合韦老师的视频,发现原来的理解稍微有点偏差:

芯片手册有如下说明:
The 8K EEPROM only uses the A2 device address bit with the next 2 bits being for memory page addressing. 
The A2 bit must compare to its corresponding hard-wired input pin.
The A1 and A0 pins are no connect.

学过IIC的童鞋知道,通信开始的时候要发一个开始信号,接着发从设备的地址,对于at24c08a来说,地址为 1 0 1 0 A2 P1 P0 r/w 这8位。
其中P1 P0 用来选择4页中的一页(块)。

所以即使A2 A1 A0都接地,但是,在发送从设备地址的时候,可以指定读哪一个页,就可以访问到全部1KB空间了。



//AT24C08A页写(最多写16个字节)
//输入参数依次为设备内存地址、IIC数据缓存数组和要写入的数据个数
void wr24c08a(unsigned char page, unsigned char wordAddr,unsigned char *buffer,int sizeofdate )
{

	int i;

	flag =1;        		//应答标志设置为1,表示没有进入IIC中断
	IICDS = page;
	//IICCON &= ~0x10; 	//清中断标志
	IICSTAT = 0xf0;		//主设备发送模式

	uart0_puts("\n\rwait for ack after start signal........\n\r");
	while(flag == 1){		//等待从设备应答,               

                uart0_puts("flag=1\n\r"); //如果将这句话注释条,程序就不能继续运行了。这是为什么????下面也是这样。
		delay(10);		//一旦进入IIC中断,设置flag=0之后,即可跳出该死循环
	}
	uart0_puts("receive the ack from the device\n\r");	

	uart0_puts("write device memory address\n\r");
	flag = 1;
	IICDS = wordAddr;		//写入从设备内存地址
	IICCON &= ~0x10;		//恢复IIC传送
	while(flag){
		uart0_puts("flag=1\n\r");
		delay(10);
	}
	uart0_puts("get ack\n\r");

	//连续写入数据
	uart0_puts("write data to EEPROM\n\r");
	for(i=0;i<sizeofdate;i++){
	      flag = 1;
	      IICDS = *(buffer+i);
	      IICCON &= ~0x10;
	      while(flag){
			uart0_puts("flag=1\n\r");
			delay(10);
		}
	}
	uart0_puts("finish writing\n\r");

	IICSTAT = 0xd0;         //发出stop命令,结束该次通讯
	IICCON = 0xaf;          //为下次IIC通讯做准备

	delay(100);                   //等待
}
 

//AT24C08A的序列读,sizeofdate最大为256
//输入参数依次为设备内存地址、IIC数据缓存数组和要读取的数据个数
void rd24c08a(unsigned char page, unsigned char wordAddr,unsigned char *buffer,int sizeofdate)
{
	int i;
      unsigned char temp;

	uart0_puts("\n\rDUMMY WIRTE\n\r");
      flag =1;
      IICDS = page;
//      IICCON &= ~0x10; 	//清中断标志
      IICSTAT = 0xf0; 	//主设备发送模式


	uart0_puts("send device address\n\r");
      while(flag)
		delay(100);
	uart0_puts("get ack\n\r");

	uart0_puts("send word address \n\r");
      flag = 1;
      IICDS = wordAddr;
      IICCON &= ~0x10;
      while(flag){
		uart0_puts("flag=1\n\r");
		delay(10);
	}
	uart0_puts("get ack\n\r");
	uart0_puts("DUMMY WRITE FINISH.\n\r");

	uart0_puts("host receive mode,send start signal again\n\r");
      flag = 1;
      IICDS =  page;	//
      IICCON &= ~0x10;   
      IICSTAT = 0xb0; 	//主设备接收模式
     	while(flag){
		uart0_puts("flag=1\n\r");
		delay(10);
	}

	uart0_puts("get ack\n\r");
  
	uart0_puts("first data is device address\n\r");
      flag = 1;
      temp = IICDS;                    //读取从设备地址
      IICCON &= ~0x10;
      while(flag){
		uart0_puts("flag=1\n\r");
		delay(10);
	}	

	uart0_puts("get ack,decice address is \n\r" );

	//连续读
	uart0_puts("read data\n");
      for(i=0;i<sizeofdate;i++){
		flag = 1;
		if(i==sizeofdate-1) 	//如果是最后一个数据
			IICCON &= ~0x80; 	//不再响应
		*(buffer+i) = IICDS;
		IICCON &= ~0x10;
		while(flag){
			uart0_puts("flag=1\n\r");      
			delay(10);
		}
        }
	uart0_puts("finish reading\n\r");

      IICSTAT = 0x90;         //结束该次通讯
      IICCON = 0xaf;          //
      delay(100);                         
}


注意:如果要进行连续的读写操作,那么两次操作之间要加上一个延时,如delay(3000);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值