IIC之AT24C256的读写程序

发布者:春水碧于天最新更新时间:2019-05-21 来源: eefocus关键字:IIC  AT24C256  读写程序 手机看文章 扫描二维码
随时随地手机看文章

一个通用的24C01-24C256共9种EEPROM的字节读写操作程序,此程序有五个入口条件,分别为读写数据缓冲区指针,进行读写的字节数,EEPROM首址,EEPROM控制字节,以及EEPROM类型。此程序结构性良好,具有极好的容错性,程序机器码也不多:DataBuff为读写数据输入/输出缓冲区的首址Length 为要读写数据的字节数量Addr 为EEPROM的片内地址 AT24256为0~32767Control 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;enumer为枚举变量,需为AT2401至AT24256中的一种,分别对应AT24C01至AT24C256;函数返回值为一个位变量,若返回1表示此次操作失效,0表示操作成功;ERROR为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1。SDA和SCL由用户自定义,对于1K位,2K位,4K位,8K位,16K位芯片采用一个8位长的字节地址码,对于32K位以上的采用2个8位长的字节地址码直接寻址,而4K位,8K位,16K位配合页面地址来寻址。


 


#include

#define  ERROR 10     //允许ERROR的最大次数  

 

     

sbit     SDA=P4^2;

sbit     SCL=P4^4;

 

enum  eepromtype {AT2401,AT2402,AT2404,AT2408,AT2416,AT2432,AT2464,AT24128,AT24256};/*器件的型号*/

enum  eepromtype enumer;   //定义一个枚举变量

unsigned char buf1[]="aaaaaaaaaa"; /* 发送缓冲区 */

unsigned char buf2 [12]; /* 接收缓冲区 */

 

void senddd(unsigned d1);

/* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */

void Delay(unsigned char DelayCount)

{ while(DelayCount--);

}

/* * * * * 以下是对IIC总线的操作子程序 * * * * */

/* * * * * * 启动总线 * * * * */

void Start(void)

{ SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */

  SDA=1; /* 一个"开始"状态,该状态必须在其他命令之前执行 */

  Delay(1);

  SCL=1;

  Delay(1);

  SDA=0;

  Delay(1);

  SCL=0;

  SDA=1;

  Delay(1);     

}

 

 

 

/* * * * * 停止IIC总线 * * * * */

void Stop(void)

{ SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */

  SDA=0; /*表示一个"停止"状态,该状态终止所有通讯 */

  Delay(1);

  SCL=1;

  Delay(1); /* 空操作 */

  SDA=1;

  Delay(1);

  SCL=0;

  Delay(1000);

}

 

 

/* * * * * 检查应答位 * * * * */

bit RecAck(void)

{ SCL=0;

  SDA=1;

  Delay(20);

  SCL=1;

  Delay(1);

  Delay(1);

  CY=SDA;     /* 因为返回值总是放在CY中的 */

  SCL=0;

  Delay(20);

  return(CY);

}

 

 

/* * * * *对IIC总线产生应答 * * * * */

void Ack(void)

{ SDA=0; /* EEPROM通过在收到每个地址或数据之后, */

  SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */

  Delay(1);

  SCL=0;

  Delay(1);

  SDA=1;

}

 

 

/* * * * * * * * * 不对IIC总线产生应答 * * * * */

void NoAck(void)

{ SDA=1;

  SCL=1;

  Delay(1);

  SCL=0;

}

 

/* * * * * * * * * 向IIC总线写数据 * * * * */

void Send(unsigned char sendbyte)

{ unsigned char data j=8;

  for(;j>0;j--)

  { SCL=0;

    sendbyte <<= 1; /* 使CY=sendbyte^7; */

    SDA=CY; /* CY 进位标志位 */

Delay(1);

    SCL=1;

Delay(20);

  }

  SCL=0;

  Delay(1);

}

 

/* * * * * * * * * 从IIC总线上读数据子程序 * * * * */

unsigned char Receive(void)

{ register receivebyte,i=8;

  SCL=0;

  while(i--)

  { SCL=1;

    receivebyte = (receivebyte <<1 ) | SDA;

Delay(1);

    SCL=0;

Delay(1);

  }

  return(receivebyte);

}

 

/* -----  AT24C01~AT24C256 的读写程序 ------ */

