搜索
bottom↓
回复: 9

关于24C16的问题,快郁闷死了

[复制链接]

出0入0汤圆

发表于 2010-2-28 20:26:17 | 显示全部楼层 |阅读模式
请高分帮忙解决一下我的问题:

1. 用以下程序读写24C16时出现问题了: 我调用 I2C_Write(read_data,0x0001,1); 用I2C_Read(read_data,0x02XX,1)读时XX是[01-ff任意数] 0001-00ff 地址范围 全是刚才写入的那个字节数据.

2.我调用 I2C_Write(read_data,0x0101,16); 按页写入的数据.结果15与16字节是0XFF,

3.我调用 I2C_Write(read_data,0x0201,16); 按页写入的数据.结果13,14,15与16字节是0XFF,

4.我调用 I2C_Write(read_data,0x0301,16); 按页写入的数据.结果11,12,13,14,15与16字节是0XFF,

5.一直调用  I2C_Write(read_data,0x0701,16); 按页写入的数据.结果就能写入2个正确的字节

是我的24C16地址的理解问题吗? 我是这么理解的,24C16一共有128页,一页为16字节, 那0页的地址范围是00-0F,1页的为10-1f......

以上问题我搞了一周了,也不行.高手们帮帮我吧.!!!注,数据是从网上搜索并修改的.

//MyIIC.C
#include <iom8.h>
#include "MyDelay.h"
#include "MyUSART.h"
,
#ifndef uchar
        #define uchar unsigned char
#endif

#ifndef uint
        #define uint unsigned int
#endif

//变量声明
#define EEPROM_BUS_ADDRESS 0xa0         //器件地址
//主机发送模式时各状态字的后续动作
#define TW_START            0x08        // 开始信号已发出
#define TW_REP_START        0x10        //重复开始信号已发出
#define TW_MT_SLA_ACK       0x18        // 写字节已发出并受到ACK信号  
#define TW_MT_SLA_NACK      0x20        //写字节已发出并受到NACK信号  
#define TW_MT_DATA_ACK      0x28        //数据已发出并受到ACK 信号
#define TW_MT_DATA_NACK     0x30        //数据已发出并受到NACK 信号
#define TW_MT_ARB_LOST      0x38        //丢失总线控制权
//主机接收模式时各状态字的后续动作
#define TW_MR_ARB_LOST      0x38        // 丢失总线控制权,未收到应答信号
#define TW_MR_SLA_ACK       0x40        //读命令已发出并受到ACK
#define TW_MR_SLA_NACK      0x48        //读命令已发出并受到NACK
#define TW_MR_DATA_ACK      0x50        //数据已收到,ACK已发出
#define TW_MR_DATA_NACK     0x58        //数据已收到,NACK已发出

#define SET_1(a,b) a |=        (1<<b)
#define CLE_0(a,b) a &= (~(1<<b))
//I2C初始化函数
void I2C_Init(void)
{
        TWSR = 0x02;    //不分频
//        TWBR = 0x00;    //波特率
        TWAR = 0x00;    //被控器地址寄存器
        /*TWCR 寄存器*************************************************************************************
       
                7                6                5                4                3                2                1                0       
          TWINT    TWEA           TWSTA   TWSTO   TWWC   TWEN      x      TWIE       
       
        **************************************************************************************************/
        TWCR |= 0x44;        //允许ACK,使能I2C,PC0、PC1、转换成SCL、SDA引脚
}
//向I2C写一个字节
uchar I2C_Write(uchar *dat,uint addr,uchar n)
{
        uchar addrl,addrh,i;
        addrl = (uchar)addr;
        //        addrl = 0x02;
        addrh = 0xa0 | ((addr >> 8) << 1);
        TWBR = 14;//设置波特率
        TWCR |= 0xa4;         //清零中断标志位,发送START信号
        while(!(TWCR & 0x80));         //检测中断标志,为1表明完成发送开始信号
        if((TWSR & 0xf8) != 0x08)//启动总线失败
        {
                TWCR |= 0x94;        // 停止
                return 1;
        }
       
        TWDR = addrh ; //写从器件地址( 1010+页地址高三位+R/W)
        TWCR |= 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x18)     //从地址+写信号发送失败
        {
                TWCR |= 0x94;        // 停止
                return 2;
        }
       
        TWCR &= 0xdf;        //手动清START信号
        TWDR = addrl;//子地址(24C16地址) 页地址低四位+第几字节
        TWCR |= 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x28)     //数据发送失败
        {
                TWCR |= 0x94;        // 停止
                return 3;
        }
       
        for(i=0;i<n;i++)        //向总线写n个数据
        {
                TWDR = *(dat+i);
        //        USART_Send(TWDR);
                TWCR |= 0x84;
                while(!(TWCR & 0x80));         //等待发送完成
            if((TWSR & 0xf8) != 0x28)     //数据发送失败
                {
                        TWCR |= 0x94;        // 停止
                        return 4;
                }
        }
        TWCR |= 0x94;                //停止位,并复位SDL与SCL线为普通IO口
        delay_ms(10);
        return 0;//操作成功
}
uchar I2C_Read(uchar *dat,uint addr,uchar n)
{       
        uchar addrl,addrh,i;
        addrl = (uchar)addr;
        addrh = 0xa0 | ((addr >> 8)<< 1);
        TWBR = 14;//设置波特率
        TWCR |= 0xa4;         //清零中断标志位,发送START信号
        while(!(TWCR & 0x80));         //检测中断标志,为1表明完成发送开始信号
        if((TWSR & 0xf8) != 0x08)//启动总线失败
        {
                TWCR |= 0x94;        // 停止
                return 1;
        }
       
       
        TWDR = addrh; //写从器件地址(固定地址1010)       
       
        TWCR |= 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x18)     //从地址+写信号发送失败
        {
                TWCR |= 0x94;        // 停止
                return 2;
        }
        TWCR &= 0xdf;        //手动清START信号
        TWDR = addrl;//子地址(24C16地址)
        TWCR |= 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x28)     //数据发送失败
        {
                TWCR |= 0x94;        // 停止
                return 3;
        }
        TWCR |= 0xa4;         //重新启动总线
        while(!(TWCR & 0x80));         //检测中断标志,为1表明完成发送开始信号
        if((TWSR & 0xf8) != 0x10)//启动总线失败
        {
                TWCR |= 0x94;        // 停止
                return 4;
        }

        TWDR = addrh | 0x01; //写从器件地址(固定地址1010)
        TWCR |= 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x40)     //从地址+写信号发送失败
        {
                TWCR |= 0x94;        // 停止
                return 5;
        }
        for(i=0;i<n-1;i++)        //读n个字节数据
        {
                TWCR = 0xc4;
                while(!(TWCR & 0x80));         //等待发送完成
                if((TWSR & 0xf8) != 0x50)     //数据接收失败
                {
                        TWCR |= 0x94;        // 停止
                        return 6;
                }
                *(dat + i) = TWDR;
               
                USART_Send(TWDR);  //用串口显示
               
               
        }
        TWCR = 0x84;
        while(!(TWCR & 0x80));         //等待发送完成
        if((TWSR & 0xf8) != 0x58)     //数据接收失败
        {
                TWCR |= 0x94;        // 停止
                return 7;
        }
        *(dat + i) = TWDR;
       
        USART_Send(TWDR);        //用串口显示
       
       
        TWCR |= 0x94;         //停止位,并复位SDL与SCL线为普通IO口
//        delay_ms(10);
        return 0;//操作成功
}

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

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

出0入0汤圆

 楼主| 发表于 2010-2-28 21:15:37 | 显示全部楼层
别沉了啊,自己顶

出0入0汤圆

 楼主| 发表于 2010-3-1 10:09:42 | 显示全部楼层
再顶啊

出0入0汤圆

 楼主| 发表于 2010-3-2 09:08:52 | 显示全部楼层
高手帮帮忙吧

出0入0汤圆

 楼主| 发表于 2010-3-3 08:35:36 | 显示全部楼层
DDDDDDDDDDDDD

出0入0汤圆

 楼主| 发表于 2010-3-3 23:19:53 | 显示全部楼层
真没帮忙的啊?

出0入0汤圆

发表于 2010-3-4 01:54:02 | 显示全部楼层
话说24C512大概多少前一片?
有没有64KB的ROM,便宜点的~~~

出0入0汤圆

发表于 2010-3-4 02:21:41 | 显示全部楼层
45DB161?

出0入0汤圆

 楼主| 发表于 2010-3-4 19:35:35 | 显示全部楼层
郁闷

出0入0汤圆

发表于 2017-7-1 07:44:03 | 显示全部楼层
我也遇到这个问题,向24C16的一个地址写一个数据,比如向24C16的地址0x0000,写数据0x4c,然后发现24c16中地址从0x0000到0x001f,数据都是0x4c;
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-25 19:05

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

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