×
单片机 > 单片机程序设计 > 详情

2440 I2C存储卡读写实验 AT24c08a

发布时间:2020-08-25 发布时间:
|

本实验为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读写位为自动标记无需配置。


/*51实验24: I2C存储卡读写实验*/


#include

#include

#define cp8155 XBYTE[0xff20]

#define pa8155 XBYTE[0xff21]

#define pb8155 XBYTE[0xff22]

#define pc8155 XBYTE[0xff23]

#define dataadr 0x4000



//*********************************************

//MON51必须用到的

code unsigned char stop[3] _at_ 0x3b;


unsigned char code DISPB[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90,

                            0x088,0x83,0x0C6,0x0A1,0x86,0x8E,0xFF,0x0C,0xDE,0x0F3,0x08F};

unsigned char ledbuf[6];

sbit SCL=P3^0;

sbit SDA=P3^1;

sbit INS=P1^0;

sbit WRS=P1^1;

sbit RDS=P1^2;

bit ack;                             //是否应答

void disp(void);

void delay(unsigned char dl);

void Start_I2c(void);

void Stop_I2c(void);

void SendByte(unsigned char c);

unsigned char  RcvByte();

bit ISendByte(unsigned char sla,unsigned char c);

bit IRcvByte(unsigned char sla,unsigned char *c);


void main(void)

{

    unsigned char tmp1,tmp2;

    bit wrok,wrst;                  //读写正常,读写状态

    //SP=0x60;

        SP=0x53;

    tmp2=0x50;

    wrok=1;  wrst=0;

        cp8155=0x43; 

    while(1)

    {

       while(INS);

       delay(1);

       if (INS==0) break;

    }

    while(1)

    {

       if (wrst==0)

       {//写数据到卡

          for (tmp1=0;tmp1<0x80;tmp1++)

          {

             WRS=!WRS;

             if (ISendByte(tmp1,tmp2)==0) {wrok=0; break;}

             tmp2++;

          }

          Stop_I2c();

       }

       else

       {//从卡读数据

          for (tmp1=0;tmp1<0x80;tmp1++)

          {

             RDS=!RDS;

             if (IRcvByte(tmp1,&tmp2)==0) {wrok=0; break;}

             XBYTE[dataadr+tmp1]=tmp2;               //读取数据

          }

          Stop_I2c();

       }

       if (wrok==0)

       {//读写错误

          ledbuf[0]=0x01;  ledbuf[1]=0x0c;  ledbuf[2]=0x10;

          ledbuf[3]=0x0E;  ledbuf[4]=0x14;  ledbuf[5]=0x14;//IC-ERR

          while(1) disp();

       }

       if (wrst==0) wrst=1; //向卡写数据完成后,读取数据

       else

       {//IC卡读写正确

          ledbuf[0]=0x01;  ledbuf[1]=0x0c;  ledbuf[2]=0x09;

          ledbuf[3]=0x00;  ledbuf[4]=0x00;  ledbuf[5]=0x0d;//ICgood

          while(1) disp();

       }

    }

}


void disp(void)

{

    unsigned char i;

    unsigned int ledwz=0x20;

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

    {

       pb8155=DISPB[ledbuf[i]];

       pa8155=~(ledwz>>i);

       delay(8);

    }

}


void delay(unsigned char dl)

{

   unsigned char ii1,ii2;

   for (ii1=0;ii1

    // for (ii2=0;ii2<0xA;ii2++);

     for (ii2=0;ii2<0x0f;ii2++);

}


//发送开始

void Start_I2c(void)

{

   SDA=1;  delay(1);

   SCL=1;  delay(1);

   SDA=0;  delay(1);

   SCL=0;  delay(1);

}

//发送停止

void Stop_I2c(void)

{

   SCL=0;  delay(1);

   SDA=0;  delay(1);

   SCL=1;  delay(1);

   SDA=1;  delay(1);

}


//发送数据C可以是地址,也可以是数据,发完后等待应答,并置状态位ack=1(ok)

void  SendByte(unsigned char c)

{

   unsigned char BitCnt;

   for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位

   {

      SCL=0;

      if((c<

      else  SDA=0;

      delay(1);

      SCL=1;  delay(1);            //置时钟线为高,通知被控器开始接收数据位

   }

   SCL=0;    delay(1);

   SCL=1;    delay(1);

   if(SDA==1) ack=0;

   else ack=1;                    //*判断是否接收到应答信号

}


//发送字节数据函数

bit ISendByte(unsigned char sla,unsigned char c)

{

    Stop_I2c();  delay(1);               //结束总线

    Start_I2c();                //启动总线

    SendByte(0xA0);             //WR2401

    if(ack==0) return(0);

    SendByte(sla);              //地址

    SCL=0;    delay(1);

    if(ack==0) return(0);

    SendByte(c);         //写数据

    if (ack==0) return(0);

    Stop_I2c(); delay(3);

    return(1);

}


//读字节数据函数从器件地址sla,返回值在c. 返回1(OK)

bit IRcvByte(unsigned char sla,unsigned char *c)

{

    Stop_I2c();  delay(1);       //结束总线

    Start_I2c();                //启动总线

    SendByte(0xA0);             //WR2401

    if(ack==0) return(0);

    SendByte(sla);             //地址

    SCL=0;    delay(1);

    if(ack==0) return(0);

    Start_I2c();                //启动总线

    SendByte(0xA1);             //设备地址00

    if(ack==0) return(0);

    *c=RcvByte();               //读取数据

    if (ack==0) return(0);

    Stop_I2c();

    return(1);

}


//接收从器件传来的数据,并判断总线错误(不发应答信号),

unsigned char  RcvByte()

{

   unsigned char retc;

   unsigned char BitCnt;

   retc=0;

   for(BitCnt=0;BitCnt<8;BitCnt++)

   {

        SCL=0;   delay(1);    //置时钟线为低,准备接收数据位

        SCL=1;   delay(1);    //置时钟线为高使数据线上数据有效

        retc=retc<<1;

        if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中

        delay(1);

   }


关键字:2440  I2C  存储卡读写  AT24c08a 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计