27,375
社区成员
发帖
与我相关
我的任务
分享
void I2C1SlaveInit(DWORD freq, BYTE addr)
{
PCONP |= (0x1 << 19); // 打开电源
if (freq > 400000) freq = 400000;
PINSEL0 |= 0x30C00000;// 设置I2C控制口有效
I2C1ADR = (addr); // 设置从地址
I2C1SCLH = (Fpclk/freq + 1) / 2; // 设定I2C时钟
I2C1SCLL = (Fpclk/freq)/2;
I2C1CONCLR = 0x2C;
I2C1CONSET = 0x44; // 使能从I2C
I2C1ADR = (addr); // 设置从地址
// 设置I2C中断允许
install_irq(I2C1_INT, (void*)I2C1SlaveIrq);
}
BYTE wData[32] = {0xa1, 0xa2, 0xa3, 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x88, 0x0};
int wlength = 0x0;
// 从模式
#ifdef WIN32
void I2C1SlaveIrq(void)
#else
void I2C1SlaveIrq(void) __irq
#endif
{
BYTE stat = I2C1STAT;
/* 根据状态码进行相应的处理 */
switch ( stat & 0xF8)
{
case 0x60:
case 0x70: // 已接收到通用调用位和返回ACK。将接收数据和返回ACK
{
length = 0;
I2C1_end = 0;
I2C1CONSET = 0x4;
I2C1CONCLR = 0x8; // 写0x08 到I2CONCLR 来清除SI 标志?
break;
}
case 0x68:
case 0x78: // I2C开始,初始化接收数据
{
I2C1CONSET = 0x24;
I2C1CONCLR = 0x8; // 写0x08 到I2CONCLR 来清除SI 标志?
I2C1_buf = dataBuffer; // 建立从接收模式数据缓冲区。
length = 0;
I2C1_end = 0;
break;
}
case 0x80:
case 0x90:
{
dataBuffer[length++]= (BYTE)I2C1DAT;
//*I2C1_buf++ = I2C1DAT; // 读取I2DAT 的数据字节,存放到从机接收缓冲区?
//++length;
if ( length == 1 )
{
I2C1CONSET = 0x04; // AA=1
I2C1CONCLR = 0x08;
}else if ( length == 11 )
{
I2C1CONCLR = 0x02C;
} else
{
I2C1CONSET = 0x04; // AA=1
I2C1CONCLR = 0x08;
}
break;
}
case 0x88:
case 0x98:
{
I2C1CONCLR = 0x08;
I2C1CONSET = 0x04;
I2C1_end = 1;
break;
}
case 0xA0: // 结束
{
I2C1CONSET = 0x04;
I2C1CONCLR = 0x08;
wlength = 0x0;
I2C1_end = 1;
break;
}
//---- 发送
case 0xA8:
{
wlength = 0x0;
I2C1DAT = wData[wlength++];
I2C1CONSET = 0x04;
I2C1CONCLR = 0x08;
break;
}
case 0xB8: // 此处只会进入一次,后状态就为0xC0,
{
if ( wlength < 9 )
{
I2C1DAT = wData[wlength++];
I2C1CONCLR = 0x28;
}else
{
I2C1DAT = wData[wlength++];
I2C1CONCLR = 0x028;
}
break;
}
case 0xB0:
{
wlength = 0x0;
I2C1DAT = wData[wlength++];
I2C1CONSET = 0x24;
I2C1CONCLR = 0x08;
break;
}
case 0xC0:
{
I2C1CONSET = 0x04;
I2C1CONCLR = 0x28;
break;
}
case 0xC8:
{
wlength = 0x0;
//I2C1CONSET = 0x04;
I2C1CONCLR = 0x28;
break;
}
}
VICVectAddr = 0; // 中断处理结束
}