mini2440----keil for AMR之IIC读写EEPROM(AT24C08)

发布者:真诚友谊最新更新时间:2017-11-27 来源: eefocus关键字:mini2440  keil  AMR  IIC读写  EEPROM 手机看文章 扫描二维码
随时随地手机看文章

文章大纲:

一:EEPROM芯片介绍(包括各种读写的时序与管脚定义)

二:S3C2440中对于IIC需要配置的寄存器

三:IIC成功读写EEPROM的程序(光盘的那个IIC读写程序真心对初学者不好理解)

 

一:EEPROM芯片介绍

在这里分析AT24C02A/AT24C04A/AT24C08A,对于其他不同型号的EEPROM芯片要根据具体手册进行分析。他们的大小分别是2K(256*8)/4K(512*8)/8K(1024*8)因此可以看出实际大小是256/512/1024byte,。对于AT24C02A的三位地址线都是写死的,因为在进行读写操作时使用8位地址已经足够,所以三位地址线写死作为片选,对于AT24C08A的三位地址线第一位必须写死,后两位可以作为内部页地址。因为AT24C08A的大小超过了256byte,8为寻址,已经没法使用到芯片内所有的空间。因此对于后面两位也就可以由程序决定了。

写EEPROM有两种,(在写数据的时候,AMR9作为主设备,EEPROM是从设备)

第一种写byte方式:

写一个byte实际上需要发送三次数据。在这个过程中,主设备为发送状态。第一个数据——设备地址。第二数据——ARM9想写的EEPROM中的地址。第三个数据——想写入到EEPROM中的具体数据。最后停止。

第二种写页方式:

自我感觉其实写页与写byte应该是一致的,第一个数据——设备地址。第二数据——ARM9想写的EEPROM中的地址(但是这个地址是首地址。AT24C02一页是8byte,AT24C04/08一页是16byte。所以在写页的时候最多写一页的大小,如果写太多就会重新又从首地址开始,以前写的会被覆盖掉。)。第三、四、······数据——就是你想写入到EEPROM中的数据。最后停止

读EEPROM中的数据

第一种读当前地址数据

主设备仍然是ARM9,从设备是EEPROM,但是要注意主设备的状态,有时候会是发送状态,有时候会是接收状态

第一个数据——(主设备现在处于发生状态)发送从设备地址,并且把主设备配置为接收状态。

第二个数据——(主设备处于接收状态)ARM9接收数据,注意此时是NO ACK。再停止。(要在产生NO ACK后在读取数据这时数据会是稳定的。网上有问为什么在读IIC最后需要读两次,我自己实验了,只需要最后一次就行,)

第二种随机读数据方式

第一个数据——(主设备处于发生状态),发送一个从设备地址。第一个设备地址是用来从设备匹配的,也在文档中被称为a “dummy” byte write sequence

第二个数据——(主设备处于发生状态),发送一个想读取数据在EEPROM中的地址。

第三个数据——(主设备处于发生状态),发送一个从设备地址。这是特定要求这样发送的。。(在这里主设备会被配置为接收状态),这此发送设备地址是用来同时调整主设备状态的。

第四个数据——(主设备处于接收状态)需要读的数据。也是一个NO ACK,与读当前地址类似。最后再停止。

第三种读序列地址

与读当前数据有些类似。

第一个数据——(主设备处于发送状态),发出设备地址,并配置主设备为接收状态。为后面接收数据准备

第二、三···个数据——(主设备处于接收状态),前面每个数据都会发送ACK,最后一个数据是一个NO ACK。

再停止。

以上这些,主要要注意主设备状态的调整,以及为NO ACK时的处理,后面有事例程序,能够比较清楚的看到怎么进行处理的。

二:S3C2440中对于IIC需要配置的寄存器

GPECON,主要是把这个GPIO配置为IIC模式。

IICCON:其中[0]---[3]与[6]共同决定IIC总线的时钟频率。

[4]是一个中断标志位,我们如果没有用中断方式的话,应该可以通过查询这一位进行。(我用的中断,没有具体自己实践)

[5]IIC中断使能。[7]是否发送ACK。这一位在后面读数据的时候,要注意进行改变。

IICSTAT:这个寄存器主要是一些标志为,不需要配置,主要要配置的是这几位。

[4]使能IIC数据线的,使其能够发送数据。

[5]启动和停止IIC,1启动。0停止。

[6-7]是配置AMR9的状态的,一般CPU是一个主设备的角色。只有在两块CPU进行相互通信的时候,可能把他配置成为一个从设备的状态。所以在我们实验中,ARM9全部都是处于主设备的角色。

IICADD是CPU做从设备的时候,给他配置的从设备地址,这里可以不用配置。

IICDS:数据移位寄存器。发送数据就是把数据发到这个寄存器。接收数据就是从这个寄存器中去取数据。

如果使用中断当然还得配置INTMSK,打开IIC中断。

三:IIC成功读写EEPROM的程序

首先要对程序有几点说明:

1:f_GetACK必须是volatile类型,因为在中断中改变了值,不然值被保存在缓存中了,最后检测时,不能真正读到其值。详细见

在C编程中使用到的几个重要关键字之一volatile

2:IIC的中断总是在ACK周期内,产生的,我没有贴出操作流程图,ARM9文档中IIC这章已经清楚给出。所以在有ACK的那些数据发送与接收都可以用中断操作,但是从读数据的后接收数据来看,由于是NO ACK,所以就没有用中断操作了,而且自己进行了一个延时。在读数据。

 copy

  1. static U8 _iicData[IICBUFSIZE];  

  2. static volatile int f_GetACK;  


view plain copy

  1. void Test_Iic(void)  

  2. {  

  3.     unsigned int i,j,save_E,save_PE;  

  4.     static U8 data[256];  

  5.   

  6.     Uart_Printf("\nIIC Test(Interrupt) using AT24C02\n");  

  7.   

  8.     save_E   = rGPECON;  

  9.     save_PE  = rGPEUP;  

  10.     IIC_Init();         //初始化IIC必须的一些寄存器  

  11.     Uart_Printf("Write test data into AT24C02\n");  

  12.   

  13.     for(i=0;i<48;i++)                          

  14.         Wr24C080(0xa0,i,i);         //slvaddr, addr,  data  

  15.                                                           

  16.              

  17.     for(i=0;i<48;i++)  

  18.         data[i] = 0;  

  19.   

  20.     Uart_Printf("Read test data from AT24C02\n");  

  21.       

  22.     for(i=0;i<48;i++)  

  23.         Rd24C080(0xa0,i,&(data[i]));   

  24.   

  25.         //Line changed 0 ~ f  

  26.     for(i=0;i<3;i++)  

  27.     {  

  28.         for(j=0;j<16;j++)  

  29.             Uart_Printf("%2x ",data[i*16+j]);  

  30.         Uart_Printf("\n");  

  31.     }  

  32.     rINTMSK |= BIT_IIC;      

  33.     rGPEUP  = save_PE;  

  34.     rGPECON = save_E;  

  35. }  

 copy

  1. void IIC_Init(void)  

  2. {  

  3.     //配置GPE端口为IIC功能  

  4.     rGPECON &=~(0xF<<28);  

  5.     rGPECON |=(1<<31)|(1<<29);  

  6. //产生ACK,IIC中断使能,频率200KHz  

  7.     rIICCON = 0;  

  8.     rIICCON |=(7)|(1<<5)|(1<<7);  

  9.     //模式为主发送,使能Rx/Tx     (不管是读还是写初始化都为主发送)  

  10.     rIICSTAT |=(3<<6)|(1<<4);  

  11.     rIICADD = 0x10;//从地址    表示2440作为从设备的时候的地址,  

  12. //在这里2440是作为一个主设备存在的,所以没有作用。  

  13. //EEPROM的标识符为1010  

  14. //控制字节,其中高四位为器件类型标识符,后三位作为片选   

  15. //最后一位决定读写,0是读,1是写。  

  16.   

  17. //IIC传输中断开启  

  18.     rINTMOD=0x0;  

  19.     rINTMSK &=~BIT_IIC;  

  20.     pISR_IIC = (unsigned)IicInt;  

  21. }  

 copy

  1. //*************************[ Wr24C080 ]****************************  

  2. void Wr24C080(U32 slvAddr,U32 addr,U8 data)  

  3. {  

  4.     f_GetACK = 0;  

  5.     rIICDS = slvAddr;               //发送第一个数据  

  6.     rIICSTAT = 0xf0;  

  7.     while(f_GetACK == 0);           //等待发送结束  

  8.     f_GetACK = 0;  

  9.     rIICDS = addr;                  //发送第二个数据  

  10.     rIICCON = 0xaf;  

  11.     while(f_GetACK == 0);           //等待发送结束  

  12.     f_GetACK = 0;  

  13.     rIICDS = data;                  //发送第三个数据  

  14.     rIICCON = 0xaf;  

  15.     while(f_GetACK ==0);           //等待发送结束  

  16.     rIICSTAT = 0xd0;               //停止IIC  

  17.     rIICCON = 0xaf;  

  18.     Delay(3);  

  19. }  

 copy

  1. void Rd24C080(U32 slvAddr,U32 addr,U8 *data)  

  2. {  

  3.     char cRecvByte;  

  4.   

  5.     f_GetACK = 0;  

  6.   

  7.     rIICDS = slvAddr;           //发送第一个数据  

  8.     rIICSTAT = 0xf0;  

  9.     while(f_GetACK==0);         //等待结束  

  10.     f_GetACK = 0;  

  11.     rIICDS = addr;              //发送第二个数据  

  12.     rIICCON = 0xAF;  

  13.     while(f_GetACK==0);          //等待结束  

  14.     f_GetACK = 0;  

  15.     rIICDS = slvAddr;           //发送第三个数据  

  16.     rIICSTAT = 0xb0;            //配置主设备状态为接收  

  17.     rIICCON = 0xaf;               

  18.     while(f_GetACK==0);         //等待结束  

  19.     f_GetACK = 0;  

  20.     rIICCON = 0x2f;             //NO ACK配置  

  21.     Delay(2);                   //等待其稳定,延时不要求精确  

  22.     cRecvByte = rIICDS;         //接收第四个数据  

  23.     rIICSTAT = 0x90;            //停止IIC  

  24.     rIICCON = 0xaf;  

  25.     Delay(3);  

  26.     *data = cRecvByte;  

  27. }  



  1. void __irq IicInt(void)  

  2. {  

  3.     ClearPending(BIT_IIC);      

  4.     f_GetACK = 1;  

  5. }  


