历史上的今天
返回首页

历史上的今天

今天是:2024年10月21日(星期一)

正在发生

2019年10月21日 | 2440 I2C存储卡读写实验 AT24c08a

2019-10-21 来源:51hei

本实验为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);

   }


推荐阅读

史海拾趣

FLEX LTD公司的发展小趣事

Flex Ltd.(伟创力国际有限公司),作为全球知名的电子制造服务(EMS)供应商,自1969年在美国硅谷成立以来,经历了多个关键的发展阶段和故事。以下是五个与其发展紧密相关的事实性故事:

1. 全球布局的开端:新加坡建厂

1981年,Flex Ltd.在新加坡建立了其第一个海外工厂,这一举措标志着公司正式走出美国,开启了全球化布局的序幕。新加坡工厂的建立不仅为Flex带来了更低的制造成本,还使其能够更贴近亚洲市场,为客户提供更快捷的服务。这一战略性的地理选择为Flex后续在全球范围内的扩张奠定了坚实基础。

2. 纳入纳斯达克上市

随着业务的不断扩展和实力的增强,Flex Ltd.于某年成功在纳斯达克(NASDAQ)上市。这一里程碑事件不仅为公司筹集了更多的发展资金,还极大地提升了其在国际市场上的知名度和影响力。上市后的Flex更加注重财务透明度和公司治理,为股东创造了长期价值。

3. 与华为的合作与风波

Flex与华为的合作曾是业内的佳话。特别是在2018年,Flex承接了华为价值高达25亿美元的代工订单,这一合作极大地推动了Flex的业务增长。然而,随着2019年美国商务部将华为列入“实体清单”,Flex被迫在全球范围内停止与华为的合作,并扣押了华为的物资和设备。这一事件引发了广泛争议,对Flex的声誉和客户关系造成了一定影响。尽管后续双方进行了多轮谈判,但这一风波仍成为了Flex发展历程中一个不可忽视的章节。

4. 供应链的数字化转型

Flex一直致力于通过数字化转型来提高供应链的效率和透明度。公司发起了一项全球计划,旨在通过EDI(电子数据交换)等先进技术实现采购及付款交易的完全自动化。这一举措不仅降低了成本、减少了错误,还提高了供应链的响应能力和可见性。例如,Flex与D公司的EDI项目合作就是其数字化转型的一个成功案例,展示了Flex在推动供应链自动化方面的决心和实力。

5. 环保与社会责任

Flex在快速发展的同时,也积极履行其环保和社会责任。公司遵循欧盟的RoHS和WEEE等环保指令,致力于在电子产品设计和制造过程中减少有害物质的使用,并推动电子废弃物的回收和处理。此外,Flex还通过专项拨款、财务捐助、自愿者行动等多种形式加大对全球社会的支援和投入力度,关注灾难赈济、医疗援助、教育、环保等领域。这些举措不仅提升了Flex的企业形象,也为其可持续发展奠定了坚实的基础。

Elektron公司的发展小趣事

随着技术的不断进步和市场需求的不断变化,Elektron公司不断进行技术创新和产品升级。公司成功开发出适用于船上使用的单点和多点焊接整流器以及弧光灯的电影整流器等产品,进一步扩大了市场份额。同时,Elektron还注重产品质量和性能的提升,通过引进先进的生产设备和工艺,不断提高产品的可靠性和耐用性。

Embedded Artists公司的发展小趣事

在业务迅速发展的同时,Embedded Artists公司也始终关注环境保护和可持续发展。他们致力于采用环保材料和节能技术来生产产品,并通过优化生产流程来降低能源消耗和废物排放。此外,公司还积极参与公益活动,支持环保组织和项目。这些举措不仅提高了公司的社会形象,也为公司的长期发展奠定了坚实基础。

冠西电子(COSMO)公司的发展小趣事

近年来,冠西电子积极布局全球市场,设立了多个分公司和办事处,以便更好地服务全球客户。同时,冠西电子还不断关注新兴技术和市场需求的变化,积极寻求新的发展机遇。展望未来,冠西电子将继续秉承“专业、创新、品质、服务”的理念,不断推动公司业务的发展和进步。

以上五个故事概要涵盖了冠西电子(COSMO)公司从创立到发展的主要阶段和事实。每个阶段都体现了冠西电子在技术、市场、品质、品牌等方面的努力和成就。

GC Electronics公司的发展小趣事
如发现传感器、报警装置或电路中的其他部件损坏,应及时更换,以确保报警电路的可靠性。
ABI Electronics公司的发展小趣事

随着业务的不断发展和产品的不断升级,ABI Electronics公司的品牌影响力也逐渐提升。其产品在市场上获得了良好的口碑和声誉,成为了电子行业内的知名品牌。同时,ABI还积极参与行业内的交流和合作,为行业的发展做出了积极的贡献,进一步提升了其在行业内的地位和影响力。

这五个故事展示了ABI Electronics公司在电子行业里的发展历程,从电路板测试技术的突破,到集成电路测试技术的创新,再到全球市场布局和合作伙伴关系的建立,以及研发实力的持续增强和品牌影响力的提升,都体现了ABI Electronics公司不断进取、不断创新的精神。

问答坊 | AI 解惑

一个有关复位的问题

本人做的一个串口接收的测试程序,上机位使用串口调试助手,        由于下载程序口和串口通信用的同是COM2,所以在刚下载完程序的时候,有些乱码造成ED灯点亮,这是正常的,但本人复位以后,重新发数据点亮LED灯却没有任何反应;不进 ...…

查看全部问答>

提高开关电源功率因数的设计

提高开关电源功率因数的设计…

查看全部问答>

s3c6410的power-saving mode

      6410的板子做出来了,可是发现了一些问题,尤其是挂起下的电流消耗比较大。大概能有55ma。头说还比较大。也是,因为XGPWRTON引脚没有连接在电源芯片的使能管教。所以在sleep模式下,核电压和模块电压都存在。不知道是不 ...…

查看全部问答>

求教:PB samples编译问题

%WINCEroot%\\PUBLIC\\COMMON\\SDK\\SAMPLES\\SCWCSP 下的代码 在命令行下执行build以后,生成debug目录下生成.obj,.mac等文件 没有可执行程序,请问各位大侠应该怎么办,谢谢…

查看全部问答>

求助:花了几千大元参加了SMT工程师认证课程和考试不知道值不值?

刚刚加入SMT行业没多久,朋友一直要我和他一起报名了深圳NEPCON展会的SMT工程师认证课程,而且还要花上几千大元的费用,可是不知道这个证书对我以后的职业规划有没有帮助!请各位前辈给指引一下,谢谢!…

查看全部问答>

GSM教你使用PlanAhead进行 I/O Pin Planning

兄弟姐妹们对使用PlanAhead有很多抵触,其实是不了解PlanAhead强大功能,现在就想和大家一起分享Xilinx的PlanAhead的I/O Pin Planning教程使用的工具: ISE 13.2 XILINX 开发板 SP605 实验材料为UART_LED的材料教程的目的 教会大 ...…

查看全部问答>

lm3S系类RESET引脚可否经受5V电压?

因为板子上有一些5V的芯片需要上电复位,所以就用了一片MAX705,想把MAX705的复位输出端直接接到LM3S的reset引脚上,但是,当MAX705完成复位后会变成高电平,这样就相当于在LM3S复位引脚上加了一个5V电压,不知道这样用会不会有问题。 还有就是有 ...…

查看全部问答>

DDR2布线规则

叠层设置:1、 对于同一组数据线及其对应的DQ STROBE线,如DQ[7:0]、DM0与DQS0、DQS0#,应布在同一层,以减小信号skew。2、 DDR2信号线的参考平面最好是选择地平面(尤其是时钟线),如果基于成本考虑,不得不选用电源层作为参考面,则DDR2供电电 ...…

查看全部问答>