szdream2011 发表于 2012-7-21 18:20:26

IO口IIC读出来的数据一直为0xFF?

本帖最后由 szdream2011 于 2012-7-21 18:21 编辑

用IO口模拟IIC读电容屏坐标,读出来的数据一直为0xFF呢,查了好久不知道怎么 回事,各位帮忙看看问题出在哪!
#define DELAY_TIME50

BYTE SDA_IN(void)
{
    register GPIO *sGpio;
    sGpio = (GPIO *)(GPIO_BASE);

    /* 设置FMS_DAT1为输入模式FGPIO */
    sGpio->Fgpcfg &= 0xbfffbfff;

    sGpio->Fgpdat &= 0xbfffbfff;
   
    if (sGpio->Fgpdat & 0x00004000)
    {
      return 1;
    }
    else
    {
      return 0;
    }
}

void SDA_OUT_HIGH(void)
{
    register GPIO *sGpio;
    sGpio = (GPIO *)(GPIO_BASE);

    /* 设置FMS_DAT1为输出模式FGPIO */
    // sGpio->Fgpcfg |= 0x40004000;
    sGpio->Fgpdat |= 0x40000000;

    sGpio->Fgpdat |= 0x40004000;
}
void SDA_OUT_LOW(void)
{
    register GPIO *sGpio;
    sGpio = (GPIO *)(GPIO_BASE);

    /* 设置FMS_DAT1为输出模式FGPIO */
    //sGpio->Fgpcfg |= 0x40004000;
    sGpio->Fgpdat |= 0x40000000;

    sGpio->Fgpdat &= 0xffffbfff;
}
void SCL_OUT_HIGH(void)
{
    register GPIO *sGpio;
    sGpio = (GPIO *)(GPIO_BASE);

    /* 设置FMS_DAT1为输出模式FGPIO */
    //sGpio->Fgpcfg |= 0x00010001;
    sGpio->Fgpdat |= 0x00010001;

    sGpio->Fgpdat |= 0x00000001;
}
void SCL_OUT_LOW(void)
{
    register GPIO *sGpio;
    sGpio = (GPIO *)(GPIO_BASE);

    /* 设置FMS_DAT3为输出模式FGPI1 */
    //sGpio->Fgpcfg |= 0x00010001;
    sGpio->Fgpdat |= 0x00010001;

    sGpio->Fgpdat &= 0xfffffffe;
}
/*********************************************************
**函数名:Start_I2C
**功能:启动总线
**输入参数:无
**返回值:无
**********************************************************
*/
void Start_I2C(void)
{
    SDA_OUT_HIGH();    /* 发送起始条件的数据信号 */
    IODelay(DELAY_TIME);
    SCL_OUT_HIGH();
    IODelay(DELAY_TIME);

    SDA_OUT_LOW();   /* 发送起始信号 */
    IODelay(DELAY_TIME);
    SCL_OUT_LOW();
    IODelay(DELAY_TIME);
}
/*********************************************************
**函数名:Stop_I2C
**功能:停止总线
**输入参数:无
**返回值:无
**********************************************************
*/
void Stop_I2C(void)
{
    SDA_OUT_LOW();   /* 发送结束条件的数据信号 */
    IODelay(DELAY_TIME);

    SCL_OUT_HIGH();    /* 发送I2C总线结束信号 */
    IODelay(DELAY_TIME);
    SDA_OUT_HIGH();
    IODelay(DELAY_TIME);
}
/*********************************************************
**函数名:SendByte
**功能:数据发送函数,单字节发送
**输入参数:bData----数据值
**返回值:无
**********************************************************
*/
void SendByte(BYTE bData)
{
    BYTE bCount = 0;

    for (bCount=0; bCount<8; bCount++) /* 要传送的数据长度为8位 */
    {
      bData <<= 1;
      if (bData & 0x80)
      {
            SDA_OUT_HIGH();   /* 判断发送位 */
      }
      else
      {
            SDA_OUT_LOW();
      }
      bData <<= 1;
      IODelay(DELAY_TIME);
      SCL_OUT_HIGH();         /* 置时钟线为高,通知被控制器开始接收数据 */
      IODelay(DELAY_TIME);
    }
    SCL_OUT_LOW();
    /*IODelay(DELAY_TIME);


    if (SDA_IN() == 1) bAck = 0; /* 判断是否接收到应答信号 */
    /*else bAck = 1;
    SCL_OUT_LOW();
    IODelay(DELAY_TIME);*/
}
/*********************************************************
**函数名:RecvByte
**功能:接收从器件传回的数据
**输入参数:无
**返回值:接收到的数据
**********************************************************
*/
BYTE RecvData(void)
{
    BYTE bRecvData = 0;
    BYTE bCount;

    //SCL_OUT_LOW();
    //IODelay(DELAY_TIME);
    SDA_OUT_HIGH();         /* 置数据线为输入方式 */
    IODelay(DELAY_TIME);
   
    for (bCount=0; bCount<8; bCount++)
    {
      SCL_OUT_HIGH();
      IODelay(DELAY_TIME);
      bRecvData = (bRecvData<<1)|(SDA_IN());
      SCL_OUT_LOW();
      IODelay(DELAY_TIME);
    }
    return bRecvData;
}

