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

📄 i2c.c

📁 这个是基于ARM7的相关驱动代码
💻 C
字号:
/*
*******************************************************************************
*                    Copyright (c) 2006, Comba Telecom System
*                             All Rights Reserved
*
* Purpose           : SLV_I2C DRIVER and I2C communication File
* File Name         : I2C.c

* Chip type         : LPC22XX(ARM7TDMI)
* IDE               : ADS1.2

* Revision history  :
    vision: 0.0.0.1
    date  : 2006.09.14
		author: lihao
* Description       :

*******************************************************************************
*/
#define _DEFINE_VAR_I2C
#include "config.h"

/*
*******************************************************************************
* 函数功能:  作为从设备的IIC 总线 初始化I2C
* 说 明:
*       1.  输入:
            addr--总线地址.
            输出:
            初始化是否成功.

*       2.  基本方法:

*       3.  注意:
*******************************************************************************
*/
INT8U I2cInit(INT8U addr)
{

	PINSEL0 = (PINSEL0&0xFFFFFF0F)|0x50;
	
	I2ADR = addr&0xFE;				// 设置从机从地址寄存器,最后一位为‘0’
        I2CONCLR = 0x28;					// 将STA STO SI 置0
        I2CONSET = 0x44;                           // 使能I2c 并设置I2C为从接收模式

        I2CDataPos = 0;
  //      LPC_VIC_Disable(LPC_BASE_VIC, LPCVIC_ID_I2C); //防止在FPGA下载过程中发生中断
	
        I2cSem = OSSemCreate(1);                    // 信号量用于互斥操作总线
        I2cMbox = OSMboxCreate(NULL);               // 消息邮箱用于中断向任务传递操作结果

	if (I2cMbox == NULL)
        {
            return FALSE;
        }
        if (I2cSem != NULL)
        {
            return TRUE;
        }

    return FALSE;
}

/*
*******************************************************************************
* 函数功能: I2C 从机读(模式)
* 说 明:
*       1.  输入:
            Ret--指向返回数据存储位置的指针;
             输出:
            读到完整数据(-1表示出错).

*       2.  基本方法:

*       3.  注意:
*******************************************************************************
*/
INT16S I2cReadIsEnd(void)
{
    INT8U err;
    INT32U Rt;

    OSSemPend(I2cSem, 0, &err);

    Rt = (INT32U) OSMboxPend(I2cMbox, 20, &err); // 等待收到完整的数据
    if (Rt != I2C_READ_END)
    {
        OSSemPost(I2cSem);
        return -1;
    }
    OSSemPost(I2cSem);
    return TRUE;
}

/*
*******************************************************************************
* 函数功能: I2C  Get Device Address.
* 说 明:
*       1.  输入:
            Ret--指向返回数据存储位置的指针;
              输出:
            return the device address.

*       2.  基本方法:

*       3.  注意:
*******************************************************************************
*/
INT8U  I2cGetDataAddr(INT8U *Ret)
{
    INT8U DataAddr;

   DataAddr = *Ret;
   Ret++;
   return DataAddr;
}

/*
*******************************************************************************
* 函数功能: I2C  Get bytes number  how many the domain transmiting.
* 说 明:
*       1.  输入:
            Ret--指向返回数据存储位置的指针;
              输出:
            return the bytes number.

*       2.  基本方法:

*       3.  注意:
*******************************************************************************
*/
INT8U  I2cGetDataNum(INT8U *Ret)
{
    INT8U DataNum;

   DataNum = *Ret;
   Ret++;
   return DataNum;
}

void I2cIntDisable(void)
{
     LPC_VIC_Disable(LPC_BASE_VIC, LPCVIC_ID_I2C);
}

void I2cRecNextDataEnable(void)
{
     LPC_VIC_Enable(LPC_BASE_VIC, LPCVIC_ID_I2C);
     I2CDataPos = 0;
}


/*
*******************************************************************************
* 函数功能: 向量IRQ(I2C)中断服务
* 说 明:
*       1.  支持主机写和主机读模式.
*******************************************************************************
*/
void I2c_Exception(void)
{
//  OS_ENTER_CRITICAL();
  
   switch(I2STAT & 0xf8)
    {
        case  0x60:                     // 收到自己的地址与W,并返回了一个ACK
        case  0x68:                     // 主仲裁丢失,收到自己的地址与W,并返回一个ACK
					  // 将SI位清空,并返回一个ACK
            I2CONSET |= AA;
            break;
        case  0x70:                     // 收到通用地址并返回一个ACK
        case  0x78:                     // 主机的仲裁丢失,收到一个通用地址并返回一个ACK
		I2CONCLR |= AA;							// 清SI位,同时不返回ACK,因此将AA位清空
		break;
        case  0x80:                     // 之前已经收到自己地址,并收到一个数据,返回一个ACK
              I2cBuf[I2CDataPos++] = I2DAT;          // 接收数据字节,返回ACK
        	I2CONSET |= AA;
            break;
        case  0x88:                     // 之前已经收到自己的地址,并收到一个数据字节,并返回非ACK
        case  0x90:                     // 之前已经收到一个通用地址,并收到数据字节,并返回ACK
        case  0x98:                     // 之前已经收到一个通用地址,并收到数据字节,并返回非ACK
					// OSMboxPost(I2cMbox, (void *)SLV_I2C_ACK_ERR);
             break;
        case  0xA0:                     // 收到一个停止条件或者重复的起始条件
         	OSMboxPost(I2cMbox, (void *)I2C_READ_END);
		I2cIntDisable();
        	I2CONSET |= AA;
/***********************************************************************************************/
              break;
        default:
            break;
    }

      I2CONCLR = 0x38;

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

⌨️ 快捷键说明

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