mini2440 IIC-AT24C08a读写实验

 本实验为IIC总线通信协议,以友善之臂mini2440为实验平台,对其开发板上的AT24c08a指定位置写入字符串“hello”,并指定位置读出该位置的内容。

    初始工作,首先需要配置GPE14、15管脚分别为IICSLC、IICSDA,并禁止上拉功能。然后设置IIC时钟频率,使能应答信号,并使IIC中断使能,禁止IIC中断屏蔽寄存器。

应答中断处理函数为清除中断标志位,清除中断标记flag。

    指定内存写函数的实现为:首先设置主设备发送模式,写入从设备地址,清除中断标记,然后等待应答,写入设备内存地址,等待到应答后开始连续发送数据,存入指定空间。发送结束发出停止命令,结束本次通讯,让IIC状态改为开始状态,准备下一次读写操作。

    指定内存读函数,首先配置设备为发送模式,写入要读的设备地址,写入要读的设备内存,设置为主机接收模式,发送接收设备地址,此后从设备会返回一个要读的内存地址,读取该地址抛弃后,连续读取指定内存数据,读到最后一个数据不再产生应答,停止接收,改为准备状态。

    AT24C08 的地址格式为: 1 0 1 0 A2 P1 P0 W/R

    A2为设备地址位、P1,P0为片内页寻址  LSB=0 写    LSB=1 读

其中mini2440读写位为自动标记无需配置。

 

本实验实验代码如下:

#define    GLOBAL_CLK              1

#include <stdlib.h>

#include <string.h>

#include "def.h"

#include "option.h"

#include "2440addr.h"

#include "2440lib.h"

#include "2440slib.h"

#include "mmu.h"

#include "profile.h"

#include "memtest.h"

 

#define writedevAddr 0xa0;

 

#define readdevAddr 0xa0;

 

int flag;

 

void delay(int times)//延时函数

{

    int i;

    for(;times>0;times--)

      for(i=0;i<400;i++);

}

 

 

void init_24c08a(void)

{

       rGPEUP  |= 0xc000; //禁止上拉

 

    rGPECON |= 0xa00000;//设置管脚为时钟线和数据线

 

       rIICCON = 0xe0;  //设置IIC时钟频率,使能应答信号,并开启中断

 

       rIICSTAT = 0x10;//IIC中断使能

      

       rINTMSK &=~(0x1<<27);//禁止IIC中断屏蔽寄存器,使其中断使能

}

 

 

static void __irq IicISR(void)//IIC中断函数

{

       rSRCPND |=0x1<<27;

 

       rINTPND |=0x1<<27;

 

       flag=0;//标记中断发生

}

 

 

void wr_24c08a(unsigned char wordAddr,unsigned char *buffer,int sizeofdate) //写EEPROM程序

{

       int i;

 

       flag=1;//应答标记为无应答

      

       rIICSTAT=0xf0;//设置为在主设备发送模式     

 

       rIICDS=writedevAddr;//写入从设备地址

 

       rIICCON &=~(0x1<<4);//清除应答中断标记位

 

       while(flag)//等待中断是否发生,即从设备是否有应答

 

       delay(100);

 

       flag=1;//清除中断标记       

 

       rIICDS=wordAddr;//写入设备内存地址

 

       rIICCON &=~(0x1<<4);//清除应答中断标记位

 

       while(flag)//等待中断是否发生,即从设备是否有应得

 

       delay(100);

 

       for(i=0;i<sizeofdate;i++)//连续写入数据

       {

              flag =1;

 

              rIICDS =*(buffer+i);

 

              rIICCON &=~(0x1<<4);//清除应答中断标记位

 

              while(flag)

 

              delay(100);

       }

 

       rIICSTAT=0xd0;//发出停止命令,结束本次通讯

 

       rIICCON =0xe0;//为下次通讯做准备

 

       delay(100);

      

}

 

 

void rd24c02a(unsigned char wordAddr,unsigned char *buffer,int sizeofdate )//读指定内存地址程序

{

          int i;

 

       unsigned char temp;

 

     

       flag =1;

      

       rIICSTAT = 0xf0;                 //主设备发送模式

 

       rIICDS=readdevAddr;  //发送要读设备地址

 

       rIICCON &= ~0x10;            //清中断标志

 

       while(flag)

 

              delay(100);     

 

       flag = 1;

      

 

       rIICDS = wordAddr;//发送要读取内存地址

   

       rIICCON &= ~0x10;

 

       while(flag)

 

              delay(100);           

 

       flag = 1;

      

 

       rIICSTAT = 0xb0; //主设备接收模式

 

       rIICDS =readdevAddr;   //真正发送要读取从设备地址,开始接收数据

 

       rIICCON &= ~0x10;           

 

       while (flag)

 

              delay(100);             

 

       flag = 1;

             

 

       temp = rIICDS;//读取从设备地址

 

       rIICCON &= ~0x10;

 

       while(flag)

 

              delay(100);

 

//连续读

 

       for(i=0;i<sizeofdate;i++)

 

       {

 

              flag = 1;

 

              if(i==sizeofdate-1) //如果是最后一个数据

 

                    rIICCON &= ~0x80; //不再响应

 

              *(buffer+i) = rIICDS;

 

              rIICCON &= ~0x10;

 

              while(flag)

 

                     delay(100);

 

       }

 

       rIICSTAT = 0x90;         //结束该次通讯

 

       rIICCON = 0xe0;          //为下次通讯做准备

 

       delay(100);                         

 

}

 

 

void Main()

{

       int i;

      

       unsigned char *ptr,*ptr1;

      

       unsigned char data[6]="hello",data1[6];

 

       ptr=data;

      

       ptr1=data1;

      

       MMU_Init();//内存初始化

 

       init_24c08a();//IIC初始化

 

       pISR_IIC = (U32)IicISR;//中断函数入口地址传递给中断向量表

 

       wr_24c08a(0x0,ptr,6);//向EEPROM写入hello字符串

      

       delay(500);//写完不能马上读,否则出乱码,此处反复实验终于解决读乱码问题!

 

       rd24c02a(0x0,ptr1,6);//读出EEPROM内的数据并用Uart_print()函数打印出来

 

       Uart_Printf("从EEPROM读出的数据为:");

      

       for(i=0;i<5;i++)

       {

              Uart_Printf("%c",data1[i]);

       }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值