📄 i2c.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 + -