📄 iic.c
字号:
#include "config.h"
#define IIC_WRITE_END 1
#define IIC_READ_END 2
#define IIC_LOST_BUS 4
#define IIC_ACK_ERROR 8
OS_EVENT *iicSem; /***IIC互斥访问信号量***/
OS_EVENT *iicMbox; /***本地信号用于从中断服务程序返回消息***/
static INT8U *iicBuf; /***缓冲区***/
static INT16U iicNbyte; /***读或写的长度***/
static INT8U iicAddr; /***设备地址***/
/*********************************************************************************************************
** 功能描述: 初始化IIC 频率不能超过400K
连接IIC到相应管脚
创建
********************************************************************************************************/
INT8U initIic(INT32U freq)
{
VICIntEnClr=1<<INTINDEXIIC;
if(freq>400000)
freq=400000;
PINSEL0=(PINSEL0&0XFFFFFF0F)|0X50; /***防止硬件初始化的时候没有配置***/
I2CONCLR=0X6C;/***AAC SIC STAC I2ENC 清除应答位、中断位、起始位、禁止IIC接口***/
I2SCLH=(Fpclk/freq+1)/2+1;
I2SCLL=(Fpclk/freq+1)/2;
//iicMutex=OSMutexCreate(IICMUTEXPRIORITY,&err);/***信用信号量测试,正式应用的时候应该用互斥信号量***/
iicSem=OSSemCreate(1); /***创建IIC信号量,只有一个IIC接口可用***/
iicMbox=OSMboxCreate(NULL);
if(iicMbox==NULL)
return(FALSE);
if(iicSem!=NULL)
return(TRUE);
return(FALSE);
}
/*********************************************************************************************************
** 功能描述: 写iiC,但不发送STOP信号 ,
提供给真正的读写函数使用,因为读写操作的时候,总是执行一段相同的处理
启动IIC 发送起始信号 写入设备地址 如果有子地址 写子地址
**注意:现行的驱动程序中 数据区包含器件的子地址(如果有)所以长度也包含子地址的长度
********************************************************************************************************/
INT8U __iicWrite(INT8U addr,INT8U *Data,INT16U length)
{
INT8U err;
unsigned int result;
iicAddr=addr&0xfe;
iicNbyte=length;
iicBuf=Data;
I2CONSET=0X24;/***发送起始条件***/
result=(unsigned int)OSMboxPend(iicMbox,0,&err);
return(result);
}
INT16U iicWrite(INT8U deviceAdd,INT8U*data,INT16U length)
{
INT8U err;
OSSemPend(iicSem,0,&err);//等待IIC信号量
I2CONCLR=0X6C;
I2CONSET=0X40;/***使能IIC接口***/
VICIntEnable=1<<INTINDEXIIC;
if(__iicWrite(deviceAdd,data,length)==IIC_WRITE_END)
{
I2CONSET=1<<4;/***发送停止信号***/
I2CONCLR=0X28;/***清除SI标志***/
}
VICIntEnClr=1<<INTINDEXIIC;/***禁止IIC中断***/
OSSemPost(iicSem);
return(length-iicNbyte);/***返回已写入的字节数***/
}
int16 iicRead(INT8U deviceAdd,INT8U *result,INT8U *extendAdd,INT8U extendAddLength,INT16U length)
{
INT8U err;
OSSemPend(iicSem,0,&err);
I2CONCLR=0X6C;
I2CONSET=0X40;
VICIntEnable=1<<INTINDEXIIC;
if(extendAddLength>0)
{
if(__iicWrite(deviceAdd,extendAdd,extendAddLength)!=IIC_WRITE_END)
{
return(-1);
}
}
iicAddr=deviceAdd|0x01;//转入读操作
iicNbyte=length;
iicBuf=result;
I2CONCLR=0X28;
I2CONSET=0x24;//为什么是24 2 起始标志,4 AC 为什么呢
VICIntEnable=1<<INTINDEXIIC;
OSMboxPend(iicMbox,0,&err);
VICIntEnClr=1<<INTINDEXIIC;
OSSemPost(iicSem);
return(length-iicNbyte);
}
/***IIC 主机模式 读写中断服务程序;根据数据手册中的中断状态进行处理***/
void IIC_Exception(void)
{
OS_ENTER_CRITICAL();
switch(I2STAT&0XF8)
{
case 0X08://已发送起始条件
{
//break;
}
case 0x10://已发送重新起始条件 目的是发送设备地址,
//如果首是写操作,因为CASE 0X08的时候没有break
//所以还是发送地址,
{
I2DAT=iicAddr;
I2CONCLR=0X28;
break;
}
case 0x18://已发送SLA+W;已接受ACK,下面发送数据
{
I2DAT=*iicBuf++;
iicNbyte--;
I2CONCLR=0X28;
break;
}
case 0x28://已发送I2DAT中的数据字节,已接受ACK
//下面若果数据没有发送完毕继续I2DAT=DATA;
//如果数据发送完毕,返回__iicWrite()函数,写完成标志
{
if(iicNbyte>0)//数据还没有发送完毕
{
I2DAT=*iicBuf++;//发送数据
iicNbyte--;
I2CONCLR=0X28;
}
else
{
OSMboxPost(iicMbox,(void*)IIC_WRITE_END);//写操作完成
VICIntEnClr=1<<INTINDEXIIC;
}
break;
}
case 0x20://已发送SLA+W;已接收非ACK
case 0x30://已发送I2DAT中的数据;已接收非ACK
case 0x48://已发送SLA+R;已接收非ACK
{
I2CONSET=1<<4;//发送STOP
OSMboxPost(iicMbox,(void *)IIC_ACK_ERROR);
I2CONCLR=0X28;
break;
}
case 0x38://在发送SLA+R时丢失仲裁
{
OSMboxPost(iicMbox,(void*)IIC_LOST_BUS);
I2CONCLR=0X28;
break;
}
case 0x40://已发送SLA+R;已接收ACK;无I2DAT动作;硬件将要接收数据;返回应答或者非应答
{
if(iicNbyte<=1)
{
I2CONCLR=1<<2;//下次发送非应答
}
else
{
I2CONSET=1<<2;//下次发送应答信号
}
I2CONCLR=0X28;
break;
}
case 0x50://已接收到数据字节;已发送ACK
{
*iicBuf++=I2DAT;//接收数据
iicNbyte--;
if(iicNbyte<=1)
{
I2CONCLR=1<<2;//如果是还剩下一个数据没有接受下次发送非应答信号
}
I2CONCLR=0X28;
break;
}
case 0x58://已接收数据字节;已发送非ACK
{
*iicBuf=I2DAT;//接收最后一个数据
iicNbyte--;
I2CONSET=1<<4;//结束总线,发送STOP
OSMboxPost(iicMbox,(void*)IIC_READ_END);
I2CONCLR=0X28;
break;
}
default:
{
I2CONCLR=0X28;
break;
}
}
VICVectAddr=0;//通知中断服务程序结束
OS_EXIT_CRITICAL();//退出中断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -