51模拟i2c

[复制链接]
16305|33
yewuyi 发表于 2010-11-6 09:39 | 显示全部楼层
容许页写模式,则连续写入的最大字节数就是页面长度
一级菜鸟 发表于 2010-11-6 09:45 | 显示全部楼层
17# 一级菜鸟  
你意思,在写命令之后,应该加一个停止命令,然后开始命令,然后写?
lp1468 发表于 2010-11-6 09:25


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

死等是笨办法,耗时长,最主要移植性很差。
yewuyi 发表于 2010-11-6 09:47 | 显示全部楼层
写命令全部结束之后,发完停止命令,然后开始命令,这时候器件处于内部写周期,会收不到ACK,反复发送一直到ACK出现,表示器件内部操作已经完成,这时候可以读了。

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


死等的方式在IIC总线被挂死后,则会导致读写错误。
一级菜鸟 发表于 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;
}
一级菜鸟 发表于 2010-11-6 09:53 | 显示全部楼层
N年没有发过源代码,为你破个例,你要的是最后一个函数。
 楼主| lp1468 发表于 2010-11-6 11:00 | 显示全部楼层
先谢谢楼上了,你给了我理论依据。也就是说我要是连续写后直接读取数据是不行的,应该i2c器件还没有转化过来。对于连续写8字节数据了紧跟这写8字节数据也是不行的。
对于100K的传输模式写完后要等待大约1ms的时间才可以对i2c操作。
一级菜鸟 发表于 2010-11-6 11:09 | 显示全部楼层
26# lp1468

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

还是那句话,跟具体的器件有关系。
一级菜鸟 发表于 2010-11-6 11:12 | 显示全部楼层
例如这一款

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| lp1468 发表于 2010-11-6 11:14 | 显示全部楼层
19# xwj
唉!没有看到xwj的精彩回复,让我想了很久,哈哈!xwj正解。
shizaigaole 发表于 2010-11-6 11:21 | 显示全部楼层
这个和51还是不是51没啥关系。
LZ应该先看datasheet。

xwj回答的比较完全
風神 发表于 2010-11-6 12:56 | 显示全部楼层
明白~~
5880527 发表于 2010-11-6 13:00 | 显示全部楼层
铁电可以一下子连续把整个器件写完的,用FM24CL64验证过
工大第二枪 发表于 2010-11-6 17:19 | 显示全部楼层
取决于被操作器件。比如EEPROM,最大可以连续写的字节数是一个PAGE的大小。有些事8个字节,有些是16个字节。
yp15147 发表于 2010-11-8 13:57 | 显示全部楼层
24c01,02 一次写入8Bytes    24c04,08,16   16bytes
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
0