搜索
bottom↓
回复: 152

通用24CXXX读写程序(GCC),兼容24C系列存储器(24C01到24C1024),支持跨器件跨页读写,支持连续

  [复制链接]

出0入0汤圆

发表于 2009-7-8 21:10:19 | 显示全部楼层 |阅读模式
我自己写了一个读写24CXXX的程序,兼容24C系列存储器(24C01到24C1024),支持多页读写,最多连续写32K字节,不知如何,请帮忙测试一下!

详见7楼

图:

(原文件名:未命名.JPG)

程序程序已经更新至V0.2:
点击此处下载 ourdev_459683.rar(文件大小:5K) (原文件名:24CXXX.rar)

谢谢!!!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2009-7-8 23:07:18 | 显示全部楼层
好,收下!

出0入0汤圆

发表于 2009-7-8 23:26:18 | 显示全部楼层
感觉24C有个不是很爽的地方。
同一个系列,dataAddress有些是byte,有些是word。
搞的一个程序接口无法兼容所有系列。

出0入0汤圆

发表于 2009-7-8 23:41:10 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2009-7-9 07:19:49 | 显示全部楼层
对的,对于24X1024,地址要超过2字节,正在解决这个问题,我就是想把程序做的通用写
只需要定义IO,芯片类型,芯片数量,就可以直接操作!争取中午或晚上上传最新程序!

出0入0汤圆

发表于 2009-7-9 07:38:24 | 显示全部楼层
有空测试一下。

出0入0汤圆

 楼主| 发表于 2009-7-9 07:41:25 | 显示全部楼层
【5楼】 ecat 电子猫

谢谢!正在继续修改,主要是把程序弄得通用些!

出0入0汤圆

 楼主| 发表于 2009-7-9 11:06:25 | 显示全部楼层
修改了程序,使得其能运行所有24C系列存储器(24C01到24C1024),我使用Proteus仿真了24C512,没有发现问题,欢迎大家测试,并提出使用意见和程序BUG!
程序有注释应该可以比较容易的看懂!

使用说明:
建立工程后,只需要修改24CXXX.h和IIC.h中的宏

24CXXX.h
//接口定义及操作
#define _24CXXX_WP_DDR                DDRB
#define _24CXXX_WP_PORT                PORTB
#define _24CXXX_WP                5                //定义WP所处IO位置,如果>7 表示不使用该IO口

//*************************************************************************
//需要自定义修改区域
//设定芯片型号------
#define DEV_24CXX_MODLE        _24C512                        //定义器件类型
#define DEV_24CXX_NUM        2                        //定义器件数量
//*************************************************************************



IIC.h
//端口定义及操作
#define IIC_SCK_DDR                DDRB
#define IIC_SCK_PORT                PORTB
#define IIC_SCK                        7


#define IIC_SDA_DDR                DDRB
#define IIC_SDA_PORT                PORTB
#define IIC_SDA_PIN                PINB
#define IIC_SDA                        6

做完以上定义就可以直接使用函数读写了,包括单字节读写和多字节读写(最多可以连续写32K)!



点击此处下载 ourdev_459683.rar(文件大小:5K) (原文件名:24CXXX.rar)

出0入0汤圆

 楼主| 发表于 2009-7-9 11:24:18 | 显示全部楼层
【2楼】 kanprin 萧威
兼容所有器件24C01-24C1024

出0入0汤圆

 楼主| 发表于 2009-7-10 17:34:40 | 显示全部楼层
自己顶一下吧,沉了!!

出0入0汤圆

 楼主| 发表于 2009-7-14 09:17:51 | 显示全部楼层
ST7920控制器LCD12864源代码,有画点、画线功能
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3424320&bbs_page_no=1&search_mode=3&search_text=jackielau&bbs_id=9999

出0入0汤圆

发表于 2009-7-14 22:11:25 | 显示全部楼层
初步测试了一下,用M48读写24C512,指定地址的读写,没发现问题。
但编译时,第一次总有警告,还没去细查。

出0入0汤圆

 楼主| 发表于 2009-7-17 12:46:44 | 显示全部楼层
【11楼】 ecat 电子猫
谢谢LS。
警告是有的,在Mydelay。h中就有,判断时钟频率的!
可以看看连续读写,最多可以一次读写32K(还没验证过,因为没有那么大的RAM啊!呵呵),不过一般读几百字节还是挺方便的!

出0入0汤圆

发表于 2009-7-28 10:07:14 | 显示全部楼层
非常感谢,马上试试

出0入0汤圆

发表于 2009-7-28 10:22:26 | 显示全部楼层
int main(void)

{
DDRA=255;
_24CXXX_init();
_24CXXX_AddrProcess(0xFFFF);

_24CXXX_WriteByte(0x0F11,0xAA);
_delay_ms(45);
PORTA=_24CXXX_ReadByte(0x0F11);
   while(1);
   
     return 0;
   
}
用测试程序仿真试了一下,没发现任何问题
晚上上硬件试,谢谢楼主先!

=========================
连续读好像有问题

void IIC_Start()
{
        IIC_SCK_OUT();
        IIC_SDA_OUT();
        IIC_SCK_HIGH();
        IIC_SDA_HIGH();

        DelayUs(4);
        IIC_SDA_LOW();
        DelayUs(4);
        IIC_SCK_LOW();
        DelayUs(4);
}
这个函数有点问题,在发Start信号前会先发STOP,所以连续读有些问题哈,可能我 说得不对,请指点

====================================

的确会发STOP,但没什么问题!已经调通,可以使用,移植性相当不错,赞!

出0入0汤圆

发表于 2009-7-28 11:11:14 | 显示全部楼层
谢谢!标记

出0入0汤圆

发表于 2009-7-28 11:52:48 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2009-7-28 13:54:50 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2009-7-28 15:19:14 | 显示全部楼层
【14楼】 poqpoqpoq
我用proteus仿真时,使用I2C分析仪,的确会出现你说的问题,但是读写正常呢!

出0入0汤圆

 楼主| 发表于 2009-7-28 15:22:13 | 显示全部楼层
最新版本正在修改,加入两个功能1、检测EEPROM是否存在 2、I2C总线速度选择(100K、400KHz),1M不好实现有点难啊!!呵呵

呵呵 希望斑竹给个COOL啊!!嘿嘿

出0入0汤圆

发表于 2009-7-28 15:24:33 | 显示全部楼层
标记

出0入0汤圆

发表于 2009-7-28 15:35:25 | 显示全部楼层
【14楼】 poqpoqpoq
我用proteus仿真时,使用I2C分析仪,的确会出现你说的问题,但是读写正常

的确,哑字节的功能我估计是移动指针,所以读写都没问题,呵呵,要解决也 很 容易,
void IIC_Start()
{
        IIC_SCK_OUT();
        IIC_SDA_OUT();

        IIC_SDA_HIGH();
        IIC_SCK_HIGH();        //对调这2个语句就OK了
        

        DelayUs(4);
        IIC_SDA_LOW();
        DelayUs(4);
        IIC_SCK_LOW();
        DelayUs(4);
}

SDA线上一定要上拉,否则只能读出一个数,呵呵,上拉后一切OK,晚上回家上硬件试去

出0入0汤圆

 楼主| 发表于 2009-7-28 15:43:11 | 显示全部楼层
【21楼】 poqpoqpoq
现在手头上没有那个程序,呵呵,晚上有事!
你先试试吧  呵呵 谢谢了

出0入0汤圆

发表于 2009-7-28 19:48:01 | 显示全部楼层
调试OK了


软件仿真 (原文件名:1.JPG)


这个就不用说了 (原文件名:图片 003.jpg)


马老师的板子 (原文件名:图片 002.jpg)


没什么问题,第二行显示出从ATMUL802中读出的一句字符 (原文件名:图片 001.jpg)

//主函数  
int main(void)
{
   uchar str[16]="nihao!woshipeng!",comp[16];  

   init_devices();




   
//toascii(add)函数是把整数转ascii码,itoa把整数转字符串,ultoa长整
  
_24CXXX_AddrProcess(0xFFFF);
_24CXXX_WriteBytes(0X0000,str,16);
_delay_ms(45);
_24CXXX_ReadBytes(0x0000,comp,16);
LCD_write_string(1,0,"To be welcome!");
LCD_write_string(0,1,comp);
while(1);
        return 0;
}
上面是程序,1602四线只写方式,用了6个IO,24C再用2个,真是方便啊!很感谢楼主!建议穿裤!!

出0入0汤圆

发表于 2009-7-28 21:32:34 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2009-7-29 09:08:28 | 显示全部楼层
【23楼】 poqpoqpoq

