mini2440裸机试炼之——IIC控制EEPROM数据传输

内容:

向EEPROM(AT24C02)内部地址0x00—0xff,依次写入0x00—0xff,然后再读出数据。

IIC总线介绍:

IIC(Inter-IntegratedCircuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备。在iic总线上,只需要两条线:串行数据线SDA和串行时钟线SCL,便可完成通信

IIC要点

1、  清IIC中断标志语句rIICCON&= ~0x10;一定要在读写寄存器IICDS的后面,中断是读写寄存器后发生的;

2、  由于EEPROM的读取速度并不快,所以每次读写中断都需要短暂的延时函数;

3、  在对AT24C02A进行读取数据时,在发送带有读命令的从设备地址后,AT24C02A会再返回一个从设备地址信息或从设备内存地址信息作为应答,所以一定要把该字节读取后抛弃,因为它不是我们所要读取的信息;

4、  按照AT24C02A的时序,在发送从设备地址字节时,它的最低位是0表示写,1表示读。但对于s3c2440来说,不用人为设置这一位,即是0是1都无所谓,因为这一位是由s3c2440根据是主设备发送模式还是主设备接收模式来自动设置。(所以都默认使用0xa0);

EEPROM介绍

AT24CXX系列是带有iic总线接口的EEPROM,其中主要包括AT24C01/02/08/16等,其容量(bits x页)分别为128 x 8/256x 8/1024 x 8/2048 x 8/;对于AT24C02A的三位地址线都是写死的,因为在进行读写操作时使用8位地址已经足够,所以三位地址线写死作为片选,对于AT24C02A的三位地址线第一位必须写死,后两位可以作为内部页地址。因为AT24C02A的大小超过了256byte,8为寻址,已经没法使用到芯片内所有的空间。因此对于后面两位也就可以由程序决定了。

写EEPROM中的数据

在写数据的时候,AMR9作为主设备,EEPROM是从设备

第一种写byte方式(我的程序中是使用这个方式):

写一个byte实际上需要发送三次数据。在这个过程中,主设备为发送状态。第一个数据——设备地址。第二数据——ARM9想写的EEPROM中相对于数据存储的首地址的偏

移地址。第三个数据——想写入到EEPROM中的具体数据。最后停止。

第二种页写方式:

其实写页与写byte应该是一致的,第一个数据——设备地址。第二数据——ARM9想写的EEPROM中相对于数据存储的首地址的偏移地址(但是这个地址是首地址。

AT24C02一页是8byte,AT24C04/08一页是16byte。所以在写页的时候最多写一页的大小,如果写太多就会重新又从首地址开始,以前写的会被覆盖掉。)。第三、四、······数据——就是你想写入到EEPROM中的数据。最后停止

读EEPROM中的数据

主设备仍然是ARM9,从设备是EEPROM,是发送状态还是接收状态,这个iic会自动设置;

第一种读当前地址数据:

第一个数据——(主设备现在处于发生状态)发送从设备地址,

第二个数据——(主设备处于接收状态)ARM9接收数据,注意此时是NO ACK。再停止。(要在产生NO ACK后在读取数据这时数据会是稳定的。网上有问为什么在读IIC

最后需要读两次,我自己实验了,只需要最后一次就行,)

第二种随机读数据方式:(我的程序中是使用这个方式)

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

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

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

整主设备状态的。

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

第三种读序列地址(页读):

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

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

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

代码块

#include "def.h"
#include "2440addr.h"
#include "2440lib.h" 

static unsigned int i,j,save_E,save_PE;
static U8 data[256];
static volatile int flag;   //用于标识是否收到应答信号,改标识在终端处理程序中被清0 

/**************************************************************
IIC 初始化函数
**************************************************************/
void iic_init(void){
    rGPECON |= 0xa0000000;                 //GPE15:IICSDA , GPE14:IICSCL (rGPEUP[14:15]没有上拉选项)

    //[7]=1允许应答发生  [6]=0 IICCLK = fPCLK /16  PCLK 50MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
    // 允许IIC总线Tx/Rx中断使能   IICCON[3:0]=16
    rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf); 

    rIICADD  = 0x10;     //从地址    表示2440作为从设备的时候的地址,在这里2440是作为一个主设备存在的,所以没有作用。
    rIICSTAT = 0x10;         //IIC总线数据输出使能读写
    rIICLC = (1<<2)|(1);     //使能滤波器 延时五个时钟  

}

/**************************************************************
 IIC中断函数
**************************************************************/
void __irq Iic_isr(void)
{
    flag = 0;
    rSRCPND = 0x1<<27;          //清除中断
    rINTPND = 0x1<<27;
}

