OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5735|回复: 9

放一个AT24C02的连续写函数 另外求一个连续读的函数

[复制链接]

3

主题

6

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-3-11
在线时间
11 小时
发表于 2016-9-5 23:04:54 | 显示全部楼层 |阅读模式
本帖最后由 260998842 于 2016-9-7 00:40 编辑

IIC写字节等应答之类的基本函数用的是原子哥的,看原子哥的历程的时候发现每写一个字节都要重新写器件地址和数据地址,最后在写数据,刚好最近用工作用到了AT24C02,Datasheet上说AT24C02支持页写和页读(8字节),于是乎就写了一个AT240C02连续写的函数,判断写的字节数超过8以后才进行换页重写器件地址和数据地址,测试了之后发现速度这样速度快了不少(0~255全部重新,速度大概快了几秒钟)。扯个题外话..工作用的是4位机..汇编.. 模拟IIC...  写完了以后整个人都不好了...还是喜欢C...

[mw_shl_code=cpp,true]#define Device_Address_Write        0xA0        //器件地址 A1 A2 A3均接地 末位0写
#define Device_Address_Read                0xA1        //器件地址 A1 A2 A3均接地 末位1读        

//连续写AT24C02,一次最多8字节,此函仅供AT24C02_Write函数调用
//WriteAddress:起始地址
//Byte:要写入的字节(数组)
//ByteNumber:字节数
void AT24C02_Continuous_Write(u8 WriteAddress,u8 *Byte,u16 ByteNumber)
{
        u8 i;
        IIC_Start();
        IIC_Send_Byte(Device_Address_Write);                        //器件地址0xA0(写)
        IIC_Wait_Response();
        IIC_Send_Byte(WriteAddress);;                                        //数据地址
        IIC_Wait_Response();
        for(i=0;i<ByteNumber;i++)
        {
                IIC_Send_Byte(Byte);                                                        //一个字节
                IIC_Wait_Response();
        }        
        IIC_Stop();
        delay_ms(6);
}

//在指定位置写入ByteNumber个字节
//WriteAddress:起始地址
//Byte:要写入的字节(数组)
//ByteNumber:字节数
void AT24C02_Write(u8 WriteAddress,u8 *Byte,u16 ByteNumber)
{
        u8 PageRemain = 8-WriteAddress%8;
        
        if(ByteNumber<=PageRemain) PageRemain = ByteNumber;
        while(1)
        {        
                AT24C02_Continuous_Write(WriteAddress,Byte,PageRemain);
                if(PageRemain==ByteNumber) break;
                else
                {
                        WriteAddress+=PageRemain;
                        Byte+=PageRemain;
                        ByteNumber-=PageRemain;
                        if(ByteNumber<8) PageRemain = ByteNumber;
                        else PageRemain = 8;
                }
        }        
}[/mw_shl_code]
怎么样,看起来是不是跟FLASH的历程很像..没错..我的灵感就是从FLASH的历程里面来的....   
再来我要做伸手党了..   求一个IIC的连续写函数..
照理来说.能连续写 自然能连续读
但是...  连续读的时候只能读到第一个字节
之后读出来的全部都是0x00

[mw_shl_code=cpp,true]//连续读AT24C02,一次最多8字节,次函仅供AT24C02_Read函数调用
//WriteAddress:起始地址
//Byte:读出的字节(数组)
//ByteNumber:字节数
void AT24C02_Continuous_Read(u8 WriteAddress,u8 *Byte,u8 ByteNumber)
{
        u8 i;
        IIC_Start();
        IIC_Send_Byte(Device_Address_Write);                        //器件地址0xA0(写)
        IIC_Wait_Response();
        IIC_Send_Byte(WriteAddress);;                                        //数据地址
        IIC_Wait_Response();
        IIC_Start();                                                                        //第二次起始信号
        IIC_Send_Byte(Device_Address_Read);                                //器件地址0xA1(读)
        IIC_Wait_Response();
        for(i=0;i<ByteNumber;i++)
        {
                Byte = IIC_Read_Byte(1);                                                //读一个字节 参数1应答
        }
        IIC_Stop();

}

//在指定位置读取ByteNumber个字节
//WriteAddress:起始地址
//Byte:读到的字节(数组)
//ByteNumber:字节数
void AT24C02_Read(u8 WriteAddress,u8 *Byte,u8 ByteNumber)
{
        u8 PageRemain = 8-WriteAddress%8;
        
        if(ByteNumber<=PageRemain) PageRemain = ByteNumber;
        while(1)
        {
                AT24C02_Continuous_Read(WriteAddress,Byte,PageRemain);
                if(PageRemain==ByteNumber) break;
                else
                {
                        WriteAddress+=PageRemain;
                        Byte+=PageRemain;
                        ByteNumber-=PageRemain;
                        if(ByteNumber<8) PageRemain = ByteNumber;
                        else PageRemain = 8;
                }
        }        
}[/mw_shl_code]

我试过改过应答IIC_Read_Byte(1)和IIC_Read_Byte(0),甚至我就直接连着读了两个字节,结果都是这样,只能读到第一个字节,为什么不科学啊,我用汇编读AT24C02可以连续读8字节的
眼尖的帮忙看下哪里有问题? 还是说...不同厂商加工生产的AT24C02功能不一样的.....


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-9-6 12:51:21 | 显示全部楼层
确定你的连读符合IIC协议?
回复 支持 反对

使用道具 举报

3

主题

6

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-3-11
在线时间
11 小时
 楼主| 发表于 2016-9-7 00:39:15 | 显示全部楼层
八度空间 发表于 2016-9-6 12:51
确定你的连读符合IIC协议?

哪里有问题吗?
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-9-7 08:55:12 | 显示全部楼层

建议抓波形看下,然后对比你的软件逻辑
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

8

主题

169

帖子

0

精华

高级会员

Rank: 4

积分
564
金钱
564
注册时间
2015-7-4
在线时间
105 小时
发表于 2016-12-23 09:46:36 | 显示全部楼层
不懂,我也遇到同样的问题了
回复 支持 反对

使用道具 举报

5

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
284
金钱
284
注册时间
2016-8-5
在线时间
158 小时
发表于 2016-12-23 12:18:46 | 显示全部楼层
连读就一直给ACK、不读就NOACK
回复 支持 反对

使用道具 举报

7

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
745
金钱
745
注册时间
2016-1-20
在线时间
78 小时
发表于 2017-2-8 10:16:50 | 显示全部楼层
我也在写 也想连续,试试吧!
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2013-7-19
在线时间
15 小时
发表于 2017-11-30 14:17:39 | 显示全部楼层
其实是原子的程序有点小问题,是个小错误,在主机发送应答后没有将数据总线(SDA)释放掉(SDA = 1),一直被占用(低电平),所以再度数据就一直是0,只要将数据总线释放就OK了,其实每次操作总线后都应将总线释放,这才是正确的
回复 支持 反对

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-11-30 16:10:42 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2019-4-29
在线时间
9 小时
发表于 2019-12-22 13:53:06 | 显示全部楼层
BABY@-@FACE 发表于 2017-11-30 14:17
**** 作者被禁止或删除 内容自动屏蔽 ****

谢谢,看了一下  是的 谢谢
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 23:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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