bit   RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr,

                     unsigned char Control,enum eepromtype enumer)

 

  unsigned char data j,i=ERROR;

  bit errorflag=1;  /*   出错标志   */

  while(i--)

  { Start();  /*   启动总线   */

    Send(Control & 0xfe); /*   向IIC总线写数据,器件地址 */

    if(RecAck()) continue; /*   如写不正确结束本次循环   */

    if(enumer > AT2416)

    { Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.如果容量大于32K位,使用16位地址寻址,写入高八位地址

      if(RecAck())  continue;

    }

    Send((unsigned char)Addr); /*   向IIC总线写数据   */

    if(RecAck())  continue; /*   如写正确结束本次循环   */

    if(!(Control & 0x01))   //判断是读器件还是写器件

    { j=Length;

      errorflag=0;         /* 清错误特征位 */

      while(j--)

      { Send(*DataBuff++); /*   向IIC总线写数据   */

        if(!RecAck()) continue; /*   如写正确结束本次循环   */

        errorflag=1;

        break;

      }

      if(errorflag==1) continue;

      break;

    }

    else

    { Start();  /*   启动总线   */

      Send(Control); /*   向IIC总线写数据   */

      if(RecAck()) continue;//器件没应答结束本次本层循环

      while(--Length)  /*   字节长为0结束   */

      { *DataBuff ++= Receive();

        Ack();   /*   对IIC总线产生应答   */

      }

      *DataBuff=Receive(); /* 读最后一个字节 */

      NoAck();  /*   不对IIC总线产生应答   */

      errorflag=0;

      break;

    }

  }

  Stop();  /*   停止IIC总线   */

  if(!(Control & 0x01))

  { 

  Delay(255); 

  Delay(255); 

  Delay(255);

  }

  return(errorflag);

}


下面是主函数:


 


#include

#include "24c256_1.h"

#include

 

unsigned char temp[64];

unsigned char rxnum;

unsigned char flag2;

 

void senddd(unsigned d1);

 

 

void uart(void) interrupt 4// 串口中断

{

unsigned char k = 0;

if(RI) //接收

{

 

}

else //发送

{

TI=0;

}

 

//查询方式发送单个字符

void senddd(unsigned d1)

ES=0; 

//TE=1;

TI=0;SBUF=d1;while(!TI);

//TE=0;

TI=0; ES=1; 

}

 

 

//Send String Tor Uart

void printu(char * str)

{

    char *ct = str;

 

while (*ct != '')

{

if (*ct == 'n')

{

SBUF = 13;

while (!TI);

TI = 0;

}

SBUF=*ct;

while (!TI);

TI = 0;

ct++;

}

}

//UART初始化

void initUart(void)

{

TMOD &=0x0f; TMOD |=0x20; SCON=0x50; IP = 0x10;

//PCON|=0x80;

TH1=0xf7; TL1=0xf7; //115200,normal

//TH1=0xfa; TL1=0xfa; //倍速 

TR1=1; ET1=0; RI=0; 

//AUXR = 0xA0;

//TE=0; //允许接收 仅485时用。

}

 

void main(void)

{

  unsigned char Control,*p1,*p2;

  unsigned char Length;

  unsigned int addr ,i; /* 24Cxx片内地址 */

    P4SW|= 0x10;

  initUart();

ES =1;

ET1=0;

EA =1;

senddd('O');

senddd('N');  

    printu(" starting...rn");

 

  p1=buf1;p2=buf2;

  printu(p1);    

  printu("rn"); 

 

  addr=0; ////片内地址 AT24C256为0~32767/////

  Length=10; ////// 读写长度 //////

  enumer=AT24256; /// 读写AT24C256////

 

  Control=0xa0; /// 写操作///

  RW24xx(p1,Length,addr,Control,enumer); // 写 //

  Control=0xa1; ///读操作///

  for(i=0;i<10000;i++);    //要加入延时···才可正确的读取数据!  

  // Delay(1000);//1:6.18us; 2:8.36us 3:10.55us △=2.18us

  RW24xx(p2,Length,addr,Control,enumer);// 读 

 

  printu(p2);

  printu("rn");

 

}


下面是运行结果:

关键字:IIC  AT24C256  读写程序 引用地址:IIC之AT24C256的读写程序

上一篇:单片机之UIP--TCP 校验和计算
下一篇:单片机之UIP--TCP作为服务器,主动发送数据 ACK

推荐阅读最新更新时间:2024-11-11 19:27

STM32—基于模拟IIC方式读取EEPROM
前言: 最近在调试STM32L152芯片利用IIC接口读取EEPROM的程序,总结下STM32的 IIC接口 读取EEPROM的使用方法。 PS:由于STM32的硬件IIC存在一些问题,本文暂时使用模拟IIC进行EEPROM的读取。STM32的硬件IIC使用方法见另外两篇文章:传送门1和传送门2。 硬件平台:STM32L152 软件平台:keil v5+cubeMX 函数库:HAL函数库 1:配置iic引脚,本例对应PC2和PC3管脚,移植修改对应管脚。 #define I2C_SCL GPIO_PIN_2 //PC2 #define I2C_SDA GPIO_PIN_3 //PC3 #de
[单片机]
单片机模拟IIC总线与EEPROM进行数据通信
#include reg52.h #define uchar unsigned char sbit sda=P2^0; sbit scl=P2^1; uchar a; void delay() { ;; } void start() //开始信号 { sda=1; delay(); scl=1; delay(); sda=0; delay(); } void stop() //停止 { sda=0; delay(); scl=1; delay(); sda=1; delay(); } void respons() //应答 { uchar i; scl=1; delay(); whil
[单片机]
s3c2440的IIC控制
在tq2440和mini2440上都连接着EEPROM 它们作用也不过測试I2C总线能否用。 当中在mini2440上EEPROM型号是 AT24C08,在tq2440上这个型号是 AT24C02A。 它们之间容量不同。地址线也不一样。 S3C2440A RISC 微处理器能够支持一个多主控 IIC 总线串行接口。一条串行数据线(SDA)和一条专用时钟线(SCL) 连接到 IIC 总线的总线主控和外设之间。SDA 和 SCL 线都为双向的。都连接到GPE14(SCL) GPE15(SDA)。 为了控制多主控 IIC 总线操作,必须写入值到下面寄存器中: – 多主控 IIC 总线控制寄存器,IICCON – 多主控
[单片机]
s3c2440的<font color='red'>IIC</font>控制
S3C2440IIC中断方式
#include string.h #include 2440addr.h #include 2440lib.h #include Option.h #include def.h int flag; //中断标志(在中断子程序里清零,即未中断flag=1,中断后flag=0) void __irq IicInt(void); void Wr24C02(U32 slvAddr,U32 addr,U8 data); void Rd24C02(U32 slvAddr,U32 addr,U8 *data); void Main(void) { unsigned in
[单片机]
N76E003 IIC OLED
#include N76E003.h #include Common.h #include Delay.h #include SFR_Macro.h #include Function_define.h #include math.h #include oledfont.h #define u8 unsigned char #define u32 unsigned int /*SCL P1.3 SDA P1.4*/ #define OLED_SCLK_Clr() SCL=0 #define OLED_SCLK_Set() SCL=1 #define OLED_SDIN_Clr() SDA=0 #
[单片机]
N76E003 <font color='red'>IIC</font> OLED
51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码
I2C总线是Philips公司提出的一种集成电路IC器件之间相连接的总线协议,其目的是使电子系统(不只 限于单片机系统)各个IC器件之间的连线变得容易。因为使用传统的并行总线在IC器件之间连接,往往会使得IC之间连线较多,显得非常复杂。而I2C总线 则使IC器件之间只需SDA、SCL两条连线就可以传送数据,因而十分方便。由于I2C在印刷体中不容易书写(需要上标),所以实际书写时,还常见到 IIC、I2C等书写方法,本文采用IIC的写法,敬请注意。关于IIC总线的知识,请参阅相关书籍,此处不再做进一步介绍。 I2C总线是Philips公司提出的一种集成电路IC器件之间相连接的总线协议,其目的是使电子系统(不只 限于单片机系统)
[单片机]
51单片机普通IO口模拟<font color='red'>IIC</font>(I2C)接口通讯的程序代码
stm32专题十七:深度解析 stm32 硬件iic (i2c)
首先是配置I2C的GPIO,然后配置I2C参数。就是常规配置,按流程来写不会错。 /** * @brief EEPROM IIC 配置 */ void I2C_EE_config(void) { GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // 开启I2C GPIO时钟 EPROM_I2C_GPIO_APBxClkCmd(EEPROM_I2C_SCL_GPIO_CLK | EEPROM_I2C_SDA_GPIO_CLK, ENABLE); // 开启I2C 外设时钟 EEPROM_I2C_APBxC
[单片机]
stm32专题十七:深度解析 stm32 硬件<font color='red'>iic</font> (i2c)
IIC总线测试总结
一、信号完整性测试简要介绍 前一段时间在做板卡信号完整性测试。 信号完整性测试主要是对信号质量进行测试,观察信号电平是否满足门限,有无过冲、振荡、回沟,时序是否满足要求等。 由于在产品需求层面,是不会将信号质量作为一项需求提出,因此很多时候在归档的测试报告中只会存在功能测试报告,而是将信号完整性测试报告作为内部公开的一份参考资料,但这并不意味着我们可以减少对信号完整性测试的重视程度,因为信号完整性测试往往能够发现很多潜在的风险,比如自己在以前的测试中就遇到过低电平门限是0.8V,而测得的信号低电平也接近0.8V,虽然在功能上的验证是正常的,但这就是一项风险项,很有可能在量产上市后,随着长期运行或者环境改变
[测试测量]
<font color='red'>IIC</font>总线测试总结
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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