📄 key&i2c.c.svn-base
字号:
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 + -