void Ack_IIC(BYTE bAck)
{
   SCL_OUT_LOW();
   IODelay(DELAY_TIME);
   if (bAck)
   {
   SDA_OUT_HIGH();
   }
   else
   {
   SDA_OUT_LOW();
   }
   IODelay(DELAY_TIME);
   SCL_OUT_HIGH();
   IODelay(DELAY_TIME);
   SCL_OUT_LOW();
   IODelay(DELAY_TIME);
   SDA_OUT_LOW();
   IODelay(DELAY_TIME);
}

void NoAck_IIC(void)
{
    SCL_OUT_LOW();
    IODelay(DELAY_TIME);
    SDA_OUT_HIGH();
    IODelay(DELAY_TIME);
    SCL_OUT_HIGH();
    IODelay(DELAY_TIME);
    SCL_OUT_LOW();
    IODelay(DELAY_TIME);
}
BYTE I2C_WaitAck(void)
{
    SCL_OUT_HIGH();
    if (SDA_IN())
    {
      SCL_OUT_LOW();
      IODelay(DELAY_TIME);
      SCL_OUT_HIGH();

      if (SDA_IN() == 1)
      {
             return 1;
      }
    }
    else
    {
      return 0;
    }
}
/*********************************************************
**函数名:IIC_Read_Data
**功能:从IIC_Read_Data地址读入n个字节数据
**输入参数:bAddr    ----写入器件地址
**         pbData   ----写入数据指针
**返回值:读取数据成功与否标志,1:成功,0:失败
**********************************************************
*/
BYTE IIC_Read_Data(BYTE bSlaveAddr, BYTE bSubAddr, BYTE *pbData, BYTE bLen)
{
    Start_I2C();
    SendByte(0x70);
    if (I2C_WaitAck())
    {
      mpDebugPrint("1bAck == 0\n");
      Stop_I2C();
      return 0;
    }
   
    SendByte(0xf9);
    if (I2C_WaitAck())
    {
      mpDebugPrint("2bAck == 0\n");
      Stop_I2C();
      return 0;
    }
    Stop_I2C();

    Start_I2C();
    SendByte(0x71);
    if (I2C_WaitAck())
    {
      mpDebugPrint("3bAck == 0\n");
      Stop_I2C();
      return 0;
    }
   
    while(bLen != 1)
    {
      *pbData = RecvData();
      Ack_IIC(0);
      pbData++;
      bLen--;
    }
   
    *pbData = RecvData();
    Ack_IIC(1);
    Stop_I2C();
    return 1;
}

szdream2011 发表于 2012-7-23 09:36:12

顶一个。

devcang 发表于 2012-7-23 15:54:05

搞过几下数字收音机,不会那么呀
页: [1]
查看完整版本: IO口IIC读出来的数据一直为0xFF?