感谢帮忙测试!


_24CXXX_AddrProcess(0xFFFF);
_24CXXX_WriteBytes(0X0000,str,16);

函数_24CXXX_AddrProcess(0xFFFF); 不需要调用,这是在读写函数中使用的,对于用户不可见

置酷是版主们的事情啊!希望能酷一下!呵呵

出0入0汤圆

发表于 2009-7-29 10:02:33 | 显示全部楼层
绝对有资格给条裤子了!

出0入0汤圆

发表于 2009-7-29 10:56:42 | 显示全部楼层
顶起来,看看

出0入93汤圆

发表于 2009-7-29 11:08:19 | 显示全部楼层
不错

出0入0汤圆

发表于 2009-7-29 11:15:19 | 显示全部楼层
支持

出0入0汤圆

 楼主| 发表于 2009-7-29 11:41:22 | 显示全部楼层
【28楼】 friendljy
【29楼】 csclz

感谢支持!

出0入0汤圆

 楼主| 发表于 2009-7-29 17:06:28 | 显示全部楼层
【21楼】 poqpoqpoq

“void IIC_Start()  
{  
        IIC_SCK_OUT();  
        IIC_SDA_OUT();  

        IIC_SDA_HIGH();  
        IIC_SCK_HIGH();        //对调这2个语句就OK了

IIC_SCK_OUT();  
IIC_SDA_OUT();

IIC_SDA_HIGH();  
IIC_SCK_HIGH();
对调一下就不出现该问题开了!!

出0入0汤圆

发表于 2009-8-25 15:16:54 | 显示全部楼层
谢谢!
本贴是我试验过的模拟读写24CXXX最好的代码(WINAVR)。网上(包括本站)提供的代码(WINAVR)
基于 TWI 查询方式的几乎没有能对24C01到24C1024 (proteu s)仿真都成功的,
仅仅只对某个器件能行.不知道是怎么回事

出0入0汤圆

发表于 2009-8-25 15:18:34 | 显示全部楼层
专门注册顶楼主一下

出0入0汤圆

发表于 2009-8-25 15:22:33 | 显示全部楼层
不错 ,
再搞个S FLASH的,也弄成通用的

出0入0汤圆

 楼主| 发表于 2009-8-27 15:28:44 | 显示全部楼层
34楼
什么是“S FLASH”啊??不明白

出0入0汤圆

发表于 2009-8-28 14:52:05 | 显示全部楼层
搞不懂为什么该贴还没有置酷?

出0入0汤圆

 楼主| 发表于 2009-8-28 15:35:53 | 显示全部楼层
【36楼】 ecat 电子猫
呵呵 ,因为你不是版主啊!?呵呵

出0入0汤圆

发表于 2009-8-28 23:04:26 | 显示全部楼层
好帖子,楼主的探究精神值得学习

出0入0汤圆

 楼主| 发表于 2009-12-12 17:18:37 | 显示全部楼层
最新消息,本代码已成功应用于一个项目当中,两片24C512!运行3个月了,还好,暂时没发现问题!!!

出0入0汤圆

发表于 2009-12-12 17:26:46 | 显示全部楼层
支持一下

出0入0汤圆

发表于 2009-12-12 17:33:40 | 显示全部楼层
顶顶!

出0入0汤圆

发表于 2009-12-19 18:05:58 | 显示全部楼层
学习
谢谢!

出0入0汤圆

发表于 2009-12-29 18:32:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-21 13:21:56 | 显示全部楼层
xue xi le

出0入0汤圆

发表于 2010-3-21 13:54:41 | 显示全部楼层
学习了!

出0入0汤圆

发表于 2010-3-30 16:39:32 | 显示全部楼层
目前在学习T2C的通讯方式,有利东西。。。

出0入0汤圆

发表于 2010-3-30 20:49:46 | 显示全部楼层
mark O(∩_∩)O

出0入0汤圆

发表于 2010-4-26 14:52:01 | 显示全部楼层
mark

出0入85汤圆

发表于 2010-4-26 17:13:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-14 20:49:31 | 显示全部楼层
绝对的好东西,我移植在mega8上,测试完全正常,楼主,感谢,期待至酷!!!

出0入0汤圆

发表于 2010-5-14 21:52:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-14 23:56:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-15 08:01:36 | 显示全部楼层
回复【楼主位】jackielau 九天
-----------------------------------------------------------------------

Mark!!!!!

出0入0汤圆

发表于 2010-5-18 22:14:19 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2010-6-29 17:26:57 | 显示全部楼层
回复【50楼】chinakernel  
绝对的好东西,我移植在mega8上,测试完全正常,楼主,感谢,期待至酷!!!
-----------------------------------------------------------------------

呵呵 ,感谢测试

出0入0汤圆

发表于 2010-6-29 19:48:38 | 显示全部楼层
回复【50楼】chinakernel   
绝对的好东西,我移植在mega8上,测试完全正常,楼主,感谢,期待至酷!!!
-----------------------------------------------------------------------


好呀

出0入0汤圆

 楼主| 发表于 2010-6-29 20:59:57 | 显示全部楼层
最近买了个24MHz 虚拟逻辑分析仪,实测了一下!!不过,这个软件不能截图,也不能保存成图片格式!

出0入0汤圆

发表于 2010-7-26 18:06:26 | 显示全部楼层
楼主大侠好,请问用PIC16F716 如何读写24C01.先谢啦。

出0入0汤圆

发表于 2010-7-26 19:00:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-26 19:30:40 | 显示全部楼层
回复【23楼】poqpoqpoq
-----------------------------------------------------------------------
我把他移植到51上怎么不能实现连续写啊
写一个字节是正常的。不知道为什么啊

出0入0汤圆

发表于 2010-7-26 19:32:42 | 显示全部楼层
#include "config.h"

unsigned char sw[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
unsigned char pus[16];
void init()
{         
        TMOD=0X21;        //定时器1为波特率发生,定时器0为16位定时,方式1
        TL1=TH1=0XFA;        //9600和上位机通信 (晶振22.1184M)
        TR1=1;//开启定时器1

        TH0=0x00;  //初始化定时器0
          TL0=0x00;
          
        SM0=0;  //串口工作方式1
        SM1=1;                                                                  
        REN=1; //允许串口接收         //REN使能必须在工作方式设置好之后,否则会出现乱码         

        PS=1;   //串口中断优先   

        IT0=1;   //外部中断下降沿触发

        EA=1;//开始所有中断          
        ES=1;//开启串口中断          
        ET0=1;//开启定时器0中断       
        EX0=1;  //开启外部中断           
                                                                                       
}

void SBUF_byte(unsigned char i)
{
        REN=0;                                //关闭串口接收            
        ES=0;                                //关串口中断,防止在发送完数据后又进入中断服务程序          

           SBUF=i;
           while(!TI);
    TI=0;  
          
        REN=1;
        ES=1;
}

void main(void)

{
unsigned char i;
init();
_24CXXX_init();

_24CXXX_WriteByte(0x0F11,0xAA);
DelayMs(45);
SBUF_byte(_24CXXX_ReadByte(0x0F11));

_24CXXX_WriteBytes(0,sw,16);
DelayMs(45);
_24CXXX_ReadBytes(0,pus,16);
for(i=0;i<16;i++)
{
SBUF_byte(pus);
}
   while(1);
   
}

出0入0汤圆

发表于 2010-7-26 19:33:29 | 显示全部楼层
请大家帮忙看一下啊,问题出在哪里?

出0入0汤圆

 楼主| 发表于 2010-7-26 21:17:09 | 显示全部楼层
回复【58楼】sxbsmile  
楼主大侠好,请问用pic16f716&#160;如何读写24c01.先谢啦。
-----------------------------------------------------------------------

你需要修改几个文件
1.
24CXXX。h中关于WP操作的部分
//接口定义及操作
#define _24CXXX_WP_DDR                DDRD
#define _24CXXX_WP_PORT                PORTD
#define _24CXXX_WP                        4                //定义WP所处IO位置,如果>7 表示不使用WP

#if _24CXXX_WP < 8
#define _24CXXX_WP_OUT()        _24CXXX_WP_DDR |= (1<<_24CXXX_WP)
#define _24CXXX_WP_HIGH()        _24CXXX_WP_PORT        |= (1<<_24CXXX_WP)
#define _24CXXX_WP_LOW()        _24CXXX_WP_PORT        &= ~(1<<_24CXXX_WP)
#else
#define _24CXXX_WP_OUT()        asm("nop");
#define _24CXXX_WP_HIGH()        asm("nop");
#define _24CXXX_WP_LOW()        asm("nop");
#endif        //#if _24CXXX_WP < 8
#define _24CXXX_WR_EN()                _24CXXX_WP_LOW()
#define _24CXXX_WR_DIS()        _24CXXX_WP_HIGH()

2.
IIC.h关于IO操作的一些宏定义
//端口定义及操作
#define IIC_SCK_DDR                DDRD
#define IIC_SCK_PORT        PORTD
#define IIC_SCK                        5
#define IIC_SCK_OUT()        IIC_SCK_DDR |= (1<<IIC_SCK)
#define IIC_SCK_HIGH()        IIC_SCK_PORT        |= (1<<IIC_SCK)
#define IIC_SCK_LOW()        IIC_SCK_PORT        &= ~(1<<IIC_SCK)

#define IIC_SDA_DDR                DDRD
#define IIC_SDA_PORT        PORTD
#define IIC_SDA_PIN                PIND
#define IIC_SDA                        6
#define IIC_SDA_OUT()        IIC_SDA_DDR |= (1<<IIC_SDA)
#define IIC_SDA_IN()        IIC_SDA_DDR &= ~(1<<IIC_SDA)
#define IIC_SDA_HIGH()        IIC_SDA_PORT        |= (1<<IIC_SDA)
#define IIC_SDA_LOW()        IIC_SDA_PORT        &= ~(1<<IIC_SDA)
#define IIC_SDA_GET()        (IIC_SDA_PIN&(0x01<<IIC_SDA))

3.修改延时函数DelayUs();

出0入0汤圆

发表于 2010-7-26 21:23:04 | 显示全部楼层
mark,明天试试

出0入0汤圆

 楼主| 发表于 2010-7-26 21:27:49 | 显示全部楼层
回复【62楼】cy371  
请大家帮忙看一下啊,问题出在哪里?
-----------------------------------------------------------------------

我也说不好,建议你用proteus仿真一下,里面有IIC分析仪,可以方便的找的问题所在

出0入0汤圆

 楼主| 发表于 2010-7-26 21:30:14 | 显示全部楼层
另外,希望一直到其他MCU的各位,能把移植后的代码上传到本贴,方便大家
如果能说出移植时遇到的问题就更好了,如果存在大的问题我也好修改代码,谢谢!

出0入0汤圆

发表于 2010-7-26 22:36:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-2 13:45:38 | 显示全部楼层
/*在找资料的过程中无意发现了这强帖,就想问楼主一下有关I2C读写eeprom的问题,下列的代码只能写,读出的数据都是0xff,找了很久不知道是哪里出了问题,想问下呀。*/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

#define e2prom 8                // <---在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512

#if e2prom==1
        #define PAGE_SIZE 8
        #define SIZE 0x007f
#elif e2prom==2
        #define PAGE_SIZE 8
        #define SIZE 0x00ff
#elif e2prom==4
        #define PAGE_SIZE 16
        #define SIZE 0x01ff
#elif e2prom==8
        #define PAGE_SIZE 16
        #define SIZE 0x03ff
#elif e2prom==16
        #define PAGE_SIZE 16
        #define SIZE 0x07ff
#elif e2prom==32
        #define PAGE_SIZE 32
        #define SIZE 0x0fff
#elif e2prom==64
        #define PAGE_SIZE 32
        #define SIZE 0x1fff
#elif e2prom==128
        #define PAGE_SIZE 64
        #define SIZE 0x3fff
#elif e2prom==256
        #define PAGE_SIZE 64
        #define SIZE 0x7fff
#elif e2prom==512
        #define PAGE_SIZE 128
        #define SIZE 0xffff
#endif


#define W_ADD_COM 0xa0                //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa1                //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
//-------------------------------



#define SLAW        0x18                //SLA_W 已正常发送代码,判断器件是否正常应答的常量.

#define ERR_SLAW        10                //写字节命令及器件地址错, 在此也就是读写器件错!!

uint8_t * wt24c_fc(uint8_t *p, uint16_t ad, uint8_t n);        //向24Cxx写入数据wt24c_h()所要调用的函数

extern uint8_t mRxData[10];
extern uint8_t CompSeat;
extern uint8_t buffer[8];
uint8_t syserr;
uint8_t Clear_buffer[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

void Twi_init(void)
{
TWCR= 0X00; //disable twi
TWBR= 0x20; //set bit rate
TWSR= 0x00; //set prescale
TWAR= 0x00; //set slave address
TWCR= 0x04; //enable twi
}

//-------------------------------以下为其它I2总线器件可调用的函数--------------------------

/********************************************************************************************************
函数描述:总线上起动开始条件
输入参数:无
返回参数:无
*********************************************************************************************************/
void I2C_Start(void)
{
        TWCR= (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
           while (!(TWCR & (1<<TWINT)));
}
/********************************************************************************************************
函数描述:把一个字节数据输入器件, 返回TWI状态
输入参数:一个字节数值=a
返回参数:状态
*********************************************************************************************************/
uint8_t I2C_Wt(uint8_t a)
{
        TWDR = a;
           TWCR = (1<<TWINT) | (1<<TWEN);
           while (!(TWCR & (1<<TWINT)));
           return(TWSR&0b11111000);
}

/********************************************************************************************************
函数描述:从器件读出一个字节
输入参数:无
返回参数:读出数值
*********************************************************************************************************/
uint8_t I2C_Rd(void)
{
           TWCR= (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
           while (!(TWCR & (1<<TWINT)));
           return(TWDR);
}

/********************************************************************************************************
函数描述:总线上起动停止条件
输入参数:无
返回参数:无
*********************************************************************************************************/
void I2C_Stop(void)
{
  TWCR= (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}

/*********************************************************************************************
函数描述:        向24Cxx写入数据
参数:                 *p_rsc要输出数据的主机内存地址指针; ad_dst要写入数据的i2c的地址(双字节); num数据个数
参数条件:         ad_dst: ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
**********************************************************************************************/
void Write_24c08(uint8_t *p_rsc, uint16_t ad_dst, uint16_t num)
{   uint16_t n;

    n=ad_dst/PAGE_SIZE;                                //确定地址与块地址的差

        if(n)
        {
                 n=(uint32_t)PAGE_SIZE*(n+1)-ad_dst;
        }       
        else
        {
                n=PAGE_SIZE-ad_dst;
        }

    if(n>=num)                                                //如果ad_dst所在的数据块的末尾地址 >= ad_dst + num, 就直接写入num个数据
    {
                wt24c_fc(p_rsc, ad_dst, num);
            if(syserr!=0) return;
    }
    else                                                        //如果ad_dst所在的数据块末尾地址 < ad_dst + num, 就先写入ad_dst所在的数据块末尾地址与 ad_dst 之差个数据
    {   
                p_rsc=wt24c_fc(p_rsc, ad_dst, n);
            if(syserr!=0) return;
                num-=n;                                     //更新剩下数据个数
        ad_dst+=n;                                        //更新剩下数据的起始地址

                                                                //把剩下数据写入器件
        while(num>=PAGE_SIZE)                //先按PAGE_SIZE为长度一页一页的写入
        {
                        p_rsc=wt24c_fc(p_rsc, ad_dst, PAGE_SIZE);
                if(syserr!=0) return;
               
            num-=PAGE_SIZE;                        //更新剩余数据个数
                ad_dst+=PAGE_SIZE;                //更新剩下数据的起始地址
                }
        
                if(num)                                                //把最后剩下的小于一个PAGE_SIZE长度的数据写入器件
                        wt24c_fc(p_rsc, ad_dst, num);
    }
}


/*****************************************************************************************************
函数描述:        从24cxx读出数据
参数:                 *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形)
参数条件:          ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
*****************************************************************************************************/
void Read_24c08(uint8_t *p_dst, uint16_t ad_rsc, uint16_t num)
{   uint8_t t=0;

        #if e2prom<32
        t=ad_rsc>>8;
        t<<=1;
        #endif
               
        I2C_Start();                                                //发送起始信号

        if(I2C_Wt(W_ADD_COM+t)==SLAW)                //发送SLA_W, 写字节命令及器件地址
        {       
                #if e2prom>16
                I2C_Wt(ad_rsc>>8);                                //ad_rsc的高位,  发送要读出数据的地址
                #endif

                I2C_Wt(ad_rsc);                                        //ad_rsc的低位       
                I2C_Start();                                        //再发送起始信号
                I2C_Wt(R_ADD_COM+t);                        //发送SLA_R, 读命令字节及器件地址
                               
                for(;num>0;num--)
                {  
                        *p_dst=I2C_Rd();                        //从器件读出一个字节
                        p_dst++;
                }
        }       
        else syserr=ERR_SLAW;                                //写字节命令及器件地址错或对方无应答
               
        I2C_Stop();

}

/*************************************************************************************************
函数描述:        向24Cxx写入数据wt24c_h()所要调用的函数
参数:
返回参数:        写入n个字节后的主机内存指针
**************************************************************************************************/
uint8_t * wt24c_fc(uint8_t *p, uint16_t ad, uint8_t n)
{        uint8_t t=0;

        #if e2prom<32
        t=ad>>8;
        t<<=1;
        #endif
       
        I2C_Start();                                        //发送起始信号
               
        if(I2C_Wt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
        {       
                #if e2prom>16
                I2C_Wt(ad>>8);                        //ad_dst的高位到器件
                #endif
                I2C_Wt(ad);                        //ad_dst的低位到器件
                       
                for(;n>0;n--)                        //发送要写入的数据
                {   I2C_Wt(*p);
                        p++;
                }
        }
        else syserr=ERR_SLAW;                //写字节命令及器件地址错
       
        I2C_Stop();
    _delay_ms(6);                                //延时6ms
       
        return(p);
}
/*************************************************************************************************
函数描述:        清楚24c08
参数:                无
返回参数:        无
**************************************************************************************************/
void Clear_24c08(void)
{
        uint16_t i;

        for(i=0;i<100;i++)
        {
                 Write_24c08(Clear_buffer, i*16, 16);
        }

}

出0入0汤圆

发表于 2010-8-6 17:13:19 | 显示全部楼层
好东西啊 mark

出0入0汤圆

 楼主| 发表于 2010-8-10 21:53:39 | 显示全部楼层
回复【68楼】wenzi0595  
/*在找资料的过程中无意发现了这强帖,就想问楼主一下有关i2c读写eeprom的问题,下列的代码只能写,读出的数据都是0xff,找了很久不知道是哪里出了问题,想问下呀。*/
#include&#160;&lt;avr/io.h&gt;
#include&#160;&lt;avr/signal.h&gt;
#include&#160;&lt;avr/interrupt.h&gt;
#include&#160;&lt;avr/delay.h&gt;

#define&#160;e2prom&#160;8                //&#160;&lt;---在此设定芯片型号,&#160;1代表24c01;&#160;16代表24c16;&#160;512代表24c512

#if&#160;e2prom==1
        #define&#160;page_size&#160;8
        #define&#160;size&#160;0x007f
#elif&#160;e2prom==2
        #define&#160;page_size&#160;8
        #define&#160;size&#160;0x......
-----------------------------------------------------------------------
proteus仿真一下,里面有IIC分析仪,可以发现逻辑和时序的问题

出0入0汤圆

发表于 2010-9-10 19:47:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-11 00:34:44 | 显示全部楼层
试试看

出0入0汤圆

发表于 2010-9-11 08:28:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-11 09:32:22 | 显示全部楼层
早上过来的确调通了  我的环境是atmega128
现在正在完善   呵呵  谢谢 楼主   
这的确是我见过的软件模拟读写24c系列最好的帖子了

出0入0汤圆

发表于 2010-9-11 10:53:55 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-9-11 14:09:37 | 显示全部楼层
不错!!!!!!!!!!11

出0入0汤圆

 楼主| 发表于 2010-9-19 09:15:43 | 显示全部楼层
自己庆贺一下,庆祝至酷!

出0入0汤圆

发表于 2010-10-13 21:49:05 | 显示全部楼层
非常好的东东,谢谢楼主

出0入57汤圆

发表于 2010-10-13 22:38:48 | 显示全部楼层
好东西记号!!!!

出0入0汤圆

发表于 2010-10-18 13:26:22 | 显示全部楼层
请问楼主,我吧芯片数量定义成一个512时,编译出现如下的警告:
AT24CX.C(49): warning C280: 'Addr': unreferenced local variable
提示的在如下的函数里面:

//地址处理函数,主要处理多芯片时,对于地址的处理
#if DEV_24CXX_MODLE == _24C1024
        #if MAX_ADDR > 0xFFFF        //如果地址大于65535
        void _24CXXX_AddrProcess(unsigned long Addr)
        #else
        void _24CXXX_AddrProcess(unsigned int Addr)
        #endif        //#if MAX_ADDR > 0xFFFF
        {
                if( Addr>( (MEM_SIZE+1)/2-1 ) )        //如果地址大于65535
                {
                        Addr /= (MEM_SIZE+1)/2;
                }
                else
                {
                        Addr = 0x00;
                }

                HardAddr = Addr;
        }
#else
        #if DEV_24CXX_NUM > 1        //如果使用多个芯片
                #if MAX_ADDR > 0xFFFF                //如果地址大于65535
                void _24CXXX_AddrProcess(unsigned long Addr)
                #else
                void _24CXXX_AddrProcess(unsigned int Addr)
                #endif        //#if MAX_ADDR > 0xFFFF
                {
                        if( Addr> MEM_SIZE )        //如果地址大于单芯片地址范围
                        {
                                Addr /= MEM_SIZE+1;
                        }
                        else
                        {
                                Addr = 0x00;
                        }

                        HardAddr = Addr;
                }
        #elif        DEV_24CXX_NUM == 1//如果使用单个芯片
                #if MAX_ADDR > 0xFFFF                //如果地址大于65535
                void _24CXXX_AddrProcess(unsigned long Addr)
                #else
                void _24CXXX_AddrProcess(unsigned int Addr)   //出现在此处??????????
                #endif        //#if MAX_ADDR > 0xFFFF
                {
                        HardAddr = 0x00;
                }
        #endif        //#if DEV_24CXX_NUM > 1
#endif        //#if DEV_24CXX_MODLE==_24C1024

出0入0汤圆

 楼主| 发表于 2010-10-23 15:43:06 | 显示全部楼层
80楼:
#elif DEV_24CXX_NUM == 1//如果使用单个芯片

这一行是错误的,应该是
#else
#if DEV_24CXX_NUM == 1//如果使用单个芯片

出0入0汤圆

发表于 2010-10-24 12:31:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-24 17:27:27 | 显示全部楼层
太强大了。支持一下。

出0入0汤圆

发表于 2010-10-24 18:19:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-3 13:02:15 | 显示全部楼层
好东西

出0入0汤圆

发表于 2010-11-5 10:57:33 | 显示全部楼层
移植到51试试

出0入0汤圆

发表于 2010-11-5 14:21:59 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-11-5 14:47:45 | 显示全部楼层
回复【86楼】gxy508  
-----------------------------------------------------------------------

欢迎移植!

不过一般的51使用有点费劲,最好RAM大一点的才好

出0入0汤圆

发表于 2010-12-20 18:12:39 | 显示全部楼层
恩,好东西。正好碰到换页写的问题

出0入0汤圆

发表于 2011-4-2 08:54:11 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-4-2 09:09:29 | 显示全部楼层
强....非常强

出0入0汤圆

发表于 2011-4-2 09:23:55 | 显示全部楼层
mark .

出0入0汤圆

发表于 2011-4-13 13:43:59 | 显示全部楼层
ClrBit(PORTC, iic_scl); //pull up
        ClrBit(PORTC, iic_sda); //pull up
        SetBit(PORTC, iic_wp);  //只能读

        SetBit(DDRC, iic_scl);        //Pull up the pin SDA and SCL          
        SetBit(DDRC, iic_sda);        //Pull up the pin SDA and SCL          
        SetBit(DDRC, iic_wp);        //读写使能IO需要输出

        TWCR = 0;
        TWBR = 12; //set bit rate  
        TWSR = 0; //set prescale

-------------------------------------------------------------------------

#define I2C_START()                    TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA)
#define I2C_STOP()                          TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO)



这样设置示波器都看不到2个IO上有任何波形,把24C128焊下来都没波形,外部有上拉电阻,AVR用的是内部8M,串口通讯正常  

调了1整天了,实在不行就改IO模拟了,沮丧

出0入0汤圆

发表于 2011-4-13 13:50:56 | 显示全部楼层
用程序控制这2个脚又发现没有烧坏。TWI就是没启动

出0入0汤圆

发表于 2011-4-13 15:56:34 | 显示全部楼层
MARK.谢谢楼主

出0入0汤圆

发表于 2011-4-13 16:49:09 | 显示全部楼层
好贴!!!

出0入0汤圆

发表于 2011-5-9 10:14:22 | 显示全部楼层
好东西啊!

出0入0汤圆

发表于 2011-8-17 10:34:18 | 显示全部楼层
好贴,顶起来

出0入0汤圆

发表于 2011-8-17 10:42:17 | 显示全部楼层
感谢楼主,好帖!建议经常更新和完善
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 08:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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