打印

请各位网友看看如何读写这个eeprom

[复制链接]
楼主: xbyu520
手机看帖
扫描二维码
随时随地手机跟帖
21
liu1028tao| | 2014-3-12 07:43 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 liu1028tao 于 2014-3-12 07:47 编辑

IIC总线对时间要求比较严格,一般都是选择延时4 7us(大概延时4个机器周期),你延时那么长读的出才怪呢。

使用特权

评论回复
评论
xbyu520 2014-3-12 15:00 回复TA
刚刚试验了一下,延时太长也是不可以的。从效率考虑,比规定时间长一点点就可以了。 
ningling_21 2014-3-12 10:35 回复TA
最小是4.7US,长一点是可以的,例如20US没问题,但短了就不行了... 
22
xbyu520|  楼主 | 2014-3-12 08:35 | 只看该作者
更正一下,我用的是现成的开发板,有10K上拉电阻到VCC的。

使用特权

评论回复
23
xbyu520|  楼主 | 2014-3-12 08:36 | 只看该作者

更正一下,我用的是现成的开发板,有10K上拉电阻到VCC的。这个可以肯定。因为仔细看了原理图,然后仔细量了PCB

使用特权

评论回复
24
xbyu520|  楼主 | 2014-3-12 09:01 | 只看该作者
自己顶起来

使用特权

评论回复
25
xbyu520|  楼主 | 2014-3-12 09:30 | 只看该作者
大神来看看啊

使用特权

评论回复
26
xbyu520|  楼主 | 2014-3-12 10:01 | 只看该作者
#include<reg52.h>
#include <soft_delay.h>

