发新帖我要提问
12
返回列表
打印

51模拟i2c

[复制链接]
楼主: lp1468
手机看帖
扫描二维码
随时随地手机跟帖
21
容许页写模式,则连续写入的最大字节数就是页面长度

使用特权

评论回复
22
一级菜鸟| | 2010-11-6 09:45 | 只看该作者
17# 一级菜鸟  
你意思,在写命令之后,应该加一个停止命令,然后开始命令,然后写?
lp1468 发表于 2010-11-6 09:25


写命令全部结束之后,发完停止命令,然后开始命令,这时候器件处于内部写周期,会收不到ACK,反复发送一直到ACK出现,表示器件内部操作已经完成,这时候可以读了。

死等是笨办法,耗时长,最主要移植性很差。

使用特权

评论回复
23
yewuyi| | 2010-11-6 09:47 | 只看该作者
写命令全部结束之后,发完停止命令,然后开始命令,这时候器件处于内部写周期,会收不到ACK,反复发送一直到ACK出现,表示器件内部操作已经完成,这时候可以读了。

死等是笨办法,耗时长,最主要移植性很差。 ...
一级菜鸟 发表于 2010-11-6 09:45


死等的方式在IIC总线被挂死后,则会导致读写错误。

使用特权

评论回复
24
一级菜鸟| | 2010-11-6 09:52 | 只看该作者
void StartIIC(void)
{
        SDA =   1;
        IICDelay();
        SCL =   1;
        IICDelay();
        SDA =   0;
        IICDelay();
        SCL =   0;
}      

void EndIIC(void)
{
        SDA =   0;
        IICDelay();
        SCL =   1;
        IICDelay();
        SDA =   1;
        IICDelay();
        SCL =   1;
}      


unsigned char RecvIIC(void)
{
        unsigned char Count,DataR;
        SDA =   1;
        for (Count = 0;Count<8;Count++)
        {
                SCL =   1;
                DataR = DataR << 1;
                if (SDA)
                {
                        DataR |= B00000001;
                }
                SCL =   0;
                IICDelay();
        }
        return DataR;
}


unsigned char SendIIC(unsigned char idata DataS)
{
        unsigned char Count;
        for (Count = 0;Count<8;Count++)
        {
                SDA =   DataS & 0x80;
                IICDelay();
                SCL =   1;
                IICDelay();
                SCL =   0;
                DataS = DataS << 1;
        }
        IICDelay();
        SDA =   1;
        IICDelay();
        SCL =   1;
        IICDelay();
        if (SDA)
        {
                SCL =0;
                return FALSE;
        }
        SCL =0;
        return TRUE;
}


void IICDelay(void)
{
   
}


        
unsigned char ReadIIC(unsigned char* DataIn,unsigned char Address,unsigned char Length)
{
        if (Length == 0)
        {
                return TRUE;
        }

        StartIIC();
        if (!SendIIC(EEP_SLAVEADDR_WRITE))
        {
                EndIIC();
                return FALSE;
        }
        SendIIC(Address);
        StartIIC();
        SendIIC(EEP_SLAVEADDR_READ);
        while (Length > 1)
        {
                *DataIn = RecvIIC();
                SDA =   0;
                IICDelay();
                SCL =   1;
                IICDelay();
                SCL =   0;
                Length--;
                DataIn++;
        }      
        
        *DataIn = RecvIIC();
        SDA =   1;
        IICDelay();
        SCL =   1;
        IICDelay();
        SCL =   0;
        EndIIC();
        return TRUE;
}

unsigned char WriteIIC(unsigned char* DataIn,unsigned char Address,unsigned char Length)
{
        unsigned char idata Count;
        if (Length == 0)
        {
                return TRUE;
        }
        
        StartIIC();
        SendIIC(EEP_SLAVEADDR_WRITE);
        SendIIC(Address);

        while(1)
        {
               
                if (!SendIIC(*DataIn))
                {
                        EndIIC();
                        return FALSE;
                }
               
                Address++;
                DataIn++;
               
                if (Count++ == Length)
                {
                        EndIIC();
                        if (WaitPoll())
                        {
                                return TRUE;
                        }
                        else
                        {
                                return FALSE;
                        }
                }
        
                if ((Address & B00000111) == 0)
                {
                        EndIIC();
                        WaitPoll();
                        StartIIC();
                        SendIIC(EEP_SLAVEADDR_WRITE);
                        SendIIC(Address);
                }
        }
}

unsigned char WaitPoll(void)
{
        unsigned char Retry;
        Retry = 0xff;
        while(Retry--)
        {
                StartIIC();
                if (SendIIC(EEP_SLAVEADDR_WRITE))
                {
                        EndIIC();
                        return TRUE;
                }
        }
        EndIIC();
        return FALSE;
}

使用特权

评论回复
25
一级菜鸟| | 2010-11-6 09:53 | 只看该作者
N年没有发过源代码,为你破个例,你要的是最后一个函数。

使用特权

评论回复
26
lp1468|  楼主 | 2010-11-6 11:00 | 只看该作者
先谢谢楼上了,你给了我理论依据。也就是说我要是连续写后直接读取数据是不行的,应该i2c器件还没有转化过来。对于连续写8字节数据了紧跟这写8字节数据也是不行的。
对于100K的传输模式写完后要等待大约1ms的时间才可以对i2c操作。

使用特权

评论回复
27
一级菜鸟| | 2010-11-6 11:09 | 只看该作者
26# lp1468

未必,如果是铁电,根本不需要等就可以直接读。

还是那句话,跟具体的器件有关系。

使用特权

评论回复
28
一级菜鸟| | 2010-11-6 11:12 | 只看该作者
例如这一款

使用特权

评论回复
29
lp1468|  楼主 | 2010-11-6 11:14 | 只看该作者
19# xwj
唉!没有看到xwj的精彩回复,让我想了很久,哈哈!xwj正解。

使用特权

评论回复
30
shizaigaole| | 2010-11-6 11:21 | 只看该作者
这个和51还是不是51没啥关系。
LZ应该先看datasheet。

xwj回答的比较完全

使用特权

评论回复
31
風神| | 2010-11-6 12:56 | 只看该作者
明白~~

使用特权

评论回复
32
5880527| | 2010-11-6 13:00 | 只看该作者
铁电可以一下子连续把整个器件写完的,用FM24CL64验证过

使用特权

评论回复
33
工大第二枪| | 2010-11-6 17:19 | 只看该作者
取决于被操作器件。比如EEPROM,最大可以连续写的字节数是一个PAGE的大小。有些事8个字节,有些是16个字节。

使用特权

评论回复
34
yp15147| | 2010-11-8 13:57 | 只看该作者
24c01,02 一次写入8Bytes    24c04,08,16   16bytes

使用特权

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

本版积分规则