zoukankan      html  css  js  c++  java
  • STM32驱动AT24CXX系列芯片

    AT24Cxx系列EEPROM是由美国Mcrochip公司出品,1-512K位的支持I2C总线数据传送协议的串行CMOS E2PROM,可用电擦除,可编程自定时写周期(包括自动擦除时间不超过10ms,典型时间为5ms)的。串行E2PROM一般具有两种写入方式,一种是字节写入方式,还有另一种页写入方式。允许在一个写周期内同时对1个字节到一页的若干字节的编程写入,1页的大小取决于芯片内页寄存器的大小。其中,AT24C01具有8字节数据的页面写能力,AT24C02/04/08/16具有16字节数据的页面写能力,AT24C32/64具有32字节数据的页面写能力

    AT24CXX的驱动是基于IIC的,在基本的IIC上加入了一些通讯协议,具体如下

    1.随机写


    主器件发送起始命令和从器件地址
    信息(R/W 位置 0)给从器件,主器件在收到从器件产生应答信号后,主器件发送 1 个 8 位字节地
    址写入 AT24C01/02/04/08/16 的地址指针,对于 AT24C31/64/128/256 来说,所不同的是主器件发
    送两个 8 位地址字写入 AT24C32/64/128/256 的地址指针。主器件在收到从器件的另一个应答信号
    后,再发送数据到被寻址的存储单元。AT24Cxx 再次应答,并在主器件产生停止信号后开始内部
    数据的擦写,在内部擦写过程中,AT24Cxx 不再应答主器件的任何请求

    2.页写


    。在页写模式下,AT24C01/02/04/08/16/32/64/128/256 
    可一次写入 8 /16/16/16/16/32/32/64/64 个字节数据。页写操作的启动和字节写一样,不同的是在
    于传送了一字节数据后并不产生停止信号。主器件被允许发送 P(AT24C01:P=7;
    AT24C02/04/08/16: P=15;AT24C32/64:P=31;AT24C128/256:P=63)个额外的字节。每发送
    一个字节数据后 AT24Cxx 产生一个应答位, 且内部低位地址加 1,高位保持不变。如果在发送停
    止信号之前主器件发送超过 P+1 个字节,地址计数器将自动翻转,先前写入的数据被覆盖。 接
    收到 P+1 字节数据和主器件发送的停止信号后,AT24Cxx 启动内部写周期将数据写到数据区。 所
    有接收的数据在一个写周期内写入 AT24Cxx

    3.立即读


    也就是说,立即读取读取的是存储器内部指针的当前数据,不需要我们设定地址

    4.随机读


    随机读操作允许主器件对寄存器的任
    意字 节进行读操作,主器件首先通过发送起始信号、从器件地址和它想读取的字节数据的地
    址执行一个伪写操作。在 AT24Cxx 应答之后,主器件重新发送起始信号和从器件地址,此时
    R/W 位置 1, AT24CXX 响应并发送应答信号,然后输出所要求的一个 8 位字节数据,主器件
    不发送应答信号但产生一个停止信号。 

    随机读需要设定需要读的地址,然后有一次伪写入过程,这个伪写入是为了修改存储器内部的工作指针

    5.顺序读


    。顺序读操作可通过立即读或选择性读操作启
    动。在 AT24Cxx 发送完一个 8 位字节数据后,主器件产生一个应答信号来响应,告知 AT24CXX
    主器件要求更多的数据,对应每个主机产生的应答信号 AT24Cxx 将发送一个 8 位数据字节。当
    主器件不发送应答信号而发送停止位时结束此操作。 从 AT24Cxx 输出的数据按顺序由 N 到 N+1
    输出。读操作时地址计数器在 AT24Cxx 整个地址内增加,这样整个寄存器区域在可在一个读操
    作内全部读出。当读取的字节超过 E(AT24C01,E=127;AT24C02,E=255;AT24C04,E=511;
    AT24C08,E=1023;AT24C16,E=2047;AT24C32,E=4095;AT24C64,E=8191;AT24C128,
    E=16383;AT24C256,E=32767)计数器将翻转到零并继续输出数据字节

    顺序读其实就是在前两个的基础上,一个数据读完了不发送noack二十发送ACK这样就可以一直读下去,需要自己计数因为存储器内部指针会自动循环的


    所以只要按照时序图的标准来祝贺IIC基础驱动,就能实现一个存储器的驱动了

    代码如下


    #ifndef __24CXX_H
    #define __24CXX_H
    #include "iic.h"
    #include "delay.h"
    
    #define AT24C01		127
    #define AT24C02		255
    #define AT24C04		511
    #define AT24C08		1023
    #define AT24C16		2047
    #define AT24C32		4095
    #define AT24C64	    8191
    #define AT24C128	16383
    #define AT24C256	32767  
    
    #define EE_TYPE AT24C02
    
    #define AT_ADDR		0xa0
    
    #define AT_CHECK_ADDR	0X00
    #define AT_CHECK_VALUE	0X52
    
    
    u8 At24cxxReadOneByte(u16 ReadAddr);							//指定地址读取一个字节
    
    
    void At24cxxWriteOneByte(u16 WriteAddr,u8 DataToWrite);		//指定地址写入一个字节
    
    
    void At24cxxWriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据
    
    
    u32 At24cxxReadLenByte(u16 ReadAddr,u8 Len);					//指定地址开始读取指定长度数据
    
    
    void At24cxxWrite(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);	//从指定地址开始写入指定长度的数据
    
    
    void At24cxxRead(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);   	//从指定地址开始读出指定长度的数据
    
    
    
    u8 At24cxxCheck(void);  //检查器件
    
    
    void At24cxxInit(void); //初始化IIC
    
    
    #endif
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #include "24cxx.h" 										 
    
    
    //初始化IIC接口
    void At24cxxInit(void)
    {
        IIcInit();
    }
    
    
    //在AT24CXX指定地址读出一个数据
    //ReadAddr:开始读数的地址  
    //返回值  :读到的数据
    u8 At24cxxReadOneByte(u16 ReadAddr)
    {				  
        u8 temp=0;		  	    																 
        IIcStart();  
        if(EE_TYPE>AT24C16)
        {
            IIcSendByte(AT_ADDR);	   //发送写命令
            IIcWaitAck();
            IIcSendByte(ReadAddr>>8);//发送高地址	    
        }else IIcSendByte(AT_ADDR+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据 	   
        IIcWaitAck(); 
        IIcSendByte(ReadAddr%256);   //发送低地址
        IIcWaitAck();	    
        IIcStart();  	 	   
        IIcSendByte(AT_ADDR+1);           //进入接收模式			   
        IIcWaitAck();	 
        temp=IIcReadByte(0);		   
        IIcStop();//产生一个停止条件	    
        return temp;
    }
    
    
    //在AT24CXX指定地址写入一个数据
    //WriteAddr  :写入数据的目的地址    
    //DataToWrite:要写入的数据
    void At24cxxWriteOneByte(u16 WriteAddr,u8 DataToWrite)
    {				   	  	    																 
        IIcStart();  
        if(EE_TYPE>AT24C16)
        {
            IIcSendByte(AT_ADDR);	    //发送写命令
            IIcWaitAck();
            IIcSendByte(WriteAddr>>8);//发送高地址	  
        }else IIcSendByte(AT_ADDR+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据 	 
        IIcWaitAck();	   
        IIcSendByte(WriteAddr%256);   //发送低地址
        IIcWaitAck(); 	 										  		   
        IIcSendByte(DataToWrite);     //发送字节							   
        IIcWaitAck();  		    	   
        IIcStop();//产生一个停止条件 
        DelayMs(10);	 
    }
    
    
    //在AT24CXX里面的指定地址开始写入长度为Len的数据
    //该函数用于写入16bit或者32bit的数据.
    //WriteAddr  :开始写入的地址  
    //DataToWrite:数据数组首地址
    //Len        :要写入数据的长度2,4
    void At24cxxWriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
    {  	
        u8 t;
        for(t=0;t<Len;t++)
        {
            At24cxxWriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
        }												    
    }
    
    //在AT24CXX里面的指定地址开始读出长度为Len的数据
    //该函数用于读出16bit或者32bit的数据.
    //ReadAddr   :开始读出的地址 
    //返回值     :数据
    //Len        :要读出数据的长度2,4
    u32 At24cxxReadLenByte(u16 ReadAddr,u8 Len)
    {  	
        u8 t;
        u32 temp=0;
        for(t=0;t<Len;t++)
        {
            temp<<=8;
            temp+=At24cxxReadOneByte(ReadAddr+Len-t-1); 	 				   
        }
        return temp;												    
    }
    
    
    //检查AT24CXX是否正常
    //这里用了24XX的最后一个地址(255)来存储标志字.
    //如果用其他24C系列,这个地址要修改
    //返回1:检测失败
    //返回0:检测成功
    u8 At24cxxCheck(void)
    {
        u8 temp;
        temp=At24cxxReadOneByte(AT_CHECK_ADDR);//避免每次开机都写AT24CXX			   
        if(temp==AT_CHECK_VALUE)return 0;		   
        else//排除第一次初始化的情况
        {
            At24cxxWriteOneByte(AT_CHECK_ADDR,AT_CHECK_VALUE);
            temp=At24cxxReadOneByte(AT_CHECK_ADDR);	  
            if(temp==AT_CHECK_VALUE)return 0;
        }
        return 1;											  
    }
    
    //在AT24CXX里面的指定地址开始读出指定个数的数据
    //ReadAddr :开始读出的地址 对24c02为0~255
    //pBuffer  :数据数组首地址
    //NumToRead:要读出数据的个数
    void At24cxxRead(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
    {
        while(NumToRead)
        {
            *pBuffer++=At24cxxReadOneByte(ReadAddr++);	
            NumToRead--;
        }
    }  
    
    
    //在AT24CXX里面的指定地址开始写入指定个数的数据
    //WriteAddr :开始写入的地址 对24c02为0~255
    //pBuffer   :数据数组首地址
    //NumToWrite:要写入数据的个数
    void At24cxxWrite(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
    {
        while(NumToWrite--)
        {
            At24cxxWriteOneByte(WriteAddr,*pBuffer);
            WriteAddr++;
            pBuffer++;
        }
    }
    
    
    
    
    
    
    
    




  • 相关阅读:
    052-14
    052-13
    css垂直居中
    js中的null 和undefined
    给数组添加属性
    js中避免函数名和变量名跟别人冲突
    js变量问题
    Life
    BFC和haslayout
    json文件
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4279446.html
Copyright © 2011-2022 走看看