⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key&i2c.c.svn-base

📁 一个基于UCOS/2操作系统开发的实际产品(电力负控)的代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:

    I2CONCLR = 0x6C;
    I2CONSET = 0x40;                            /* 使能I2c */
    VICIntEnable = 1 << 9;                      /* 使能I2c中断 */

    if (EaddrNByte > 0)
    {
        if (I2cWriteByte(Addr, Eaddr, EaddrNByte) != I2C_WRITE_END)
        {
            OSSemPost(I2cSem);
            return -1;
        }
    }

    I2cAddr = Addr | 0x01;                      /* 存储发送地址 */
    I2cNbyte = ReadNbyte;                       /* 存储读字节数 */
    I2cBuf = Ret;                               /* 存储读到的数据 */
    I2CONCLR = 0x28;
    I2CONSET = 0x24;                            /* 设置为主机,并启动总线 */
    VICIntEnable = 1 << 9;                      /* 使能I2c中断 */

    OSMboxPend(I2cMbox, 0, &err);               /* 等待操作结束 */

    VICIntEnClr = 1 << 9;                       /* 禁止能I2c中断 */
    OSSemPost(I2cSem);
    return (ReadNbyte - I2cNbyte);
}


/*********************************************************************************************************
** 函数名称: I2c_Exception
** 功能描述: I2c中断服务程序
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: I2cAddr,I2cBuf,I2cNbyte,I2cMbox
** 调用模块: OSMboxPost
********************************************************************************************************/
        void I2c_Exception(void)
{
    OS_ENTER_CRITICAL();
    switch(I2STAT & 0xf8)
    {
        case  0x08:                     /* 已发送起始条件,与0x18相同处理 */
//            break;
        case  0x10:                     /* 已发送重复起始条件 */
            I2DAT = I2cAddr;            /* 发送地址 */
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x18:                     /* 已发送SLA+W,并已接收应答 */
            I2DAT = *I2cBuf++;
            I2cNbyte--;
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x28:                     /* 已发送I2C数据,并接收到应答 */
            if (I2cNbyte > 0)
            {
                I2DAT = *I2cBuf++;
                I2cNbyte--;
                I2CONCLR = 0x28;        /* 清除标志 */
            }
            else
            {
                OSMboxPost(I2cMbox, (void *)I2C_WRITE_END);
                VICIntEnClr = 1 << 9;   /* 禁止能I2c中断 */
            }
            break;
        case  0x20:                     /* 已发送SLA+W;已接收非ACK, 与0x48处理相同 */
//            break;                    
        case  0x30:                     /* 已发送I2DAT中的数据字节;已接收非ACK, 与0x48处理相同 */
//            break;
        case  0x48:                     /* 已发送SLA+R;已接收非ACK */
            I2CONSET = 1 << 4;          /* 发送停止信号 */
            OSMboxPost(I2cMbox, (void *)I2C_ACK_ERR);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x38:                     /* 在SLA+R/W或数据字节中丢失仲裁 */
            OSMboxPost(I2cMbox, (void *)I2C_NOT_GET_BUS);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x40:                     /* 已发送SLA+R;已接收ACK */
            if (I2cNbyte <= 1)
            {
                I2CONCLR = 1 << 2;      /* 下次发送非应答信号 */
            }
            else
            {
                I2CONSET= 1 << 2;       /* 下次发送应答信号 */
            }
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x50:                     /* 已接收数据字节;已发送ACK */
            *I2cBuf++ = I2DAT;          /* 接收数据 */
            I2cNbyte--;
            if (I2cNbyte <= 1)
            {
                I2CONCLR = 1 << 2;      /* 下次发送非应答信号 */
            }
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x58:                     /* 已接收数据字节;已返发送ACK */
            *I2cBuf = I2DAT;            /* 接收数据 */
            I2cNbyte--;
            I2CONSET= 1 << 4;           /* 结束总线 */
            OSMboxPost(I2cMbox, (void *)I2C_READ_END);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        default:
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
    }

    VICVectAddr = 0;                    /* 通知中断控制器中断结束 */
    OS_EXIT_CRITICAL();
}

/*********************************************************************************************************
** 函数名称: I2c_Wait
** 功能描述: 
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: I2cAddr,I2cBuf,I2cNbyte,I2cMbox
** 调用模块: OSMboxPost
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
 
        uint8 I2c_Wait(void)
{
    uint16 wi;
    uint8  ist;
    OS_ENTER_CRITICAL();

    while(1)
      {
       for(wi=0;wi<10000;wi++)
          if(I2STAT!=0xf8)break;
       if (wi==10000)
          return I2C_NOT_GET_BUS;
       ist=I2STAT & 0xf8;
       switch(ist)
        {
         case  0x08:                     /* 已发送起始条件,与0x18相同处理 */
//             break;
         case  0x10:                     /* 已发送重复起始条件 */
               I2DAT = I2cAddr;            /* 发送地址 */
               I2CONCLR = 0x28;            /* 清除标志 */
               break;
         case  0x18:                     /* 已发送SLA+W,并已接收应答 */
               I2DAT = *I2cBuf++;
               I2cNbyte--;
               I2CONCLR = 0x28;            /* 清除标志 */
               break;
         case  0x28:                     /* 已发送I2C数据,并接收到应答 */
               if (I2cNbyte > 0)
                 {
                  I2DAT = *I2cBuf++;
                  I2cNbyte--;
                  I2CONCLR = 0x28;        /* 清除标志 */
                 }
                else
                 {
                  OS_EXIT_CRITICAL();
                  return I2C_WRITE_END;
                 }
                break;
         case  0x20:                     /* 已发送SLA+W;已接收非ACK, 与0x48处理相同 */
         case  0x30:                     /* 已发送I2DAT中的数据字节;已接收非ACK, 与0x48处理相同 */
         case  0x48:                     /* 已发送SLA+R;已接收非ACK */
               I2CONSET = 0x10;          /* 发送停止信号 */
               //I2CONCLR = 0x28;            /* 清除标志 */
               OS_EXIT_CRITICAL();
               return I2C_ACK_ERR;
               break;
         case  0x38:                     /* 在SLA+R/W或数据字节中丢失仲裁 */
               I2CONCLR = 0x28;            /* 清除标志 */
               OS_EXIT_CRITICAL();
               return I2C_NOT_GET_BUS;
               break;
         case  0x40:                     /* 已发送SLA+R;已接收ACK */
               if (I2cNbyte <= 1)
                 {
                   I2CONCLR = 1 << 2;      /* 下次发送非应答信号 */
                 }
                else
                 {
                  I2CONSET= 1 << 2;       /* 下次发送应答信号 */
                 }
               I2CONCLR = 0x28;            /* 清除标志 */
               break;
         case  0x50:                     /* 已接收数据字节;已发送ACK */
               *I2cBuf++ = I2DAT;          /* 接收数据 */
               I2cNbyte--;
               if (I2cNbyte <= 1)
                {
                 I2CONCLR = 1 << 2;      /* 下次发送非应答信号 */
                }
               I2CONCLR = 0x28;            /* 清除标志 */
               break;
         case  0x58:                     /* 已接收数据字节;已返发送ACK */
               *I2cBuf = I2DAT;            /* 接收数据 */
               I2cNbyte--;
               I2CONSET= 0x10;           /* 结束总线 */
               //I2CONCLR = 0x28;            /* 清除标志 */
               OS_EXIT_CRITICAL();
               return I2C_READ_END;
               break;
         default:
               I2CONCLR = 0x28;            /* 清除标志 */
               break;
        }
      }
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -