精华内容
下载资源
问答
  • AT24C1024读写程序

    2014-05-16 10:13:53
    AT24C1024读写程序,不完整只含有读写程序
  • AT24C02页写数据

    2015-11-22 16:32:53
    通过IIC读写AT24C02,百度上面有一大堆例程。但向AT24C02写一个字符串时,例程上基本上都是以页写的形式呈现。写入的方式只能满一,不能跨继续。本文档的函数可以实现跨页写数据。
  • AT24C02EEPROM读写

    2013-04-04 22:39:06
    AT24C02 IIC读写,自己测试通过。
  • at24c02读写驱动

    2011-09-13 14:05:05
    at24c02 基于at24c02的读写程序驱动文档
  • AT24C02读写程序

    2012-08-14 21:34:09
    AT24C02模块的读写程序例程。
  • 根据AT24C02的手册读写AT24C02

    千次阅读 2017-11-21 12:55:32
    1.从起始地址连续读出AT24C02中256个字节中的数据。采用的是Random read的时序读取的。 //连续读(Randem读的时序) AT24C04_Start(); //起始信号 AT24C04_SendByte(AT24_Address); //发送设备地址+信号 ack=...

    1.从起始地址连续读出AT24C02中256个字节中的数据。采用的是Random read的时序读取的。

     //连续读(Randem读的时序)

    AT24C04_Start();            //起始信号

     AT24C04_SendByte(AT24_Address);     //发送设备地址+写信号

    ack=check();

    AT24C04_SendByte(0x00);     //发送存储单元地址

    ack=check();

    AT24C04_Start();            //起始信号

    AT24C04_SendByte(AT24_Address+1);     //发送设备地址+读信号

    ack=check();

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

     {

       temp1[i]= AT24C04_RecvByte(); //自己创建的数组用来接收存储的数据

       if (i == 255)

       {

           AT24C04_SendACK(1);//最后一个数据需要回NAK

       }

       else

       {

          AT24C04_SendACK(0);//回应ACK

        } 

       }

      AT24C04_Stop();               //停止信号

    2.     用Byte Write时序把0xa0写入到0x01的地址中

    AT24C04_Start();                    //起始信号

    AT24C04_SendByte(AT24_Address);     //发送设备地址+写信号

    ack =check();

    AT24C04_SendByte(0x01);             //发送存储单元地址0x01

    ack=check();

    AT24C04_SendByte(0x0a);            //发送要写入的数据0x0a

    ack=check();

     AT24C04_Stop();

    3.用Page Write时序来写一页数据到AT24C02中,切记存储单元地址一定要是8的倍数

    AT24C04_Start();                    //起始信号

    AT24C04_SendByte(AT24_Address);     //发送设备地址+写信号

    ack=check();

    AT24C04_SendByte(0x18);                 //发送存储单元地址,0x18,换为10进制为24,也就是第4页的起始地址
     ack=check();
    for(i=0;i<8;i++)
    {
           AT24C04_SendByte(10);//写入一页,8个10
           ack=check();
     }

     AT24C04_Stop();

    4.用Current Address Read的时序来读,上次最后一个数据存在哪里,则从哪个地址的后一个地址开始读

    AT24C04_Start(); 

    AT24C04_SendByte(AT24_Address+1);

    ack=check();

    temp1[0]= AT24C04_RecvByte();

    AT24C04_SendACK(1);//最后一个数据需要回NAK

    5.用Sequential Read 时序从当前地址连续读256个数,如果当前地址不是从0开始则读不够256个

    AT24C04_Start();

    AT24C04_SendByte(AT24_Address+1);

    ack=check();

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

     {

      temp1[i]= AT24C04_RecvByte();

      if (i == 255)

      {

      AT24C04_SendACK(1);//最后一个数据需要回NAK

      }

      else

      {

         AT24C04_SendACK(0);//回应ACK

    }

    AT24C04_Stop();               //停止信号

    }

    6.附start(),stop(),ack(), check(),AT24C04_SendByte(),AT24C04_RecvByte()代码

     

    void AT24C04_Start()

    {

        SDA = 1;                    //拉高数据线

        SCL = 1;                    //拉高时钟线

        Delay5us();                 //延时

        SDA = 0;                    //产生下降沿

        Delay5us();                 //延时

        SCL = 0;                    //拉低时钟线

    }

     

    void AT24C04_Stop()

    {

        SDA = 0;                    //拉低数据线

        SCL = 1;                    //拉高时钟线

        Delay5us();                 //延时

        SDA = 1;                    //产生上升沿

        Delay5us();                 //延时

    }

     

    void AT24C04_SendACK(bit ack)

    {

        SDA = ack;                  //写应答信号

        SCL = 1;                    //拉高时钟线

        Delay5us();                 //延时

        SCL = 0;                    //拉低时钟线

        Delay5us();                 //延时

    }

     

    unsigned char check(void)

    {

    //    SDA =1; //释放SDA线

        SCL=1; //拉高时钟线

        Delay5us();//延时

      CY = SDA;//读应答信号

        SCL=0; //拉低时钟线

        Delay5us();   //延时

        return CY;

    }

     

    void AT24C04_SendByte(unsigned char dat)

    {

        unsigned char i;

     

        for (i=0; i<8; i++)         //8位计数器

        {

            dat <<= 1;              //移出数据的最高位

            SDA = CY;               //送数据口

            SCL = 1;                //拉高时钟线

            Delay5us();             //延时

            SCL = 0;                //拉低时钟线

            Delay5us();             //延时

        }

    }

     

    unsigned char AT24C04_RecvByte()

    {

        unsigned char i;

        unsigned char dat = 0;

     

        SDA = 1;                    //使能内部上拉,准备读取数据

        for (i=0; i<8; i++)         //8位计数器

        {

            dat <<= 1;

            SCL = 1;                //拉高时钟线

            Delay5us();             //延时

            dat |= SDA;             //读数据

            SCL = 0;                //拉低时钟线

            Delay5us();             //延时

        }

     

        return dat;

    }

    展开全文
  • 该程序是通过定时器0定时,每1s数码管显示数值加一(00-99),(从at24c02中读出然后数码管显示)数码管显示的数值会每隔1s往at24c02中保存一次。当复位时,数码管显示的数值仍然是你复位前的数值。
  • AT24C02的读写操作

    千次阅读 2020-05-09 22:40:46
    AT24C02的读写操作 **说明:**最近我在做基于EEPROM存储器24c02存储的电子锁时遇到了一些问题:每次向24C02写入数据的时候没出现什么问题,可以正常写入。但是每次读取24C02却总是出现错误。 通过查找网上的各种资料...

    AT24C02的读写操作

    **说明:**最近我在做基于EEPROM存储器24c02存储的电子锁时遇到了一些问题:每次向24C02写入数据的时候没出现什么问题,可以正常写入。但是每次读取24C02却总是出现错误。
    通过查找网上的各种资料,发现这个问题很多小伙伴都有遇到,但是楼下的评论不是说时序有问题就是说函数有问题,却没有具体的指出来到底哪里有问题。

    下面我就以我的I2C驱动24C02为例来说说我是如何解决24C02数据读取问题的。

    关于24c02的资料我觉得这篇博客写的比较详细,我这里就不花时间了(而且感觉我写的也没这篇博客写的好)

    https://blog.csdn.net/snyanglq/article/details/50408489?

    不懂的小伙伴可以康康。

    我主要讲讲我如何实现读取24c02的问题
    请看代码:

    # 原始代码
    void At24c02Read(unsigned char *b, unsigned char addr)
    {
    	unsigned char i;
    	I2C_Start_signal();
    	I2C_SendByte(0xa0, 1); //发送写器件地址	   1010   0000
    	I2C_SendByte(addr, 1); //发送要读取的地址
    	I2C_Start_signal();
    	I2C_SendByte(0xa1, 1); //发送读器件地址
    	for(i = 0; i < 8; i++)
    	{
    		*b = I2cReadByte();	 //读取数据
    		b++;	
    	}
    	
    	I2C_Stop_signal();
    }
    
    
    # 改进代码
    void At24c02Read(unsigned char b[], unsigned char addr)
    {
    	unsigned char i;
    	for(i = 0; i < 7; i++)
    	{
    		I2C_Start_signal();					//开始信号
    		I2C_SendByte(0xa0, 1); 		//发送写器件地址1010 0000
    		I2C_SendByte(addr + i, 1); 		//发送要读取的地址
    		I2C_Start_signal();
    		I2C_SendByte(0xa1, 1); 			//发送读器件地址
    		b[i] = I2cReadByte();	 		//读取数据
    		ACK();	
    	}
    	I2C_Start_signal();
    	I2C_SendByte(0xa0, 1); 			//发送写器件地址1010   0000
    	I2C_SendByte(addr + i, 1);			 //发送要读取的地址
    	I2C_Start_signal();
    	I2C_SendByte(0xa1, 1); 				//发送读器件地址
    	b[i] =  I2cReadByte();
    	NACK();
    	I2C_Stop_signal();
    	Delay10us();
    }
    

    与其他人的代码有些差异,我将这几行代码同时放入循环体内

    I2C_Start_signal();					//开始信号
    I2C_SendByte(0xa0, 1); 			//发送写器件地址	   1010   0000
    I2C_SendByte(addr + i, 1); 		//发送要读取的地址
    I2C_Start_signal();
    I2C_SendByte(0xa1, 1); 			//发送读器件地址
    

    理由是我发现当只发送读取地址的首地址时单片机内读取到的数据只有一个,如下图:
    **主意时钟频率设置为6MHZ**
    单片机内存中的FF数据为24c02中其他地址的,并不是连续读取。所以我用一个循环,每次读取都给定一个不同的地址,通过软件操作使得单片机从24C02中连续读取数据。按照改进的代码可以得到如下情况:
    在这里插入图片描述
    需要进行说明的是,这里我设置的系统时钟是6M左右,如果偏高会出现不能读取数据的情况。

    下面附上我的整个24c02的读写函数以及主函数代码:

    # 主函数
    #include <reg51.h>
    #include "I2C.h"
    
    void main()
    {
    	unsigned char a[8]={1,3,1,4,5,2,0,0};
    	unsigned char b[8];
    	At24c02Write(0x50, a);
    	Delay10us();
    	At24c02Read(b,0x50);
    	while(1);
    }
    
    I2C.H
    #ifndef __I2C_H
    #define __I2C_H
    #include <reg51.h>
     
    sbit SCL=P1^0;	   //时钟线
    sbit SDA=P1^1;	   //地址线
    
    /**********************************
    **	函数名称 :ACK
    **	函数功能 : 应答信号
    **********************************/
    void ACK();			//发送应答A子函数ACK
    
    
    
    /**********************************
    **	函数名称 :NACK
    **	函数功能 : 非应答信号
    **********************************/
    
    void NACK();
     
    /**
     * 函数: void At24c02Write(unsigned char addr,unsigned char dat);
     * 函数功能:AT24C02写数据.
     * 使用方法:用户想要往里写数据的话就调用本函数,传入地址和数据即可
     **/
    void At24c02Write(unsigned char addr,unsigned char dat[]); 
    /**
     * 函数: unsigned char At24c02Read(unsigned char addr);
     * 函数功能:AT24C02读数据.
     * 使用方法:用户想要读数据的话就调用本函数,传入地址即可
     **/
     
    void At24c02Read(unsigned char b[], unsigned char addr);
    //unsigned char At24c02Read(unsigned char addr);
     
    /**
     * 函数: void I2C_Start_signal(void);
     * 函数功能:I2C总线的起始信号
     **/
     
    void I2C_Start_signal(void);
     
    /**
     * 函数: void I2C_Stop_signal(void);
     * 函数功能:I2C总线的结束信号
     **/
     
    void I2C_Stop_signal(void);
     
    /**
     * 函数: unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);
     * 函数功能:I2C总线的写数据
     **/
     
    unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);
     
    /**
     * 函数: unsigned char I2cReadByte();
     * 函数功能:I2C总线的读数据
     **/
    unsigned char I2cReadByte();
     
    /**
     * 函数: void Delay10us();
     * 函数功能:10us延时
     **/
     
    void Delay10us();
     
     
    #endif
    
    
    # I2C.c
    #include "i2c.h"
    
    
    /**********************************
    **	函数名称 :ACK
    **	函数功能 : 应答信号
    **********************************/
    void ACK()			//发送应答A子函数ACK
    {
    	unsigned char i;
    	SCL = 1;		//时钟线发出时钟脉冲
    	Delay10us();
    	while((SDA == 1) && (i < 200))i++ ;
    	SCL = 0;		//与SCL=1组成时钟脉冲
    	Delay10us();
    }
    /**********************************
    **	函数名称 :NACK
    **	函数功能 : 非应答信号
    **********************************/
    void NACK()			//发送应答A子函数NACK,见实例354
    {
    
    	SDA = 1;		//数据线高电平(发送数据1)
    	SCL = 0;
    	Delay10us();
    	SCL = 1;		//时钟线发出时钟脉冲
    	Delay10us();
    	SCL = 0;		//与SCL=1组成时钟脉冲
    	SDA = 0;		//数据线低电平复位
    }
     
    /*******************************************************************************
    * 函数名         : Start_signal(void)
    * 函数功能		 : I2C总线起始信号
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
     
    void I2C_Start_signal(void)
    {
    	 SDA = 1 ;
    	 Delay10us();
    	 SCL = 1 ;
    	 Delay10us();
    	 SDA = 0 ;
    	 Delay10us();
    	 SCL = 0 ;
    	 Delay10us();
    }
     
    /*******************************************************************************
    * 函数名         : Start_signal(void)
    * 函数功能		 : I2C总线终止信号
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
     
    void I2C_Stop_signal(void)
    {
    	SDA = 0 ;
    	Delay10us();
       	SCL = 1 ;
    	Delay10us();
    	Delay10us();
    	SDA=1;
    	Delay10us();
    }
     
    /*******************************************************************************
    * 函数名         : I2C_SendByte(unsigned char dat, unsigned char ack)
    * 函数功能		 : I2C总线发送数据
    * 输入           : dat,一个字节的数据
    * 输出         	 : 发送成功返回1,发送失败返回0
    * 备    注       : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
    *******************************************************************************/
     
    unsigned char I2C_SendByte(unsigned char dat, unsigned char ack)
    {
     
     
     
    	unsigned char a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
    Replay:
        b = 0 ;			
    	for(a=0; a<8; a++)//要发送8位,从最高位开始
    	{
    		SDA = dat >> 7;	 //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
    		dat = dat << 1;
    		Delay10us();
    		SCL = 1;
    		Delay10us();//建立时间>4.7us
    		SCL = 0;
    		Delay10us();//时间大于4us		
    	}
     
    	SDA = 1;
    	Delay10us();
    	SCL = 1;
    	while(SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
    	{
    		b++;
    		if(b > 200)	 //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
    		{
    			SCL = 0;
    			Delay10us();
    		//	return 0;
    			goto Replay ;   //如果超过200us没有应答则发送失败,或者为非应答,这时候系统启动重发机制
    							//使用goto语句返回到上面接着发
    		}
    	}
     
    	SCL = 0;
    	Delay10us();
     	return 1;		
    }
     
    /*******************************************************************************
    * 函数名         : I2cReadByte()
    * 函数功能		 : I2C总线接收数据
    * 输入           : 无
    * 输出         	 : dat,数据
    *******************************************************************************/
     
    unsigned char I2cReadByte()
    {
    	unsigned char a=0,dat=0;
    	SDA=1;			
    	Delay10us();
    	for(a=0;a<8;a++)//接收8个字节
    	{
    		SCL=1;
    		Delay10us();
    		dat<<=1;
    		dat|=SDA;
    		Delay10us();
    		SCL=0;
    		Delay10us();
    	}
    	return dat;	
    }
     
    /*******************************************************************************
    * 函数名         : Delay10us()
    * 函数功能		 : 延时
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
     
    void Delay10us()
    {
       unsigned char a,b;
    	for(b=1;b>0;b--)
    		for(a=2;a>0;a--);
    }
     
    /*******************************************************************************
    * 函 数 名         : void At24c02Write(unsigned char addr,unsigned char dat)
    * 函数功能		   : 往24c02的8个地址写入8个数据
    * 输    入         : 地址和数据
    * 输    出         : 无
    *******************************************************************************/
     
    void At24c02Write(unsigned char addr,unsigned char dat[])
    {
    	unsigned char i;
       	I2C_Start_signal();
    	I2C_SendByte(0xa0, 1);//发送写器件地址
    	I2C_SendByte(addr, 1);//发送要写入内存地址
    	for(i = 0; i < 8; i++)
    		I2C_SendByte(dat[i], 0);	//发送数据
    	I2C_Stop_signal();
     
    }
     
    /*******************************************************************************
    * 函 数 名         : unsigned char At24c02Read(unsigned char addr)
    * 函数功能		   : 读取24c02的一个地址的一个数据
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    
    void At24c02Read(unsigned char b[], unsigned char addr)
    {
    	unsigned char i;
    	for(i = 0; i < 7; i++)
    	{
    		I2C_Start_signal();
    		I2C_SendByte(0xa0, 1); 			//发送写器件地址	   1010   0000
    		I2C_SendByte(addr + i, 1); 		//发送要读取的地址
    		I2C_Start_signal();
    		I2C_SendByte(0xa1, 1); 			//发送读器件地址
    		b[i] = I2cReadByte();	 		//读取数据
    		ACK();	
    	}
    	I2C_Start_signal();
    	I2C_SendByte(0xa0, 1); 				//发送写器件地址	   1010   0000
    	I2C_SendByte(addr + i, 1);			 //发送要读取的地址
    	I2C_Start_signal();
    	I2C_SendByte(0xa1, 1); 				//发送读器件地址
    	b[i] =  I2cReadByte();
    	NACK();
    	I2C_Stop_signal();
    	Delay10us();
    }
     
    

    可能代码有些冗余,不过通过以上代码实现读写是没问题的。

    以上是我个人的一点体会,希望对大家有所帮助。

    展开全文
  • 对I2C总线上挂接多个AT24C02的读写操作
  • RAM 62256 和 ROM AT24C02 C51读写 C程序 包中包含 仿真图 和 程序源码 程序实现功能简单明了 代码很容易看懂 帮助有需要的朋友快速上手
  • bit write byte uchar date 一字节 将 date 写入AT24C02 中 uchar read byte 读一字节 从 AT24C02 中读一字节 bit busy 应答查询 stop 后 启动AT24C02内部周期 启动查询 初始化EEPROM子程序内容为0XFF nPage 0 ...
  • AT24C02B读写程序

    2011-07-25 14:52:06
    IIC 24C02读写数据,并在1602上显示读出来的数据
  • AT24C01~AT24C256通用读写程序(C51),为AT24C01~AT24C256的读写程序,各人可根据自己的需要应用。 在buf1中填入需要写入的内容,buf2的大小可根据需要定义。 addr可根据使用的芯片选择,可从任何位置读写,只要在...
  • 这是基于STM32设计的AT24C02与AT24C08_EEPROM存储芯片驱动代码,包含了IIC模拟时序、IIC硬件时序两种方式驱动。 包含了AT24C02、AT24C08两款芯片的代码。
  • IIC及AT24C02的读写(单片机实验)

    千次阅读 2020-07-21 14:29:59
    IIC及AT24C02的读写(单片机实验) 有问题欢迎私信哦 课程设计(综合实验)内容及要求 通过IIC总线扩展1片AT24C02芯片 ,实现单片机对存储器24C02 的读写,并通过LED灯或8段数码管显示存储单元的状态。进行软件仿真,...

    IIC及AT24C02的读写(单片机实验)

    有问题欢迎私信哦

    课程设计(综合实验)内容及要求
    通过IIC总线扩展1片AT24C02芯片 ,实现单片机对存储器24C02 的读写,并通过LED灯或8段数码管显示存储单元的状态。进行软件仿真,实验仪实现或焊接制作具体实物。

    目录
    1 项目分析 1
    1.1 设计内容 1
    1.1.1 设计任务 1
    1.1.2 设计要求 1
    1.2 总体设计 1
    2 硬件设计 2
    2.1 器件选型 2
    2.1.1 单片机芯片的选择方案和论证  2
    2.1.2 显示模块选择方案和论证 2
    2.1.3 扩展芯片的选择方案和论证 3
    2.1.4 独立按键的选择方案和论证 3
    2.2 器件设计 4
    2.2.1 IIC总线接口电路模块设计 4
    2.2.2 单片机主控制模块设计 8
    2.2.3 复位电路模块设计 10
    2.2.4 显示模块设计 10
    2.2.5 按键控制模块设计 11
    2.3 硬件调试 11
    3 软件设计 12
    3.1 代码设计 12
    3.2 仿真实现 16
    4 系统调试总结分析 18
    4.1 电路调试 18
    4.2 软件调试 18
    4.3 综合调试 18
    4.4 故障分析与解决方案 18
    4.5 总结与经验 18

    1 项目分析
    1.1 设计内容
    1.1.1 设计任务
    通过IIC总线扩展1片AT24C02芯片,实现单片机对存储器24C02的读写,并通过LED灯或8段数码管显示存储单元的状态。
    1.1.2 设计要求
    1.具有对存储器24C02 的读写功能;
    2.具备num++、保存、清零、读取功能;
    3.设置按键控制num++、保存、清零、读取功能;
    4.设置显示模块可以直观的看到操作显示;
    5.使用Protues软件进行电路设计并仿真;
    6.按照仿真设计实物;
    1.2 总体设计
    方案说明:
    此系统利用AT89C51单片机和芯片AT24C02设计完成。利用按键输入读写命令和相应的地址、数据,对AT24C02芯片进行读写操作,与单片机进行数据交换;8段数码管显示器作为显示部分;独立键盘实现多种操作。
    系统结构如图1-1所示
    在这里插入图片描述
    2 硬件设计
    2.1 器件选型

    2.1.1 单片机芯片的选择方案和论证

    采用AT89C51芯片作为硬件核心,AT89C51是美国ATMEL公司生产的一种高性能、低功耗、带4kFlashMemory的8位CMOS单片微型计算机芯片。FlashMemory又称闪烁存储器,它是EPROM和EEPROM技术有机结合的产物。其既具有EPROM一样的可编程能力,又带有像EEPROM的电可擦除性能,而且还具有不挥发性、反访问速度快(约60ns)和密度高等特点。由于以上优点使AT89C51可靠性高、实时性好、速度快、系统掉电后重要数据和状态信息不会丢失,其性能价格远高于同类芯片。它与MCS-51指令系统兼容,片内FPEROM允许对程序存储器在线重复编程,也可用常规的EPROM编程器编程,可循环写入或擦除1000次。一般的EEPROM的字节擦除时间和写入时间基本上均为10ms,对于任意实时控制系统来说,这样长的时间是不可能在线修改程序的。与EEPROM相比较,FPEROM大大缩短了存储内容擦除和写入的时间,为在线改写程序提供了极大的方便。

    2.1.2 显示模块选择方案和论证
    采用LED灯作为显示模块,虽然通过灯的颜色可以判断,但是不能读取具体的数据,并且实物焊接电路复杂,通过数码管显示模块,不仅可以知道是否读取,而且还可以直观地读取具体的数据,也为电路的设计带来了方便。

    本实验选择采用数码管显示模块。
    LED数码管简介:
    LED(Light Emitting Diode),发光二极管,是一种固态的半导体器件,它可以直接把电转化为光。LED的心脏是一个半导体的晶片,晶片的一端附在一个支架上,一端是负极,另一端连接电源的正极,使整个晶片被环氧树脂封装起来。半导体晶片由两部分组成,一部分是P型半导体,在它里面空穴占主导地位,另一端是N型半导体,在这边主要是电子。但这两种半导体连接起来的时候,它们之间就形成一个“P-N结”。

    当电流通过导线作用于这个晶片的时候,电子就会被推向P区,在P区里电子跟空穴复合,然后就会以光子的形式发出能量,这就是LED发光的原理。而光的波长也就是光的颜色,是由形成P-N结的材料决定的。除半导体激光器外,当电流激励时能发射光学辐射的半导体二极管。严格地讲,术语LED应该仅应用于发射可见光的二极管;发射近红外辐射的二极管叫红外发光二极管(IRED,Infrared Emitting Diode);发射峰值波长在可见光短波限附近,由部份紫外辐射的二极管称为紫外发光二极管;但是习惯上把上述三种半导体二极管统称为发光二极管。

    LED七段数码管的结构:
    LED七段数码管,如图2-1-2所示,是由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。LED数码管常用的段数一般为7段,有的另加一个小数点 。LED数码管根据LED的接法不同,分为共阴和共阳两类 。
    共阴极结构,是8段发光二极管的阴极端连接在一起,阳极端分开控制,使用时公共端接地,要使哪根发光二极管,则对应的阳极端接高电平。共阳极结构,是8段发光二极管的阳极端连接在一起,阴极端分开控制,使用时公共端接电源。要使哪根发光二极管,则对应的阴极端接地。
    在这里插入图片描述
    图2-1 LED数码管结构图

    其中7段发光二极管构成7笔的字形“8”,1根发光二极管构成小数点。从a-g引脚输入不同的8位二进制编码,可显示不同的数字或字符。通常把控制发光二极管的7(或8)位二极管编制称为字段码。不同数字或字符其字段码不一样,对于同一个数字或字符,共阴极连接和共阳极连接的字段码也不一样,共阴极和共阳极的字段码互为反码。

    2.1.3 扩展芯片的选择方案和论证
    AT24C02是带有IIC总线接口的EEPROM存储器,具有掉电记忆的功能,并且可以像普通RAM一样用程序改写。它是一个2k位串行CMOS E2PROM,内部含有256个8位字节,有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能 。

    2.1.4 独立按键的选择方案和论证
    独立按键主要是指轻触式按键开关,也称之为轻触开关。独立按键是一种电子开关,属于电子元器件类,使用时以满足操作力的条件向开关操作方向施压开关功能闭合接通,当撤销压力时开关即断开,其内部结构是靠金属弹片受力变化来实现通断的。

    独立按键的软件常采用查询式结构,先逐位查询没跟I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。

    独立键盘的按键相互独立,每个按键接一根I/O口线,一根I/O口线上的按键工作状态不会影响其它I/O口线的工作状态(引脚图如图2-2所示)。因此,通过检测I/O口线的电平状态,即可判断键盘上哪个键被按下,每次只处理一个按键,期间对任何按键的操作对系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序,准确输出按键值(或键号),满足跳转指令要求。本次实验中,单片机控制系统,只需要几个功能键,此时,可采用独立式按键结构,矩阵键盘编程复杂。
    在这里插入图片描述
    图2-2 独立按键引脚图

    2.2 器件设计
    2.2.1 IIC总线接口电路模块设计
    2.2.1.1 IIC 总线协议
    IIC 总线的两根通信线,一根是串行数据线SDA,另一根是串行时钟线SCL。多个符合IIC总线标准的器件都可以通过同一条IIC总线进行通信,而不需要额外的地址译码器。每个连接到总线上的器件都有一个唯一的地址作为识别的标志,都可以发送或接收数据。IIC 总线通信速率受主机控制,标准模式下可达100kbit/s。
    一般具有IIC总线的器件其SDA、SCL引脚都为集电极(或漏极)开路结构。因此实际使用时,SDA和SCL信号线必须加3-10K的上拉电阻。总线空闲时均保持高平。IIC总线接法如图2-3所示。

    图2-3 IIC总线连接示意图

    (1) IIC的主机和从机,发送器和接收器
    产生IIC总线时钟信号和起始、停止控制信号的器件,称为主机,被主机寻址的器件称为从机。
    任何将数据传送到IIC总线的器件称为发送器,任何从IIC总线接收数据的器件称为接收器。
    主机和从机都可作为发送数据器件和接收数据器件。

    (2) IIC 总线上数据的有效性:
    时钟线SCL为高电平时,数据线SDA的任何电平变化将被看作总线的起始或停止信号;
    在数据传送过程中,当时钟线SCL为高电平时,数据线SDA必须保持稳定状态,不允许有跳变;数据线SDA的状态只能在SCL低电平期间才能改变。即进行串行传送数据时,在SCL高电平期间传送位数据,低电平期间准备数据。

    (3) 从机地址
    IIC总线不需要额外的片选信号或地址译码。多个IIC总线接口器件可连接到一条IIC总线上,它们之间通过地址来区分。主机是主控制器件,只有一个主机的不需要地址。其它器件均为从机,均有器件地址,但必须保证同一条IIC总线上的器件地址不能重复。一般从机地址由7位地址位和1位读写位组成,地址位为高7位,读写位为最低位。读写位为0时,表示主机将向从机写入数据;读写位为1时,表示主机将要从从机读取数据。

    (4) IIC 总线的通信时序
    IIC 总线的通信时序如图2-4所示。

    图2-4 IIC 总线的通信时序

    SCL线为高电平期间,SDA线由高电平 SCL线为高电平期间,SDA线由低电平
    向低电平的变化表示起始信号,如图2-5 向高电平的变化表示终止信号,如图2-6

    图2-5 IIC起始信号 图2-6 IIC终止信号
    ① 首先主机发送一个起始信号。当时钟线SCL处于高电平期间,数据线SDA电平从高到低的跳变形成IIC总线的起始信号,启动IIC总线。
    ② 主机逐位发送7位(高位在前,低位在后)从机地址和1位读写控制信号,共8位。需8个时钟。
    ③ 与传送地址一致的从机发应答信号(ACK)。在第9个时钟周期时将SDA线拉低表示其已收到一个8位数据。若在第9个时钟周期,SDA为高电平时为非应答。
    ④ 开始传送数据,传送数据数量不限。每个字节(8位)后紧跟1个接收器件发出的应答位。若是主机读取从机数据时,从机发送数据,主机发应答位;若是主机写数据到从机时,主机发送数据,从机发应答位。
    ⑤ 数据传输结束时,主机发送1个停止信号,当时钟线SCL为高电平时,数据线SDA由低电平变为高电平时形成终止信号,停止IIC总线通信。

    (5) 数据传输基本格式如表2-1。

    表2-1 IIC总线数据传输基本格式
    S A7~A1 R/W ACK D7~D0 ACK D7~D0 ASK P
    起始位 7位
    地址 0:写
    1:读


    位 8位
    数据 应答位 8位
    数据 … 应答位
    0:应答
    1:非应答 停


    其中S、A7-A1、R/W、P总是由主机产生;写数据时,ACK由从机产生,D7-D0由主机产生;读数据时,ACK由主机产生,D7-D0由从机产生。
    (6) 总线空闲
    IIC总线空闲的时候,两条线SDA和SCL都是高电平。
    接收器件收到一个完整的数据字节后,有可能需要完成一些其它工作,如处理内部中断服务等,可能无法立刻接收下一个字节,这时接收器件可以将SCL线拉成低电平,从而使主机处于等待状态。直到接收器件准备好接收下一个字节时,再释放SCL线使之为高电平,从而使数据传送可以继续进行。
    2.2.1.2 IIC总线器件AT24C02
    AT24C02 是一个2K位的串行CMOS型 E2PROM,内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功能。该器件通过IIC总线接口进行操作,其引脚如图2-7所示,各引脚功能见表2-2。

    图2-7 AT24C02引脚图

    表2-2 AT24C02引脚功能说明
    管脚名称 功能说明
    SCL AT24C02 串行时钟输入管脚。用于产生器件所有数据发送或接收的时钟,是输入管脚。
    SDA 双向串行数据/地址管脚。用于器件所有数据的发送或接收,SDA 是一个开漏输出管脚可与其它开漏输出或集电极开路输出进行线或wire-OR。
    WP 写保护。当WP 脚连接到Vcc ,所有内存变成写保护只能读;当WP 引脚连接到Vss 或悬空,允许器件进行读/写操作。
    A0 A1 A2 器件地址输入。这些管脚为硬连线或者不连接,对于单总线系统最多可寻址4 个AT24C02器件。当这些引脚没有连接时其默认值为0。
    VSS 电源地
    VCC 1.8-6V
    AT24C02的器件地址见表2-3
    型号 控制码 片选 读写 总线访问的器件
    AT24C02 1010 A2A1A0 1/0 最多8个
    表2-3 AT24C02器件地址
    主器件每次传送的信息的第一个字节必须是器件地址码,第二个字节为器件单元地址,用于实现选择所操作的器件的内部单元,从第三个字节开始为传送的数据。
    从器件在接收到起始条件后,每接收一个地址编码或数据后都会回送一个低电平的应答信号。IIC器件地址码格式见表2-4
    D7 D6 D5 D4 D3 D2 D1 D0
    器件类型码 片选 R/W
    表2-4 器件地址码格式
    在这里插入图片描述
    图2-8 单个AT24C02连接电路图

    2.2.1.3 对AT24C02的读写过程
    (1) 向AT24C02某一存储单元写入1个字节数据,过程如下:
    ① 主机发送一个起始信号,启动发送过程;
    ② 主机发送7 位从机地址和1位写控制位;
    ③ 从机发应答位。在主机发送起始信号和从机地址字节后,AT24C02监视总线并当其地址与发送的从地址相符时,响应一个应答信号。在第9个时钟,将SDA 线拉为低电平;
    ④ 主机接收到应答位后,发从机子地址高8位(为AT24C02某一存储单元地址);
    ⑤ 从机接收完高8位子地址后,发应答位;
    ⑥ 主机接收到应答位后,发从机子地址低8位;
    ⑦ 从机接收完低8位子地址后,发应答位;
    ⑧ 主机接收到应答位后,发送待8位写入数据;
    ⑨ 从机接收完8数据后,发应答位,并开始内部数据的擦写;
    ⑩ 主机接收到应答位后,发停止位,结束传送,总线挂起。
    (2) 从AT24C02某一存储单元读出1个字节数据,过程如下:
    ① 主机发送一个起始信号,启动发送过程,接着发送7 位从机地址和1位写控制位;
    ② 从机检测到起始信号及本身从地址相符时的从机地址后,发应答位。
    ③ 主机接收到应答位后,发从机子地址高8位(为AT24C02某一存储单元地址)。
    ④ 从机接收完高8位子地址后,发应答位;
    ⑤ 主机接收到应答位后,发从机子地址低8位;
    ⑥ 从机接收完低8位子地址后,发应答位;
    ⑦ 主机接收到应答位后,再发送一个起始信号(称为重复起始信号),接着再发送7 位从机地址和1位读控制位;
    ⑧ 从机检测到重复起始信号及从机地址后,发应答位,并将子地址对应的存储单元数据发送到总线上;
    ⑨ 主机接收到应答位后,接着准备从总线接收数据,从总线接收完8数据后。发非应答位和发停止位,结束传送,总线挂起。
    2.2.2 单片机主控制模块设计
    由AT89C51单片机为控制核心,根据系统功能要求以及单片机硬件电路设计思路对单片机模块进行设计, 要使单片机准确的输入数据,将数据传送给AT24C02芯片,并且将数据读取出来,使数据能通过数码管直观的显示出来。
    AT89C51单片机如图2-9所示,为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地做输出或输入。
    在这里插入图片描述
    图2-9 AT89C51单片机
    管脚说明:
    (1) VCC:供电电压;
    (2) GND:接地;
    (3) P0口:P0口为一个8位漏极开路双向I/O口,每脚可吸收8TTL门流。
    当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在 FIASH 编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
    (4) P1口:P1 口是一个内部提供上拉电阻的 8 位双向 I/O 口, P1口缓冲器能接收输出4TTL门电流。P1口管脚写入 1 后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
    (5) P2口:P2 口为一个内部上拉电阻的 8 位双向 I/O 口, P2口缓冲器可接收,输出4个TTL门电流,当 P2 口被写“1” 时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。 P2 口当用于外部程序存储器或 16 位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2 口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
    (6) P3 口:P3 口管脚是 8个带内部上拉电阻的双向 I/O 口,可接收输出 4 个TTL门电流。当 P3 口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
    P3 口也可作为 AT89C51 的一些特殊功能口, 如下图2-10所示:
    (7) RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平
    (8) EA/VPP :当 EA 保 持 低 电 平 时 ,则 在 此 期 间 外 部 程 序 存 储 器(0000H-FFFFH), 不管是否有内部程序存储器。 注意加密方式 1 时,EA 将内部锁定为 RESET;当EA 端保持高电平时,此间内部程序存储器。 在 FLASH 编程期间,此引脚也用于施加12V编程电源(VPP)。
    51单片机允许的时钟频率因型号而异,典型值为12MHZ。
    在这里插入图片描述
    图2-10 P3口的第二功能
    2.2.3 复位电路模块设计
    51 单片机复位电路是指单片机的初始化操作。 单片机启运运行时, 都需要先复位, 其作用是使 CPU 和系统中其他部件处于一个确定的初始状态, 并从这个状态开始工作。因而, 复位是一个很重要的操作方式。 但单片机本身是不能自动进行复位的, 必须配合相应的外部电路才能实现,如图2-11所示。
    在这里插入图片描述
    图2-11 复位电路
    2.2.4 显示模块设计
    如图2-12所示,采用数码管显示模块,数码管14分别接74LS138译码器的Y0Y3;ADP依次接主控制芯片的P0.0P0.7口;排阻RESPACK8的29分别接主控制芯片的P0.0P0.7口,1接电源;74LS138译码器具有位选功能,输入是3个脚,输出是8个脚,用高低电平来表示输入和输出。输入是二进制,3个脚就是3位二进制数。3位二进制最大是111即8,输出是8个脚,表示十进制,根据输入的二进制数来输出。AC口分别接主控制芯片的P2.2P2.4口,E1接电源,E2和E3接地线,Y0~Y3口如上所述。
    在这里插入图片描述
    图2-12 数码管显示模块
    2.2.5 按键控制模块设计
    如图2-13所示,控制模块选择独立按键实现。按键按下num++,数码管会显示相应的数据,然后进行保存操作,清零按键按下后数码管清零,最后进行读取操作,显示刚才的数据。按键保存,读取,num++,清零左端分别接主控制芯片的P3.0~P3.3口,右端接地。
    在这里插入图片描述
    图2-13 独立按键模块
    2.3 硬件调试
    IIC及AT24C02的电路系统较大,对于焊接方面更是不可轻视,庞大的电路系统中只要出于一处的错误,则会对检测造成很大的不便,而且电路的交线较多,对于各种锋利的引脚要注意处理,否则会对电路造成短路现象。

    3 软件设计
    3.1 代码设计

    //main.c
    #include<reg51.h>
    #include<intrins.h>
    #include"iic.h"
    u8 numer[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    u8 display[4];
    sbit A1=P2^2;
    sbit B1=P2^3;
    sbit C1=P2^4;
    #define SHUMA P0
    sbit K1=P3^0;//保存
    sbit K2=P3^1;//读取
    sbit K3=P3^2;//num++
    sbit K4=P3^3;//清零
    u8 num;
    void delay(u16 i)
    {
    while(i--);
    }
    void shumaguan(u8 word[])
    {	 u8 i;
      for(i=0;i<4;i++)
     {
      switch(i)
      {
      case 0:C1=0;B1=0;A1=0;break;
      case 1:C1=0;B1=0;A1=1;break;
      case 2:C1=0;B1=1;A1=0;break;
      case 3:C1=0;B1=1;A1=1;break;
      }
      SHUMA=word[i];
      delay(100);
      SHUMA=0x00;
     }
    }
    void Key(u8 dat)
    {
     if(K1==0)
     {
      delay(1000);
      if(K1==0)
      At24CO2Write(dat,1);
      while(!K1);
     }
     if(K2==0)
     {
      delay(1000);
      if(K2==0)
      num=At24CO2Read(1);
      while(!K2);
     }
     if(K3==0)
     {
      delay(1000);
      if(K3==0)
      num++;
      while(!K3);
     }
     if(K4==0)
     {
      delay(1000);
      if(K4==0)
      num=0;
      while(!K4);
     }
    }
    void change()
    {
         display[0]=numer[num/1000];
    	 display[1]=numer[(num%1000)/100];
    	 display[2]=numer[(num%100)/10];
    	 display[3]=numer[num%10];
    } 
     void main()
    {
     while(1)
     {
       Key(num);
       change();
       shumaguan(display);
     }
    }
    //iic.c
    #include<reg51.h>
    #include"iic.h"
    void delay10us(void)   
    {
        unsigned char a,b;
        for(b=1;b>0;b--)
            for(a=2;a>0;a--);
    }
    
    void I2cStart() //开始函数,时钟信号始终为高,当数据线由高变低时开始
     { 
      SDA=1;
      delay10us();
      SCL=1;
      delay10us();
      SDA=0;
      delay10us();
      SCL=0;
      delay10us();
     }
     void I2cStop()	//停止函数,时钟信号始终为高,当数据线由低变高时开结束
     {
      SDA=0;
      delay10us();
      SCL=1;
      delay10us();
      SDA=1;
      delay10us();
     }
     u8 I2cSend(u8 dat)
     {
      u8 i,b;
      for(i=0;i<8;i++)
      {
      SDA=dat>>7;
      delay10us();
      dat<<=1;
      SCL=1;
      delay10us();
      SCL=0;
      delay10us();
      }
      SDA=1;
      delay10us();					
      SCL=1;
      while(SDA)
      {
       b++;
       if(b>5){SCL=0;delay10us();return 0;}
      }
      SCL=0;
      delay10us();		  	
      return 1;
     }
     u8 I2cRead()
     {
      u8 i,dat;
      for(i=0;i<8;i++)
      {
      SCL=1;
      delay10us();
      dat<<=1;
      dat|=SDA;
      SCL=0;
      delay10us();
      }
      return dat;
     }
     void At24CO2Write(u8 dat,u8 addr)
     {
       I2cStart();
       I2cSend(0xa0);
       I2cSend(addr);
       I2cSend(dat);
       I2cStop();
     }
      u8 At24CO2Read(u8 addr)
     {
       u8 num;
       I2cStart();
       I2cSend(0xa0);
       I2cSend(addr);
       I2cStart();
       I2cSend(0xa1);
       num=I2cRead();
       I2cStop();
       return num;
     }
    //iic.h
    #ifndef_IIC_H
    #define_IIC_H
    #include<reg51.h>
    typedef unsigned int u16;
    typedef unsigned char u8;
    sbit SDA=P1^0;
    sbit SCL=P1^1;
    void At24c02Write(u8 dat,u8 addr);
    u8 At24c02Write(u8 addr);
    #endif
    

    3.2 仿真实现
    在这里插入图片描述
    图3-6 读取状态仿真图
    4 系统调试总结分析
    4.1 电路调试

    图4-1 电路调试
    4.2 软件调试
    整个程序是一个主程序调用各个子程序实现功能的过程, 要使主程序和整个程序都能平稳运行, 各个模块的子程序的正确与平稳运行必不可少, 所以在软件调试的最初阶段就是把各个子程序模块进行分别调试。
    4.3 综合调试
    通过自己动手,我们完成了实验所需仪器的组装。整个装置由最小系统、数码管显示模块,4个独立按键以及AT89C51芯片模块和IIC接口电路模块组成。根据各个元器件的原理图以及仿真图,组装完成好实物。最后我们得到的实验结果和预期一致,可以通过按键用来控制电机的转速调节和电机的转向控制并通过数码管显示相关的信息。
    在硬件和软件单独调试成功后进行软硬件综合调试, 它可以分成以下几个步骤:
    (1) 独立按键分别进行num++,保存,清零,读取操作;
    (2) 使单片机获得数据并与24C02进行数据传输;
    (3) 通过LED数码管把数据显示出来。
    4.4 故障分析与解决方案
    4.5 总结与经验

    经过为期两周的实习,我对微处理器应用这门课程有了更深的认识,啦啦啦啦啦。。。。。。。。。

    展开全文
  • 用C语言AT24C系列的EPROM读写程序,适用于刚学单片机编程的初学者
  • 读写AT24c02的程序

    2017-10-17 09:30:25
    读写AT24C02的程序,包含了IIC协议的使用,测试等程序
  • AT24C02 IIC读写

    千次阅读 2011-09-30 09:08:55
    //---------------------------------------------------------- // 模块名称:IIC.h // 模块功能:AT24C02的读写操作 //------------------------------------------
    //----------------------------------------------------------
    //	模块名称:IIC.h
    //	模块功能:AT24C02的读写操作
    //----------------------------------------------------------
    sbit IIC_SDA = P1^0;
    sbit IIC_SCL = P1^1;
    
    
    //----------------------------------------------------------
    //	函数名称:void IIC_Start()
    //	函数功能:通知芯片读写开始。
    //----------------------------------------------------------
    void IIC_Start()
    {
    	IIC_SDA=1;
    	Delay5us();
    	IIC_SCL=1;
    	Delay5us();
    	IIC_SDA=0;
    	Delay5us();
    }
    
    
    //----------------------------------------------------------
    //	函数名称:void IIC_Stop()
    //	函数功能:通知芯片读写结束。
    //----------------------------------------------------------
    void IIC_Stop()
    {
    	IIC_SDA=0;
    	Delay5us();
    	IIC_SCL=1;
    	Delay5us();
    	IIC_SDA=1;
    	Delay5us();
    }
    
    
    //----------------------------------------------------------
    //	函数名称:void IIC_Ack()
    //	函数功能:对操作进行应答。
    //----------------------------------------------------------
    void IIC_Ack()
    {
    	unsigned char a;
    	IIC_SCL=1;
    	Delay5us();
    	while((IIC_SDA==0) && (a>240))a++;
    	IIC_SCL=0;
    	Delay5us();
    }
    
    
    //----------------------------------------------------------
    //	函数名称:void IIC_WriteByte(unsigned char dat)
    //	函数功能:写一个字节的数据 
    //----------------------------------------------------------
    void IIC_WriteByte(unsigned char Data)
    {
    	unsigned char i,temp;
    	temp=Data;
    	for(i=0;i<8;i++)
    	{
    		temp=temp<<1;
    		IIC_SCL=0;
    		Delay5us();
    		IIC_SDA=CY;
    		Delay5us();
    		IIC_SCL=1;
    		Delay5us();
    	}
    	IIC_SCL=0;
    	Delay5us();
    	IIC_SDA=1;
    	Delay5us();
    }
    
    
    //----------------------------------------------------------
    //	函数名称:unsigned char IIC_ReadByte()
    //	函数功能:读一个字节的数据 
    //----------------------------------------------------------
    unsigned char IIC_ReadByte()
    {
    	unsigned char i,temp;
    	IIC_SCL=0;
    	Delay5us();
    	IIC_SDA=1;
    	Delay5us();
    	for(i=0;i<8;i++)
    	{
    		IIC_SCL=1;
    		Delay5us();
    		temp=(temp<<1)|IIC_SDA;
    		Delay5us();
    		IIC_SCL=0;
    		Delay5us();
    	}
    	return temp;
    }
    
    
    //----------------------------------------------------------
    //	函数名称:void IIC_WriteAddr(unsigned char addr, dat)
    //	函数功能:从指定的地址读一个字节的数据 
    //----------------------------------------------------------
    void IIC_WriteAddr(unsigned char addr, dat)
    {
    	IIC_Start();
    	IIC_WriteByte(0xa0);
    	IIC_Ack();
    	IIC_WriteByte(addr);
    	IIC_Ack();
    	IIC_WriteByte(dat);
    	IIC_Ack();
    	IIC_Stop();
    }
    
    
    //----------------------------------------------------------
    //	函数名称:unsigned char IIC_ReadAddr(unsigned char addr)
    //	函数功能:从指定的地址写一个字节的数据 
    //----------------------------------------------------------
    unsigned char IIC_ReadAddr(unsigned char addr)
    {
    	IIC_Start();
    	IIC_WriteByte(0xa0);
    	IIC_Ack();
    	IIC_WriteByte(addr);
    	IIC_Ack();
    	IIC_Start();
    	IIC_Ack();
    	IIC_WriteByte(0xa1);
    	IIC_Ack();
    	return IIC_ReadByte();
    }
    

    展开全文
  • 这是一个用汇编语言编写的AT24C02存储器读写程序,压缩包中包括了汇编源代码和Proteus仿真电路,汇编程序均有详细注释,读起来应该不会费力气。
  • at24c02的读写操作

    2012-05-26 21:59:37
    i2c的操作,已经调试成功,在数码管上从0到9显示
  • 1.从起始地址连续读出AT24C02中256个字节中的数据。采用的是Random read的时序读取的。 //连续读(Randem读的时序) AT24C04_Start(); //起始信号 AT24C04_SendByte(AT24_Address); //发送设备地址+...
  • AT24C02读写程序(C51)

    2009-07-30 11:19:43
    用c51实现的AT24C02读写程序,已经成头文件,方便调用。
  • 51单片机对I2C总线上挂接多个AT24C02的读写操作proteus源文件(含C源码),实验中使用两个24C02进行试验

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,762
精华内容 3,104
关键字:

at24c02页写