关键字:mini2440  keil  AMR  IIC读写  EEPROM 引用地址:mini2440----keil for AMR之IIC读写EEPROM(AT24C08)

上一篇:ARM指令后缀与常用读取指令
下一篇:mini2440-----keil for ARM之中断一

推荐阅读最新更新时间:2024-03-16 15:47

U-boot-2014.04移植到MINI2440(7) nand flash datasheet及arm9控制寄存器分析
我的MINI2440上有一个256M的nand flash,后面我们需要从nand启动u-boot,然后引导加载内核,再挂载根文件系统,这里先对其做一个较为细致的认识。主要是硬件管脚定义,控制方式,处理器的控制寄存器对其做一个了解,因为现在市面上nand的用途比较广泛,数码相机,mp3都要使用,进入正题。 一.nand flash datasheeet 在移植好的u-boot下输入nand info会出现下面的信息: Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB 这说明nand大小为256M,工作电压3.3v,数据总线为8位,扇区大小为128K。首先我们
[单片机]
U-boot-2014.04移植到<font color='red'>MINI2440</font>(7) nand flash datasheet及arm9控制寄存器分析
I2C串行EEPROM应用系统的健壮性设计
引言 在嵌入式控制系统中,通常要用到非易失性存储器。无论是掉电时维持需要保存的设置,还是存储重要记录,可靠的非易失性存储器都是一种理想的选择。非易失性存储常常采用外部串行存储器来实现,其中I2C接口产品是最常用的一种类型。然而,这种产品和其他EEPROM存储器一样,在使用时也存在着一些条件会潜在地导致其产生某些非标准的甚至是错误的操作。因此在进行I2C串行EEPROM存储器的应用设计时,除了应考虑数据手册规范之外,还必须考虑更多的因素,这样才能实现更健壮的总体设计,确保系统具有优良的质量特性。 1 防意外写措施 器件在上电/掉电期间或者SDA/SCL线的噪声过大时都有可能导致意外写操作。为了解决这一问题,一方
[单片机]
KEIL提示“No target connected”的解决方法
在用STM32F051Disconvery学习时,配置GPIOA时,不小心将连接SWD总线上的两个端口都配置为了输出,这下惨了,就再也不能用SWD仿真或者下载程序了,解决方法如下: 1、先确认目标板上电。 2、先长按住目标板上的复位键,再点击 Settings,再松开目标板上的复位键。 3、此时KEIL打开Settings的设置对话框,请确认有红框圈中的内容后,再进行下一步。 4、将STM32F051Disconvery板断电,重新上电。 5、先长按STM32F051Disconvery的复位键,再点击仿真或者下载按钮,再松开复位键。 注:这里点仿真到松开复位键不是每一次都能成功,每次点了仿真键到松开复位
[单片机]
<font color='red'>KEIL</font>提示“No target connected”的解决方法
关于51单片机EEPROM的使用
STC51单片机有类似flash的功能EEPROM,可以掉电保存数据,不同型号的可以保存不同大小的数据,以12C5A60S2为例,EEPROM的大小为2K,分为两个扇区,掉电保存在很多地方需要,笔者这次和大家讨论一下STC51单片机EEPROM的使用方法。 首先寄存器的问题,不同系列的STC单片机的与EEPROM有关的寄存器不同,比如10/11/12系列的sfr ISP_DATA = 0xC2;sfr ISP_ADDRH = 0xC3;sfr ISP_ADDRL = 0xC4;sfr ISP_CMD = 0xC5;sfr ISP_TRIG = 0xC6;sfr ISP_CONTR = 0xC7;89/90系列的sfr I
[单片机]
Keil C51程序设计中精确延时的总结
一、实现延时的两种方法 1、硬件延时 优点:用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时; 缺点:往往在精度要求不是很高时,会使定时器/计数器大材小用,而且很极端时,定时器根本不够的。 2、软件延时 优点:节省硬件资源的同时,只要正确使用可接近要求的精度,这种方法主要采用循环体进行; 缺点:精度不高,对编程者经验要求甚高。 二、硬件延时 1、常用晶振:11.059 2 MHz(容易产生各种标准的波特率)、12 MHz或6 MHz(机器周期 分别为1 μs和2 μs,便于精确延时)。 2、本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达2的16次方=65 536 。若定时器工作在
[单片机]
订单火热、人力遇冷,MiR AMR为“冷热交替“的电子制造业提供自动化解答
订单火热、人力遇冷,MiR AMR为“冷热交替“的电子制造业提供自动化解答 本土电子制造企业,长期面临着一“冷”一“热”两大挑战。 “热“在于中国电子制造行业持续的火热发展。 中国信息通讯研究院数据显示 , 本土电子行业生产一直维持较快增长。2022 年上半年,规模以上电子制造业增加值累计增长10.2%,是28 个主要的制造业大类行业中增长最快的行业。快速增长意味着发展机遇,也意味着订单交付压力。 电子制造业长期面临的“冷”挑战,就是人才市场持续的冷淡,产线中重复性作业任务招工难、用工难、留工难,进而逐步影响生产效率乃至订单交付速率。 多台MiR AMR协同工作 位于上海的某外资半导体公司同样面临着这样冷热交替
[工业控制]
订单火热、人力遇冷,MiR <font color='red'>AMR</font>为“冷热交替“的电子制造业提供自动化解答
Keil C51 的printf
在Keil C51 中使用printf ,首先需要重新实现 putchar(char c)函数。此函数在 char putchar (char c) { ES=0; SBUF = c; while(TI==0); TI=0; ES=1; return 0; } 我们先分析一下上面这个程序哈, 关闭串口中断 发送单字节数据 等待发送完毕 清除TI标志 开启串口中断 在main函数里可以直接使用printf函数进行输出了。 但是,我一直存在这样一个疑惑: void main() { unsigned char test1 = 55; printf( the
[单片机]
keil生成bin文件
在烧写stm32程序的时候,有时候需要用到串口烧写。那么就需要一个可烧写的bin文件了。 我们可以直接用keil来直接生成,不过keil的默认配置是没有这个设置的。配置如下图 添加指令:fromelf.exe --bin -o $L@L.bin #L 然后编译就会生成bin文件了
[单片机]
<font color='red'>keil</font>生成bin文件
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved