打印

USB控制传输中的写I2C问题

[复制链接]
5424|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
USB-DSN|  楼主 | 2011-10-1 20:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
TEMP[0] =0xc6 ;                                                          //fengbianlv
  TEMP[1] =0xa1;
  TEMP[2] =0x03;
  EZUSB_WriteI2C(I2C_Addr, 0x03, TEMP);
在自定义命令中,能用上面的语句写大量的SENSOR寄存器配置吗?我每次执行写I2C的控制命令时,总是没**确写入I2C(不知道有没有写进去),在I2C写结束后,测I2C的SDL与SCL,发现SDL为高电平,SCL为低电平,这里有问题吧。按理说I2C写完之后,SDL与SCL应该都为高电平的。
还有一点需要说一下,我在写I2C的自定义命令中,加入了sensor图像的同步代码,发现如果我在该命令里面有写I2C的操作,采到的图像就是错帧的,而当我把所有的写I2C命令注释掉以后,采到的图像是正确的,这里是不是可以理解为该控制传输中如果加了写I2C的代码后,控制传输就失败了???  请朋友们帮忙看下,这个问题困扰了我好几天了。。。。

相关帖子

沙发
dqyubsh| | 2011-10-2 20:35 | 只看该作者
SDL与SCL都应该上拉,缺省状态是高电平。至于写的对不对,可以读出来显示一下结果。

第二个问题说的很模糊,不明所以。

使用特权

评论回复
板凳
USB-DSN|  楼主 | 2011-10-2 21:28 | 只看该作者
2# dqyubsh
I2C都已经上拉了,只是写完以后SCL没有上拉回去。。。
第2个问题跟第一个是同一个,
case SELUXGA: // 0xb4
           TEMP[0] =0xf0 ;                                                          //fengbianlv
  TEMP[1] =0x00;
  TEMP[2] =0x00;
  EZUSB_WriteI2C(I2C_Addr, 0x03, TEMP);
  IFCONFIG = 0x40;  //以下为SENSOR图像的同步                 
PORTACFG = 0x00;  
OEA |= 0x80;      //Led1 Open
     IOA |= 0x80;
            .
            .
            .
IFCONFIG = 0x43;//   
      *EP0BUF = 0xb4;
           EP0BCH = 0;
          EP0BCL = 1;
          EP0CS |= bmHSNAK;
        break;        }
我的意思就是如果我在这个自定义请求里面没写前面那段写I2C的代码,这个图像同步就是正常的,说明控制传输成功了。但是当我写上写I2C的那段代码后,该控制传输就失败了。
今天晚上写了段最简单的控制传输固件和上位机来验证控制传输是不是有问题,结果发现新问题了,代码如下:
BOOL DR_VendorCmnd(void)
{
    switch(SETUPDAT[1])
        {
          case  startcap :
          *EP0BUF = 0xb4;
          EP0BCH = 0;
          EP0BCL = 1;
          EP0CS |= bmHSNAK;
        break;
          case  get:
                *EP0BUF = 0xb5;
          EP0BCH = 0;
          EP0BCL = 1;
          EP0CS |= bmHSNAK;
          break;   
         
                   }   
   return(TRUE);
   }
上位机的代码是
CCyControlEndPoint *ept = USBDevice->ControlEndPt;
        //USHORT result;

        ept -> Target = TGT_DEVICE;
        ept -> ReqType = REQ_VENDOR;
        ept -> Direction = DIR_FROM_DEVICE;
        ept -> ReqCode = 0xA3;
        ept -> Value = 0;
        ept -> Index = 0;
        PUCHAR buf= new UCHAR[1];
        ZeroMemory(buf,1);
        LONG length = 1;
        ept -> XferData(buf, length);
CCyControlEndPoint *ept = USBDevice->ControlEndPt;
        //USHORT result;

        ept -> Target = TGT_DEVICE;
        ept -> ReqType = REQ_VENDOR;
        ept -> Direction = DIR_FROM_DEVICE;
        ept -> ReqCode = 0xA4;
        ept -> Value = 0;
        ept -> Index = 0;
        PUCHAR buf= new UCHAR[1];
        ZeroMemory(buf,1);
        LONG length = 1;
        ept -> XferData(buf, length);
}
执行控制传输的时候,我发现只有A3控制传输是成功的,A4的是失败的,明明是两段完全一样的代码,为什么就一个行一个不行了?既然A3能行,然后我把A4控制传输的固件与上位机全部删除,就执行A3控制命令,发现也是失败,而且是失败几十次之后会有一次成功,这个真让人费解。。。。难道我的芯片有问题吗?