sbit scl=P2^0;                                               
sbit sda=P2^1;                                                //
sbit led=P2^4;                                                //



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();
        while((sda==1)&&(i<255))
                i++;
        scl=0;
        delay();
}
void init()
{
        sda=1;
        delay();
        scl=1;
        delay();
}
void write_byte(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_byte()
{
                uchar i,k;
                scl=0;
                delay();
                sda=1;
                for(i=0;i<8;i++)
                {
                        scl=1;
                        delay();
                        k=(k<<1)|sda;
                        scl=0;
                        delay();
                }
                delay();       
                return k;
}

///*Ö¸¶¨µØÖ·¶ÁÒ»¸ö×Ô¼ºµÄº¯Êý*/

uchar read_add(uchar address)
{
          uchar date;
                start();
//                write_byte(0xa0);
                write_byte(0xae);
                respons();
                write_byte(address);
                respons();
                start();
//        write_byte(0xa1);
                write_byte(0xaf);
                respons();
                date=read_byte();
                stop();
                return date;
}
/*Ö¸¶¨µØַдһ¸ö×ֽڵĺ¯Êý*/

void write_add(uchar address,uchar date)
{
                start();
//                write_byte(0xa0);
                write_byte(0xae);
                respons();
                write_byte(address);
                respons();
                write_byte(date);
                respons();
                stop();
}

uchar p;
void main()
{
               
       
                init();
                write_add(0x10,0x99);
                delay();
                delay();
                delay();
                delay();
                delay();
                delay();
                delay();
                delay();
                delay();
                delay();
                p=read_add(0x10);
        while(1)
        {
                if(p==0x99)
                {
                        led=~led;
                        delay();
                        delay();
                }
                else
                {
                        led=0;
                }
        }       
       

}


使用特权

评论回复
27
xbyu520|  楼主 | 2014-3-12 10:02 | 只看该作者
#define uchar unsigned char
void delay()
{

;

}

使用特权

评论回复
28
xbyu520|  楼主 | 2014-3-12 10:02 | 只看该作者
示波器量了delay()延时约7.6uS

使用特权

评论回复
29
xbyu520|  楼主 | 2014-3-12 10:03 | 只看该作者
11.0592MHz  STC89C54RD+

使用特权

评论回复
30
ocon| | 2014-3-12 10:35 | 只看该作者
建议上TB买个三十多元的逻辑分析仪来抓波形,相信你会收获更多。

使用特权

评论回复
31
ningling_21| | 2014-3-12 10:36 | 只看该作者
xbyu520 发表于 2014-3-12 10:02
示波器量了delay()延时约7.6uS

用示波器测两根线的波形,上波形图吧...

使用特权

评论回复
32
xbyu520|  楼主 | 2014-3-12 10:39 | 只看该作者
手里有示波器,这个程序是从郭天祥51教程上拷贝过来后稍微改动后用于我的开发板的。因为我的开发板 A0 A1 A2是接VCC的。郭的开发板接了地

使用特权

评论回复
33
xbyu520|  楼主 | 2014-3-12 10:41 | 只看该作者
ningling_21 发表于 2014-3-12 10:36
用示波器测两根线的波形,上波形图吧...

好的

使用特权

评论回复
34
xyz549040622| | 2014-3-12 10:41 | 只看该作者
1.一般时序的问题,只有抓波形才知道,我300买的逻辑分析仪各种强大
2.对于C8051这种用烂的51芯片,移植别人用过的时序即可,如果不显示,怀疑你的硬件吧

使用特权

评论回复
35
xyz549040622| | 2014-3-12 10:49 | 只看该作者
xbyu520 发表于 2014-3-11 16:39
WP连接“地”。SDA 和SCL连接IO口。程序就是上面的程序。晶振11.0592MHz.单片机是传统单片机STC89C54RD+ ...

大哥,你把A0/A1/A2接地好不好。。。不级联要接地的

使用特权

评论回复
36
vkic007| | 2014-3-12 11:12 | 只看该作者
你用示波器看看时序和数据手册上的好好对比一下,其次你在初始化的时候也要把LED的状态初始化一下。其次我记得24C02这类芯片写和读之间最好延时一下,因为你写入的数据是暂时写入到缓存的,一次写完后,他就会吧数据在写入你的制定的地址,在内部写数据的时候,是不能操作芯片的。
/**************初始化iic******************/
void iic_init(void)
{
   PERCK0|=0x10; //使能IIC硬件模块功能
   P1DIR0 |= 0x0c; //
   P1DIR1 &= 0xf3; //SCL和SDA引脚设置iic模式
   I2CLK=0x55;//iic时钟设置
   I2CON|=0X10;        // iic接收和发送使能
}
void iic_start(void)  ///10 98 D1 D0 D1 D8 D1 D0
{        //Uart1_sendbyte(I2CON);
        I2CON|=0x08;
        //Uart1_sendbyte(I2CON);
        I2CON&=0xFE;
        //Uart1_sendbyte(I2CON);
        while(0==(I2CON&0x01));
        //Uart1_sendbyte(I2CON);
        //I2CON&=0xFE;
        //Uart1_sendbyte(I2CON);
}
void iic_stop(void)
{       
    I2CON|=0x04;
        I2CON&=0xFE;
        while(0==(I2CON&0x01));       
}
void iic_ack(void)
{        while(1==(I2STS&0X04));
        I2CON|=0x02;//set ACK BIT       
}
/***************任意写一个字节**************************/
void write_24c02_byte(unsigned char addr_chip,unsigned char addr_data,unsigned char write_data)
{
     iic_start();//开始位

         I2DAT=addr_chip;//器件地址
     I2CON&=0xFE;
     while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));
         I2DAT=addr_data; //字节的地址
     I2CON&=0xFE;
         while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));
         
         I2DAT=write_data;
     I2CON&=0xFE;
     while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));       

         iic_stop();

}
/***************任意读一个字节**************************/
unsigned char read_24c02_byte(unsigned char addr_chip,unsigned char addr_data)
{
        unsigned char rec_data;
         iic_start(); //起始位
         I2DAT=addr_chip;//器件地址
     I2CON&=0xFE;
     while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));
         I2DAT=addr_data;//读取字节的地址
     I2CON&=0xFE;
         while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));

         iic_start(); //起始位
         I2DAT=addr_chip+1; //器件地址 ,由于是读操作,所以需要加1
     I2CON&=0xFE;
     while(0==(I2CON&0x01));
     while(1==(I2STS&0X04));

         I2CON&=0xFE;
     while(0==(I2CON&0x01));
     rec_data=I2DAT;
         iic_stop();
         return rec_data;

       
}

使用特权

评论回复
37
vkic007| | 2014-3-12 11:13 | 只看该作者
我们用的单片机不同,但是操作顺序是一样。你在看看时序

使用特权

评论回复
38
vkic007| | 2014-3-12 11:22 | 只看该作者
void write_byte(uchar date)           //写字节函数
{
        uchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                scl=0;
                delay();
                sda=CY//CY是什么东东,什么地方来的,你是模拟IIC,我觉得你模拟的有问题
                delay();
                scl=1;
                delay();
        }
                scl=0;
                delay();
                sda=1;
          delay();
}

参考我原来写的
void iic_send(unsigned char _data1)
{
        clk=0;
        if(_data1&0x80)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x40)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x20)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x10)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x08)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x04)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x02)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;
        if(_data1&0x01)
                {
                        sda=1;
                }
        else sda=0;
        delay(1);
        clk=1;
        delay(1);

        clk=0;          ////ack
        delay(1);
        sda=0;
        delay(1);
        clk=1;
        delay(1);
}

使用特权

评论回复
39
xbyu520|  楼主 | 2014-3-12 15:05 | 只看该作者
"其次我记得24C02这类芯片写和读之间最好延时一下"我试验了一下,写和读之前确实要延时,否则就显示不对。原因可能是写的不对或者读出来的不对!!!谢谢你!!

使用特权

评论回复
40
xbyu520|  楼主 | 2014-3-12 15:07 | 只看该作者
终于写一个字节进去了,下面研究“页”写了。可以结贴了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则