打印

求助I2C问题(已经解决,结帖)

[复制链接]
2241|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tiger84|  楼主 | 2007-4-11 16:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
turmary| | 2007-4-11 17:55 | 只看该作者

ABC

最主要的不同是每页大小不同,如果有页操作的话。

另一个不同是设备寻址,倒数第3位为0,倒数第2,1位,即A1,A0与硬件连接一致..

使用特权

评论回复
板凳
airwill| | 2007-4-11 19:53 | 只看该作者

楼上说得是啊

倒数第3位为0, 这有点特别, 我也在这上载过跟斗, 注意一下啊

使用特权

评论回复
地板
tiger84|  楼主 | 2007-4-12 08:32 | 只看该作者

谢谢各位,

这些我都处理的没问题,今天仔细看了下中断函数,应该是中断函数的问题,正在改之中。

使用特权

评论回复
5
tiger84|  楼主 | 2007-4-12 09:55 | 只看该作者

晕,还没成功

写这个驱动程序的人离职了,跟着他的思路改程序,真难受。

使用特权

评论回复
6
tiger84|  楼主 | 2007-4-12 14:02 | 只看该作者

再问一下,请赐教

I2C写数据时,比如说一页最多能写64个字节的,

首先必须写2个字节的地址进去,这俩个字节是否算进去?

接下来,我是能写62个字节数据?
   
          还是64个字节数据呢?

使用特权

评论回复
7
ayb_ice| | 2007-4-12 19:02 | 只看该作者

不算...

使用特权

评论回复
8
tiger84|  楼主 | 2007-4-15 12:28 | 只看该作者

问题又来了

我用的是AT24C256,每页最多写入64字节,很奇怪,每次我写时,从0开始排号,地址为63,127,191--,总之刚好是一页的最后一个地址上总写不进去数据。自认为中断函数不存在问题,大虾们指教一下

使用特权

评论回复
9
tiger84|  楼主 | 2007-4-16 09:13 | 只看该作者

找出问题了,但是没有解决办法

原来是一页中的第64个字节写不进去啊,只有单独写这个字节才能写进去。
很纳闷。各位指教一下吧

使用特权

评论回复
10
ayb_ice| | 2007-4-16 09:16 | 只看该作者

最后一个字节就调用单独写...

使用特权

评论回复
11
lyjian| | 2007-4-16 09:21 | 只看该作者

AT24C256用了N多,不可能存在这样的问题,肯定是你的软件有

使用特权

评论回复
12
ayb_ice| | 2007-4-16 09:52 | 只看该作者

我也曾经认为我精通IIC

我也曾经认为我精通IIC,结果有一回犯了个低级错误...
11楼说的正是...

使用特权

评论回复
13
tiger84|  楼主 | 2007-4-16 09:54 | 只看该作者

??

比如说吧,我从地址62开始写2个字节的数据,62的写进去了,地址63还是写不进去。

只有单独写第64个字节即地址63才能写进去。

请问一下,如果是软件的问题,可能是在哪里?I2C的中断,我都理解了啊。

使用特权

评论回复
14
tiger84|  楼主 | 2007-4-16 09:59 | 只看该作者

望指教

如果单独写上地址63,127,191等地址时,就一切OK了,可是这样的话,程序就不规范了?我想肯定是我哪里还没有理解透吧

使用特权

评论回复
15
ayb_ice| | 2007-4-16 10:09 | 只看该作者

方便的话可以把程序帖上来...

使用特权

评论回复
16
tiger84|  楼主 | 2007-4-16 10:22 | 只看该作者

比较麻烦啊,先发个中断