void iic_isr(void){
    rINTMSK &= ~(0x1<<27);
    pISR_IIC = (unsigned)Iic_isr;//中断入口
}

/**************************************************************
    写EEPROM中的数据
**************************************************************/
void Wr24C080(U32 slvAddr, U32 addr, U8 data)
{
    flag=1;            //以下都是应答标志 标志位置1
    rIICDS = slvAddr;  //**设备地址(EEPROM的地址为1010)
    rIICSTAT = 0xf0;   // 主设备发送模式,写)产生起始信号
    rIICCON &= ~0x10;  //以下都是清中断标志
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
    Delay(1);  

    flag =1 ;
    rIICDS = addr;     //偏移地址
    rIICCON &= ~0x10;
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
    Delay(1);  

    flag =1 ;
    rIICDS = data;     //要写入的具体数据
    rIICCON &= ~0x10;
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
    Delay(1);  

    rIICSTAT = 0xd0;                    //Stop MasTx condition
    rIICCON  = 0xaf;                    //Resumes IIC operation.
    Delay(1);  

} 

/**************************************************************
    读EEPROM中的数据
**************************************************************/
void Rd24C080(U32 slvAddr, U32 addr, U8 *data)
{
    unsigned char temp;
    flag=1;
    rIICDS = slvAddr;   //设备地址(EEPROM的地址为1010)
    rIICSTAT = 0xf0;    // 主设备发送模式用来发送slvAddr和addr,,启动
    rIICCON &= ~0x10;
    while(flag == 1)    // 当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
    Delay(1);  

    flag =1 ;
    rIICDS = addr;       //偏移地址
    rIICCON &= ~0x10;
    while(flag == 1)    // 当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
    Delay(1);  

    flag=1;
    rIICDS = slvAddr;   //从设备地址。这是特定要求这样发送的。。(在这里主设备会被配置为接收状态),
                        //这此发送设备地址是用来同时调整主设备状态的。
    rIICSTAT = 0xb0;    // 主设备接收模式用来接收数据,启动
    rIICCON &= ~0x10;
    while(flag == 1)    // 当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0
     Delay(1);  

    // 注意:读取下面这个字节必须进行,因为在发送带有读命令的从设备地址后,
    // AT24C02A会再返回一个从设备地址信息或从设备内存地址信息作为应答,所以一定要把该字节读取后抛弃,因为它不是我们所要读取的信息;
    flag =1 ;                          // 标志位置1
    temp = rIICDS;      // 抛弃第一自己
    rIICCON &= ~0x10;   // 清中断标志
    while(flag)
     Delay(1);  

    rIICCON = 0x2f;     //Resumes IIC operation with NOACK.
    *data = rIICDS;
    Delay(1);
    rIICSTAT = 0x90;   //Stop MasTx condition
    rIICCON  = 0xaf;   //Resumes IIC operation.  

    Delay(1);  

}  

/**************************************************************
 IIC 子main函数
**************************************************************/
void IIC(void)
{  

    Uart_Printf("\n  ***  IIC TEST  ***  \n"); // Delay(1000); //1

    //保护现场
    save_E   = rGPECON;
    save_PE  = rGPEUP; 

    iic_init(); //IIC初始化
    iic_isr();  //IIC中断

    Uart_Printf("写入数据到EEPROM\n"); //向EEPROM写数据i
    for(i=0;i<256;i++){ Wr24C080(0xa0,(U8)i,i); Delay(1);}   //注意这个延时不能少,否则出现有些数据无法写入的问题           

    for(i=0;i<256;i++) data[0] = 0; //初始化data[i]  

    Uart_Printf("读EEPROM中的数据\n"); //EEPROM读取数据到data[i]
    for(i=0;i<256;i++){ Rd24C080(0xa0,(U8)i,&(data[i])); Delay(1);}

    for(i=0;i<16;i++)  //打印data[i]数组
    {    Uart_Printf("\n");
         for(j=0;j<16;j++)   Uart_Printf(" %2x",data[i*16+j]);  } 

    //还原现场
    rINTMSK |= 0x1<<27;
    rGPEUP  = save_PE;
    rGPECON = save_E; 

    while(1){
    }
}

截图:

时间: 2024-10-10 15:14:19

mini2440裸机试炼之——IIC控制EEPROM数据传输的相关文章

mini2440裸机试炼之—RTC闹钟中断,节拍中断

环境搭建 硬件环境:J-link v8.mini2440.J-link转接板.串口转USB线 软件环境:windows7(32位).开发板uboot(NandFlash).J-link驱动(J-Link ARM V4.10i).SecureCRT.ADS1.2 其中ADS里的AXD设置:加载JlinkRDI.dll+Options->Configure Interface...,在Session File一页中选择"Run Configuration Script",将该name

