2440 I2C存储卡读写实验 AT24c08a

发布者:名字太长了吗最新更新时间:2019-10-21 来源: 51hei关键字:I2C  存储卡读写  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读写位为自动标记无需配置。


/*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);

   }


关键字:I2C  存储卡读写  AT24c08a 引用地址:2440 I2C存储卡读写实验 AT24c08a

上一篇:arm汇编程序S3C2440
下一篇:ARM异常中断返回的几种情况

推荐阅读最新更新时间:2024-11-13 05:33

mini2440 驱动ds18b20
想着有个ds18b20,于是就写了一个18b20的驱动。是在mini2440上面实现的。 ldd3的大师说得好,linux驱动应该尽可能多的提供机制,而不是提供策略。我觉得说得太有道理了。驱动本身就不应该涉及到太多策略问题,策略问题应该尽可能多的由应用程序去提供。作为驱动,应该尽可能多得去实现提供硬件的功能,然后留出接口给上面的应用程序调用。 其实ds18b20驱动比较简单,无非就是在单片机驱动18b20的基础上,家里一个字符驱动设备的外套。下面直接上代码吧。 驱动代码: #include linux/init.h #include linux/module.h #include linux/delay.h #
[单片机]
s3c2440裸机-I2c编程-3.i2c中断服务程序
Start信号之后,发出设备地址,在第9个时钟就会产生一个中断,我们根据i2c的流程图来编写中断程序。 每传输完一个数据将产生一个中断,I2C操作的主体在中断服务程序,它可以分为两部分:写操作,读操作。 完整code如下: static p_i2c_msg p_cur_msg; int isLastData(void) { if (p_cur_msg- cnt_transferred == p_cur_msg- len - 1) return 1; /* 正要开始传输最后一个数据 */ else return 0; } void resume_iic_with_
[单片机]
s3c2440中断总结+按键中断
一、启动代码之IRQ中断分析。 举例:timer4中断调用过程 1、当timer4发生中断,INTOFFSET寄存器的值变为中断源INT_TIMER4对应的值,即 14。 同时,程序将跳转到irq中断向量地址(0x18)处去执行,该处的指令为 b HandlerIRQ 2、在启动代码中有如下一段宏定义 $HandlerLabel HANDLER $HandleLabel $HandlerLabel sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does
[单片机]
s3c<font color='red'>2440</font>中断总结+按键中断
ARM9 S3C2440—ADC和触摸屏控制详解
S3C2440芯片内部共有8路A/D转换通道,AIN0-AIN7,转换器只有一个,转换精度为10位,最大转换率为2.5MHz A/D 转换器时钟下的500 KSPS。A/D 转换器支持片上采样-保持功能和掉电模式的操作。在常见的设计中,一般AIN4,AIN5,AIN6,AIN7被用作四线电阻触摸屏的YM、YP、XM、XP通道,剩余的AIN0~AIN3被引出,其中AI0外接一个可调电阻。 ADC的配置流程如下: 1、ADCDLY(P446) rADCDLY=50000; //Normal conversion mode delay about
[单片机]
PIC单片机的I2C读写程序
TITLE TWO WIRE/I2C BUS INTERFACE WITH PIC16C5x ; LIST P=16C54 ; ;***************************************************************************** ;** Two wire/I2C Bus READ/WRITE Sample Routines of Microchip's ;** 24Cxx / 85Cxx serial CMOS EEPROM interfacing to a ;** PIC16C54 8-bit CMOS single chip microcomputer ;*
[单片机]
MINI2440 内核基础开发
Liunx内核图 Liunx内核简介 Liunx是如何构成的? 由上图得知,Liunx由用户空间和内核空间两部分组成。 为什么Liuxn系统要将系统划分为用户空间与内核空间? ARM的7种工作模式 用户模式usr 快速中断fiq 系统模式sys 外部中断irq 管理模式svc 数据访问中止 未定义指令异常 内核空间组成部分: Liunx内核源代码 内核文件夹: fs目录: 存放各种文件系统的实现代码,每个子目录对应一个文件系统的实现,公用的源程序用于实现虚拟文件系统vfs ||–devpts /* /dev/pts虚拟文件系统 / ||–ext2 / 第二扩展系统 / ||–fat / MS的fat32文
[单片机]
MINI<font color='red'>2440</font> 内核基础开发
对链接地址0x30008000(S3C2440)的理解
当我们写链接器脚本的时候,我们会设置代码段的起始链接地址为0x30008000(S3C2440)。如果对链接地址理解错误的话,可能会出现像我这样的问题。 Q:gboot的链接器脚本里写的其实链接地址是内存中的0x30008000,再用交叉工具反汇编得到的start.S前几行代码地址都变成了0x30008000+,不太对啊。ARM启动流程里面讲处理器将NAND中的代码复制了4K到垫脚石中,垫脚石的地址是0x0,也正是因为这样,我们设置的异常向量表才有意义,处理器才能准确的找到处理异常的标号。但是把链接地址改成了0x30008000还怎么找? A:首先要理解链接地址。我认为,链接地址就是为程序假想了一个起点,之后的代码都是在这
[单片机]
TQQ2440第三节:串口
做嵌入式的基本上都清楚,板子基本上跑起来了,第一个肯定要配置的是串口,便于我们后面调试信息的输出,和一些系统参数的输出,让我们有更直观看见程序的运行。 ————————————————————————————————————————————— 硬件平台:TQ2440 (S3C2440A) 开发环境:ADS1.2 时 间:2010-12-12 ————————————————————————————————————————————— 1:硬件电路:                   底板电路                           核心板上的连接管脚 由于TQ2440的板子上只引出了一个串口,也就是用的
[单片机]
TQQ<font color='red'>2440</font>第三节:串口
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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