void I2cISR (void)
{  INT8U addFlag;
   addFlag = 0;
    switch (I2STAT)    {
        case 0x00:                        //Bus Error has occured
            I2CON = GENERATE_STOP;
            break;
        case 0x08:                        //(rep) Start condition transmitted
        case 0x10:                        //Slave slvadd+R/W are transmitted
            I2DAT = pMsg[cbyMsg]->slvadd;
            I2CON = RELEASE_BUS_ACK;
            break;
        case 0x18:                        //SLA+W transmitted,ACK received DATA or STOP will be transmitted
                                        //已经发送完了SLA+W,接下来开始发送第一个地址字节
             addFlag = 1;
             I2DAT =  pMsg[cbyMsg]->buf[cbyBuf];
                I2CON = RELEASE_BUS_ACK;
                break;
        case 0x28:                        //DATA transmitted,ACK received DATA or STOP will be transmitted
                                        //已经发送了I2DAT的一个字节,接下来再次发送I2DAT里的数据字节
             if (addFlag == 1){
              I2DAT = pMsg[cbyMsg]->buf[cbyBuf + 1];
              I2CON = RELEASE_BUS_ACK;
             } else {

            if (cbyBuf < pMsg[cbyMsg]->nrBytes) {      //一个信息里的字节还没有发送完,接着发送
                I2DAT = pMsg[cbyMsg]->buf[cbyBuf++];    
                I2CON = RELEASE_BUS_ACK;
            } else {                                   //发送下一个信息
                cbyMsg++;
                if (cbyMsg < nrMessage) {
                    cbyBuf = 0;            //next message
                    I2CON = RELEASE_BUS_STA;    //generate (rep)START
                } else {
                    I2CON = GENERATE_STOP;
                    drvStatus = I2C_OK;
                }                                   //end  if
            }                                       //end  if
              }                                       //end  if
            break;
        case 0x20:                      //发送完SLA+W,但未收到ACK,发送停止信号
        case 0x48:                        //SLA+W/R transmitted NOT ACK received
            drvStatus = I2C_NACK_ON_ADDRESS;        //driver finished
            I2CON = GENERATE_STOP;
            break;
        case 0x30:                        //DATA transmitted,NOT ACK received
            drvStatus = I2C_NACK_ON_DATA;
            I2CON = GENERATE_STOP;
            break;
        case 0x38:                        //Arbitration lost in SLA+W or DATA
            I2CON = RELEASE_BUS_STA;            //release bus,set STA
            break;
        case 0x40:                        //SLA+R transmitted,ACK received
          if (pMsg[cbyMsg]->nrBytes == 1)
                  I2CON = RELEASE_BUS_NOACK;        //NOT ACK on next byte
              else
                I2CON = RELEASE_BUS_ACK;        //ACK on next byte
            break;
        case 0x50:                        //DATA received,ACK has been returned
            pMsg[cbyMsg]->buf[cbyBuf++] = I2DAT;        //read next data
            if (cbyBuf + 1 ==pMsg[cbyMsg]->nrBytes)        //next byte the lase?
                I2CON = RELEASE_BUS_NOACK;        //NO ACK on next byte
            else
                I2CON = RELEASE_BUS_ACK;        //return ACK
            break;
        case 0x58:                        //DATA received, NOT ACK has been returned
            pMsg[cbyMsg]->buf[cbyBuf] = I2DAT;        //read last data
            cbyMsg++;
            if (cbyMsg < nrMessage) {
                cbyBuf = 0;                //next message
                I2CON = RELEASE_BUS_STA;        //generate (rep)START        
            } else {
                I2CON = GENERATE_STOP;
                drvStatus = I2C_OK;
            }
            break;
        default:;
    }
}

使用特权

评论回复
17
tiger84|  楼主 | 2007-4-16 10:25 | 只看该作者

一些相关的

#define AT24C256_WR            0xA2
#define AT24C256_RD            0xA3

#define GENERATE_STOP                0xD5            //设置STO,清除STA和SI
#define RELEASE_BUS_ACK                0xC5            //清除STO,STA,SI并设置AA
#define RELEASE_BUS_NOACK            0xC1            //清除STO,STA,SI和AA
#define RELEASE_BUS_STA                0xE5            //产生(重复)START,设置STA


static I2C_MESSAGE * _data pMsg[2];    //消息指针
static _data INT8U cbyBuf;        //缓冲区数据索引
static _data INT8U cbyMsg;        //消息索引
static _data INT8U nrMessage;        //消息个数
static _data INT8U drvStatus;        //驱动程序返回的状态

typedef struct
{
    INT8U slvadd;        //发送和接收消息的从机地址。如:从机地址+R(1),或从机地址+W(0)
    INT8U nrBytes;        //消息缓冲区的字节数
    INT8U * buf;        //指向消息缓冲区的首地址
} I2C_MESSAGE; 

使用特权

评论回复
18
tiger84|  楼主 | 2007-4-16 10:27 | 只看该作者

帮看一下中断是否存在问题

使用特权

评论回复
19
ayb_ice| | 2007-4-16 10:33 | 只看该作者

EEPROM里我一直使用软件模拟方式....

帮不上忙啊...

使用特权

评论回复
20
tiger84|  楼主 | 2007-4-16 10:45 | 只看该作者

还是谢谢ayb_ice 兄

我也觉得软件模拟比较好,自己好控制。
没办法啊,单片机带有I2C,并且很成熟了,总不能不用吧

lyjian 兄可否指点一二呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

862

帖子

0

粉丝