野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10017|回复: 6

I2C_EEPROM裸机程序的疑惑

[复制链接]
发表于 2015-7-25 18:14:41 | 显示全部楼层 |阅读模式
火哥,你好,我在学习I2C协议时参考了你的MINI板的裸机I2C-EEPROM的例程,发现似乎有点错误,在I2C_EE_BufferWrite()函数中,源代码如下:
void  I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
{
        u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

        Addr = WriteAddr % I2C_PageSize;        //知道在新的一页中需要多少的字节
        count = I2C_PageSize - Addr;                //知道在新的页中还剩下多少的字节
        NumOfPage =  NumByteToWrite / I2C_PageSize;        //这里求出要写入的页数
        NumOfSingle = NumByteToWrite % I2C_PageSize;        //求出在新的页还要写入的字节数

        /* If WriteAddr is I2C_PageSize aligned  */
        if(Addr == 0)                                   //当刚好在一个页的开始处
        {
                if(NumOfPage == 0)          //如果在一页的最开始处,同时一页够写
                {
                        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                        I2C_EE_WaitEepromStandbyState();
                }
                else  
                {
                        while(NumOfPage--)           //如果在一页的开头,但是一页不够写
                        {
                                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                                I2C_EE_WaitEepromStandbyState();
                                WriteAddr +=  I2C_PageSize;
                                pBuffer += I2C_PageSize;
                        }

                        if(NumOfSingle!=0)          //多余的字节数
                        {
                                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                                I2C_EE_WaitEepromStandbyState();
                        }
                }
        }
        else                                                   //存储地址不在一个页的开头
        {
                if(NumOfPage== 0)                       //例如:有可能只需要7的字节,但是开始的地址在一个页的第三个字节处,似乎就不能这样直接写入了
                {
                        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                        I2C_EE_WaitEepromStandbyState();
                }
                else
                {
                        NumByteToWrite -= count;
                        NumOfPage =  NumByteToWrite / I2C_PageSize;
                        NumOfSingle = NumByteToWrite % I2C_PageSize;       

                        if(count != 0)
                        {  
                                I2C_EE_PageWrite(pBuffer, WriteAddr, count);
                                I2C_EE_WaitEepromStandbyState();
                                WriteAddr += count;
                                pBuffer += count;
                        }

                        while(NumOfPage--)
                        {
                                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                                I2C_EE_WaitEepromStandbyState();
                                WriteAddr +=  I2C_PageSize;
                                pBuffer += I2C_PageSize;  
                        }
                        if(NumOfSingle != 0)
                        {
                                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                                I2C_EE_WaitEepromStandbyState();
                        }
                }
        }  
}

也许是我错吧,希望火哥能指导下,谢谢!
同时火哥,我有点疑问:以前直接把外设裸机的驱动代码加载进uc/oss和enWin的工程中就可以使用了,但是就只这EEPROM的加载进去后执行不了。
回复

使用道具 举报

发表于 2015-7-26 16:52:41 | 显示全部楼层
123.jpg
楼主好 这是我对这部分的 更改 你可以参考下。
另外 我对Addr的注释与你不同 ,我认为其意为 该页的写入地址(从这页哪开始写)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-7-26 18:48:39 | 显示全部楼层
yangli 发表于 2015-7-26 16:52
楼主好 这是我对这部分的 更改 你可以参考下。
另外 我对Addr的注释与你不同 ,我认为其意为 该页的写入 ...

那四个变量我们表达的意思都是一样的:前两个变量确定写入地址(下面简称为地址)的信息(addr:确定地址在写入页中的位置;count:确定地址所在页之后还有可用多少字节);后两个变量确定要写入的页数和多余量的信息(但是我觉地这信息是在一个前提下才是正确的:刚好从一页的最开始处写入,就是在“addr==0”是正确的,之后就要改了),我改的代码是如下的,“addr==0”是正确的,关键是在else之后的部分,
        else                         //存储地址不在一个页的开头
        {
                if(count>=NumByteToWrite)             //如果开始的那一页能写完
                {
                        I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
                        I2C_EE_WaitEepromStandbyState();                       
                }
                else                                                  //如果开始那也不能写完,需要换页
                {
                        NumByteToWrite=NumByteToWrite-count;   //得除开始那页所剩字节外,还需要多少
                        NumOfPage=NumByteToWrite/I2C_PageSize; //其实就装换成:上面情况了+写完开始页所剩字节
                        NumOfSingle = NumByteToWrite % I2C_PageSize;

                        I2C_EE_PageWrite(pBuffer, WriteAddr, count); //写完开始页所剩自己(因为一定要换页的)
                        I2C_EE_WaitEepromStandbyState();
                        WriteAddr += count;              
                        pBuffer += count;

                        for(;NumOfPage>0;NumOfPage--)   //写入开始页之后的部分
                        {
                                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                                I2C_EE_WaitEepromStandbyState();
                                WriteAddr += I2C_PageSize;
                                pBuffer += I2C_PageSize;                               
                        }
                }
                if(NumOfSingle != 0)       //写入剩余量
                {
                        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                        I2C_EE_WaitEepromStandbyState();
                }
}
回复 支持 1 反对 0

使用道具 举报

发表于 2015-8-20 15:14:31 | 显示全部楼层
觉得你们说的是对的,但火哥的程序对不对呢?还有void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)这个程序里面是没有用到的吧啊?
回复 支持 反对

使用道具 举报

发表于 2015-8-26 18:16:24 | 显示全部楼层
今天看了这部分的内容,火哥写的确实有问题,明天验证一下
回复 支持 反对

使用道具 举报

发表于 2015-8-27 17:52:24 | 显示全部楼层
本帖最后由 celes 于 2015-8-27 17:53 编辑

学习STM32 I2C模块时候,发现问题,做了以下测试,首先擦除EEPROM全部写零,并按原历程验证一遍读写正确。然后设置EEP_Firstpage_1 = 0x04;从地址4开始从0到6写7个数进去,读的时候从EEP_Firstpage = 0开始读整片EEPROM,通过串口助手看结果,在分好页的情况应该是第一页 00 00 00 00 00 01 02 03  第二页是04 05 06 00 00 00 00 00 第三页00。。。现测试出来如下图,第一页直接是04 05 06 00 00 01 02 03,也就是没分到下一页。火哥这边页没有分好是吧???

我的测试结果 今天也发帖问了  没确切回复哦  火哥历程里面关于SPI这部分的和I2C也一样  可以参考下面yangli的看看 QQ图片20150827125301.jpg
回复 支持 反对

使用道具 举报

发表于 2016-1-7 15:27:12 | 显示全部楼层
这里的代码火哥好像写得不对,不过可以自己重新写一个的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-27 13:34 , Processed in 0.090477 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表