51单片机-AT24C

发布时间:2011-3-22 11:36    发布者:techshare
关键词: 51单片机 , AT24C
AT24C02是由ATMEL公司提供的,IIC总线串行EEPROM(electronic eraser programmer read only memory),其容量为2kbit(256B),工作电压在2.7v"5.5v之间,生产工艺是CMOS。  


  
一般数字芯片都在左下角和右上角为GND,VCC。容量的计算方法:AT24Cxx :01"1024  
容量 = xx * 1kbit。  

写入过程:  

AT24C系列EEPROM芯片的固定部分为1010,A2,A1,A0引脚接高低电平后得到确定的3位编码,形成7位编码即为该器件的地址码。  

单片机进行写操作时,首先发送该器件的7位地址码和写方向位”0”(共8位,即一个字节),发送完后释放SDA线并在SCL线上产生第9个时钟信号。被选中的存储器器件在确认是自己的地址后,在SDA线上产生一个应答信号作为响应,单片机收到应答后就可以传送数据了。传送数据时,单片机首先发送一个字节的被写入存储器的首地址,收到存储器器件的应答后,单片机就逐个发送数据字节,但每发送一个字节后都要等待应答。AT24C系列片内地址在接收到每一个数据字节地址后自动加1,在芯片的“一次装载字节数”限度内,只需输入首地址。装载字节数超过芯片的“一次装载字节数”时,数据地址将“上卷”,前面的数据将被覆盖。  


  
  
字节写:  


   
  
页写:  


   
读入过程:   

单片机先发送该器件的7位地址码和写方向位“0”(“伪写”),发送完后释放SDA线并在SCL线上产生第9个时钟信号。被选中的存储器器件在确认是自己的地址后,在SDA线上产生一个应答信号作为回应。      

然后,再发一个字节的要读出器件的存储区的首地址,收到应答后,单片机要重复一次起始信号并发出器件地址和读方向位(“1”),收到器件应答后就可以读出数据字节,每读出一个字节,单片机都要回复应答信号。当最后一个字节数据读完后,单片机应返回以“非应答”(高电平),并发出终止信号以结束读出操作。   


  
当前地址读:   


   
  
随机读:  


   
  
有序读:  


   
  
IIC总线模拟时序图:  


   
IIC总线应答时序图:  


  
设备地址:  


   
写周期:  


   
两次写之间要有一个10ms的twR间隔  
  
写入EEPROM一个2,然后读出,在数码管上显示出来:     #include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL = P3^6;
sbit SDA = P3^7;

void delay()
{ ;; }                //5us      
void delay1(uchar x)
{
        uchar a,b;
        for(a=x;a>0;a--)
         for(b=100;b>0;b--);
}

void Init(){
        SCL = 1;
        SDA = 1;
}

void start(){
        SDA = 1;
        delay();
        SCL = 1;
        delay();
        SDA = 0;
        delay();
}

void stop(){
        SDA = 0;
        delay();
        SCL = 1;
        delay();
        SDA = 1;
        delay();
}

void write(uchar date)
{
        uchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                SCL=0;
            delay();
                SDA=CY;
                delay();
                SCL=1;
                delay();
        }
        SCL=0;
        delay();
        SDA=1;
        delay();
}

uchar read()
{
        uchar i,k;
        SCL=0;
        delay();
        SDA=1;
        delay();
        for(i=0;i<8;i++)
        {
                SCL=1;
                delay();        
                k=(k<<1)|SDA;                          // 将SDA赋给K的每一位
                SCL=0;
                delay();        
        }
        return k;
}


void response(){
        int i;
        SCL = 1;                                               //在SCL为高电平期间,进行应答
        delay();
        while((SDA == 1) && (i < 170))i++; //SCL释放总线,等待从设备应答,从设备会把SDA拉低
        SCL = 0;                                                  
        delay();
}

void At24c_Write(uchar address, uchar value){
        start();
        write(0xa0);                         //写入设备地址
        response();
        write(address);                         //写入首地址
        response();
        write(value);                         //写入数据
        response();
        stop();        
}

uchar At24c_Read(uchar address){
   uchar value;
   start();
   write(0xa0);                                 //伪写,先写入设备地址
   response();
   write(address);                         //再写入要读取数据的首地址
   response();
   start();                                         //再次
   write(0xa1);                                 //写入要读取数据的地址,方向为1
   response();
   value = read();                         //读取数据
   stop();
   return value;
}

void main(){
        P1 = 0x0;            //        位选,使最地位数码管被选中
        Init();
        At24c_Write(23,0x5b);  // 在EEPROM的23这个地址上写数据0x5b
        delay1(100);                   // 在写和读之间要多延时一会儿,否则器件处理不完
        P2 = At24c_Read(23);   // 读取23地址的数据,也就是刚才写入的数据
        while(1);
}


掉电后数据不丢失,复位后,仍然从刚才掉电的数字开始往下显示。从0"9


#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL = P3^6;
sbit SDA = P3^7;
uchar temp, sum;
uint flag;
unsigned char code duan[]={
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
        0x77,0x7C,0x39,0x5E,0x79,0x71};

void delay()
{ ;; }                //5us      
void delay1(uchar x)
{
        uchar a,b;
        for(a=x;a>0;a--)
         for(b=100;b>0;b--);
}

void Init(){
        SCL = 1;
        SDA = 1;
}

void start(){
        SDA = 1;
        delay();
        SCL = 1;
        delay();
        SDA = 0;
        delay();
}

void stop(){
        SDA = 0;
        delay();
        SCL = 1;
        delay();
        SDA = 1;
        delay();
}

void write(uchar date)
{
        uchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                SCL=0;
            delay();
                SDA=CY;
                delay();
                SCL=1;
                delay();
        }
        SCL=0;
        delay();
        SDA=1;
        delay();
}

uchar read()
{
        uchar i,k;
        SCL=0;
        delay();
        SDA=1;
        delay();
        for(i=0;i<8;i++)
        {
                SCL=1;
                delay();        
                k=(k<<1)|SDA;                          // 将SDA赋给K的每一位
                SCL=0;
                delay();        
        }
        return k;
}


void response(){
        int i;
        SCL = 1;                                               //在SCL为高电平期间,进行应答
        delay();
        while((SDA == 1) && (i < 170))i++; //SCL释放总线,等待从设备应答,从设备会把SDA拉低
        SCL = 0;                                                  
        delay();
}

void At24c_Write(uchar address, uchar value){
        start();
        write(0xa0);                         //写入设备地址
        response();
        write(address);                         //写入首地址
        response();
        write(value);                         //写入数据
        response();
        stop();        
}

uchar At24c_Read(uchar address){
   uchar value;
   start();
   write(0xa0);                                 //伪写,先写入设备地址
   response();
   write(address);                         //再写入要读取数据的首地址
   response();
   start();                                         //再次
   write(0xa1);                                 //写入要读取数据的地址,方向为1
   response();
   value = read();                         //读取数据
   stop();
   return value;
}

void main(){
        uint i;
        flag = 1;
        P1 = 0x0;            //        位选,使最地位数码管被选中
        EA = 1;
        ET0 = 1;
        sum = 0;
        temp = 0;
        TMOD = 0x01;
        TH0 = (65536 - 50000) / 256;
        TL0 = (65536 - 50000) % 256;
        TR0 = 1;
        Init();
        P2 = At24c_Read(23);
        for(i = 0; i < 10; i++)
                if(duan[ i] == P2){
                        sum = i;
                        break;
                        flag = 0;
                }
        while(1){
                if(temp == 20){
                        temp = 0;
                        if(sum == 10){
                                sum = 0;
                        }
                        if(flag == 1){                        
                                At24c_Write(23,duan[sum]);
                                delay1(100);
                            P2 = duan[sum];
                        }
                        sum++;
                }
        }
}

void time0() interrupt 1{
        TH0 = (65536 - 50000) / 256;
        TL0 = (65536 - 50000) % 256;
        temp++;
}
本文地址:https://www.eechina.com/thread-59315-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
williamkmcn 发表于 2011-7-7 17:06:09
好东西值得收藏
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表