mini2440裸机试炼之IIS——音乐播放器

IIS 信号频率设置 IIS(Inter-IC Sound)由飞利浦公司开发,是一种常用的音频设备接口,主要用于CD.MD.MP3等设备. s3c2440一共有5个引脚用于IIS:IISDO.IISDI.IISSCLK.IISLRCK和CDCLK.前两个引脚用于数字音频信号的输出和输入,另外三个引脚都与音频信号的频率有关,可见要用好IIS,就要把信号频率设置正确. IISSCLK为串行时钟,每一个时钟信号传送一位音频信号.因此IISSCLK的频率=声道数×采样频率×采样位数,如采样频率fs为44

mini2440裸机试炼之——Uart与pc端实现文件、字符传输

1.  波特率(Baud rate)即调制速率,1波特即指每秒传输1个符号. 2.  非FIFO模式,即传输数据不利用FIFO缓存,一个字节一个字节地传输. 3.  接收到的数据是放到接收缓存器URXHn中,要发送数据时,是把数据放入发送缓存器UTXHn中.由于UART是通过字节方式传输数据的,因此要区分是大端模式还是小端模式,也就是说这两个寄存器在这两种模式下,所在的地址是不同.为了了解当前数据传输的各种状态,还需要一些状态寄存器.传输状态寄存器UTRSTATn非常有用,它的第0位可以用来判断

mini2440裸机试炼之——整合

mini2440裸机试炼系列先在这里落尾了,写了一个裸机整合的系统,各功能的代码在之前都有介绍的 目录视图: 整合的bin文件下载

mini2440裸机试炼之——看门狗中断和复位操作

看门狗的工作原理: 设本系统程序完整运行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常运行时,定时器就不会溢出,若由于干扰等原因使系统不能在Tp时刻修改定时器的记数值,定时器将在Ti时刻溢出,引发系统复位,使系统得以重新运行,从而起到监控的作用. 看门狗具有两个功能: 1. 当做常规时钟,可以产生中断: 2. 当看门狗定时器使用,当计数器WTCNT为0时,产生复位: 看门狗的功能方框图: 我程序中PCLK为50MHz,预分频值=77,时钟除数因子选128, 时钟周期t_wat

mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信

这个只能作为自己初步了解MDA的开门篇 实现功能: 将字符串数据通过DMA0通道传递给UTXH0,然后在终端 显示.数据传输完后,DMA0产生中断,beep声, LED亮. DMA基本知识 计算机系统中各种常用的数据输入/输出方法有查询方式(包括无条件及条件传送方式)和中断方式,这些方式适用于CPU与慢速及中速外设之间的数据交换.但当高速外设要与系统内存或者要在系统内存的不同区域之间进行大量数据的快速传送时,就在一定程度上限制了数据传送的速率.直接存储器存取(DMA)就是为解决这个问题提出的,采

mini2440裸机试炼之—计算器(LCD显示,触摸屏中断)

基于T35 TFT LCD屏实现功能: 1. 在屏幕上画一个计算器界面,包括0-9,+,-,*,/: 2. 实现触摸选择界面上的数字和运算符, 3. 并计算出结果显示在显示框内. 注意,只实现整数功能,没涉及小数,只实现一次运算,不保存上次运算结果. 实现界面: 实现过程: 开启LCD电源,初始化LCD>>>LCD填充界面图片>>>开启触摸屏中断>>>获取键值>>>区分数字和功能来调用数字图片显示.   数字图片: 空白图: 除数为零

s3c2440的IIC控制

在tq2440和mini2440上都连接着EEPROM 它们作用也仅仅是测试I2C总线是否能用. 其中在mini2440上EEPROM型号是 AT24C08,在tq2440上这个型号是 AT24C02A. S3C2440A RISC 微处理器可以支持一个多主控 IIC 总线串行接口.一条串行数据线(SDA)和一条专用时钟线(SCL) 连接到 IIC 总线的总线主控和外设之间.SDA 和 SCL 线都为双向的,都连接到GPE14(SCL)  GPE15(SDA). 为了控制多主控 IIC 总线操作

mini2440裸机音乐播放器(很久以前的笔记)

[这是好久以前写的,有点乱,没时间整理,当做记录用的.] 图片粘贴失效,没上传图,想要的直接下载文档吧. 项目目的:通过IIS,触摸屏,LCD模块实现音乐播放器功能(按钮上一首.下一首.播放.暂停的音频控制功能,并实现播放歌曲时显示相应的歌曲图片,不播放时显示hello music图片) 项目设备:windows7(32位),mini2440,uboot(nandflash),ADS1.2开发环境,jlink v8,耳机: 功能模块LCD.触摸屏.IIS 分别介绍: Main函数中主频设置: U