使用特权

评论回复
地板
dqyubsh| | 2011-10-3 00:30 | 只看该作者
1,你在case语句里边写这么多代码,一会这个一会那个,甚至初始化IFCONFIG,这显然不是一个好习惯。可以把初始化放在TD_Init函数,case分成两个命令,每个做一件事,简单明了。出了问题也容易查。

2,固件没通之前,直接上VC例程,也不是一个好习惯。有CyConsole控制台程序,用它单次发命令,调试固件,直至无误。VC是最后的事情,仅仅把手工测试过程写成自己的界面而已。
3,用XferData,不如用ept->Write或者ept->Read,来得更明确。这是个建议而已,可能不影响结果。

可以跟踪ept->Read的返回值,看是否等于1。如果设备有其它操作,比较忙,要加超时等待。

4,操作EEPROM,我用EEPROMWritePage和EEPROMRead函数,其它没用过。

5,芯片轻易不会出问题,99%都在固件本身。

使用特权

评论回复
5
USB-DSN|  楼主 | 2011-10-3 20:29 | 只看该作者
本帖最后由 USB-DSN 于 2011-10-3 20:53 编辑

4# dqyubsh
谢谢这位大哥,我控制传输的问题已经解决了。  我现在的问题是I2C写寄存器写不进去,我用的是EZUSB_WriteI2C()函数,每次写完以后SCL脚没有拉高回高电平,一直处在低电平。
我的板子没有加EEPROM,直接用CYCONSOLE往芯片里面加载的固件,这个对I2C写有影响吗

使用特权

评论回复
6
dqyubsh| | 2011-10-3 21:49 | 只看该作者
没看懂你要干嘛,单纯写EEPROM,还是使用I2C协议通讯?

使用特权

评论回复
7
USB-DSN|  楼主 | 2011-10-3 22:58 | 只看该作者
6# dqyubsh
不是EEPROM,我的意图是想通过68013的I2C写图像传感器的寄存器,我的板子上没有焊EEPROM。

使用特权

评论回复
8
dqyubsh| | 2011-10-4 07:02 | 只看该作者
I2C是个很麻烦的协议,它是双向的,每个操作都要等待它的返回状态。远比不得SPI,简单的主从结构。

出错的一种可能是对I2C理解过于简单了,它的SDA/SCL不同电平代表不同的意义,你要进行恰当的处理。这个可以参看EEPROM.C的读写例程,它并没有用EZUSB_WriteI2C,自己用I2C寄存器写的函数。

实际上,我用68013 I2C与AVR单片机(做为从设备)通讯时,直接用EZUSB_WriteI2C,AVR收到了,但整个通讯并不顺畅,貌似返回码处理的不好,目前无**常工作——忙别的事,这块搁下了。

从头再来吧,仔细看看例子,有什么收获,发上来共享一下。

使用特权

评论回复
9
dqyubsh| | 2011-10-4 07:09 | 只看该作者
拷贝一段可以工作的I2C函数,它是68013操作MAX519 DAC的

static BYTE xdata Dac_save_val[2];

void DAC_UpdateCh0(BYTE ch0_val)
{
        BYTE xdata Dac_val[2];

           Dac_save_val[0] = ch0_val;
        Dac_val[0] = 0x00;
        Dac_val[1] = ch0_val;
        EZUSB_WriteI2C(DAC_ADDR, 0x02, &Dac_val);
        EZUSB_WaitForEEPROMWrite(DAC_ADDR);
}

使用特权

评论回复
10
USB-DSN|  楼主 | 2011-10-12 15:47 | 只看该作者
9# dqyubsh
搞定了,直接操作那3个I2C寄存器写的,另外我的电路板的I2C上拉不够,导致从机在I2C过程中没有ACK返回。

使用特权

评论回复
11
赁旧| | 2015-8-14 12:20 | 只看该作者
麻烦给看看我这个程序怎么老是写不进eeprom,是用8013a写的一个usb传输
BYTE xdata iicsed[10] = {0,1,2,3,4,4,3,7,8,9};
BYTE xdata iicrec[10] = {0,};
//BYTE *iicrec = (BYTE*)malloc(10);

    EZUSB_WriteI2C(0,10,iicsed);
    SYNCDELAY;  
    EZUSB_WaitForEEPROMWrite(0);
    SYNCDELAY;
    EZUSB_ReadI2C(0,10,iicrec);
    SYNCDELAY;


谢了

使用特权

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

本版积分规则

0

主题

14

帖子

1

粉丝