微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 硬件中断方式I2C(CVAVR)

硬件中断方式I2C(CVAVR)

时间:11-18 来源:互联网 点击:
interrupt[TWI]voidtwi_isr(void)
{
//读状态位
unsignedcharstatus;
status=TWSR&TWSR_STATUS_MASK;
switch(status)
{
//主方式
caseTW_START://0x08:START已发送
caseTW_REP_START://0x10:重复START已发送
//发送器件地址
i2cSendByte(I2cDeviceAddrRW);
break;

//主发送,主接收状态码
caseTW_MT_SLA_ACK://0x18:SLA+W已发送;接收到ACK
caseTW_MT_DATA_ACK://0x28:数据已发送;接收到ACK

if(I2cSendDataIndex{
//发送数据
i2cSendByte(I2cSendData[I2cSendDataIndex++]);
}
else
{
//发送停止条件,保持TWEA以便从接收
i2cSendStop();
//设置状态
I2cState=I2C_IDLE;
}
break;
caseTW_MR_DATA_NACK://0x58:接收到数据;NOTACK已返回

//保存最终数据
I2cReceiveData[I2cReceiveDataIndex++]=TWDR;
//继续发送条件
caseTW_MR_SLA_NACK://0x48:SLA+R已发送,接收到NOTACK
caseTW_MT_SLA_NACK://0x20:SLA+W已发送,接收到NOTACK
caseTW_MT_DATA_NACK://0x30:数据已发送,接收到NOTACK

//发送停止条件,保持TWEA以便从接收
i2cSendStop();
//设置状态
I2cState=I2C_IDLE;
break;
caseTW_MT_ARB_LOST://0x38:SLA+W或数据的仲裁失败

//释放总线
TWCR=TWCR&TWCR_CMD_MASK|(1//设置状态
I2cState=I2C_IDLE;

break;
caseTW_MR_DATA_ACK://0x50:接收到数据,ACK已返回

//保存接收到的数据位
I2cReceiveData[I2cReceiveDataIndex++]=TWDR;
//检查是否接收完
caseTW_MR_SLA_ACK://0x40:SLA+R已发送,接收到ACK

if(I2cReceiveDataIndex<(I2cReceiveDataLength-1))
//数据位将接收,回复ACK(传送更多字节)
i2cReceiveByte(TRUE);
else
//数据位将接收,回复NACK(传送最后字节)
i2cReceiveByte(FALSE);
break;

//从接收状态码
caseTW_SR_SLA_ACK://0x60:自己的SLA+W已经被接收,ACK已返回
caseTW_SR_ARB_LOST_SLA_ACK://0x68:SLA+R/W作为主机的仲裁失败;自己的SLA+W已经被接收,ACK已返回
caseTW_SR_GCALL_ACK://0x70:接收到广播地址,ACK已返回
caseTW_SR_ARB_LOST_GCALL_ACK://0x78:SLA+R/W作为主机的仲裁失败;接收到广播地址,ACK已返回

//被选中为从写入(数据将从主机接收)
//设置状态
I2cState=I2C_SLAVE_RX;
//缓冲准备
I2cReceiveDataIndex=0;
//接收数据,回应ACK
TWCR=TWCR&TWCR_CMD_MASK|(1break;
caseTW_SR_DATA_ACK://0x80:以前以自己的SLA+W被寻址;数据已经被接收,ACK已返回
caseTW_SR_GCALL_DATA_ACK://0x90:以前以广播方式被寻址;数据已经被接收,ACK已返回

I2cReceiveData[I2cReceiveDataIndex++]=TWDR;
//检查接收缓冲区状态
if(I2cReceiveDataIndex{
//接收数据,回应ACK
i2cReceiveByte(TRUE);
}
else
{
//接收数据,回应NACK
i2cReceiveByte(FALSE);
}
break;
caseTW_SR_DATA_NACK://0x88:以前以自己的SLA+W被寻址;数据已经被接收,NOTACK已返回
caseTW_SR_GCALL_DATA_NACK://0x98:以前以广播方式被寻址;数据已经被接收,NOTACK已返回

//接收数据,回应NACK
i2cReceiveByte(FALSE);
break;
caseTW_SR_STOP://0xA0:在以从机工作时接收到STOP或重复START
TWCR=TWCR&TWCR_CMD_MASK|(1//i2c接收完成
if(i2cSlaveReceive)
i2cSlaveReceive(I2cReceiveDataIndex,I2cReceiveData);
//设置状态
I2cState=I2C_IDLE;
break;

//从发送
caseTW_ST_SLA_ACK://0xA8:自己的SLA+R已经被接收,ACK已返回
caseTW_ST_ARB_LOST_SLA_ACK://0xB0:SLA+R/W作为主机的仲裁失败;自己的SLA+R已经被接收,ACK已返回

//被选中为从读出(数据将从传回主机)
//设置状态
I2cState=I2C_SLAVE_TX;
//数据请求
if(i2cSlaveTransmit)I2cSendDataLength=i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE,I2cSendData);
I2cSendDataIndex=0;
//
caseTW_ST_DATA_ACK://0xB8:TWDR里数据已经发送,接收到ACK

//发送数据位
TWDR=I2cSendData[I2cSendDataIndex++];
if(I2cSendDataIndex//回应ACK
TWCR=TWCR&TWCR_CMD_MASK|(1else
//回应NACK
TWCR=TWCR&TWCR_CMD_MASK|(1break;
caseTW_ST_DATA_NACK://0xC0:TWDR里数据已经发送接收到NOTACK
caseTW_ST_LAST_DATA://0xC8:TWDR的一字节数据已经发送(TWAE=“0”);接收到ACK

//全部完成
//从方式开放
TWCR=TWCR&TWCR_CMD_MASK|(1//设置状态
I2cState=I2C_IDLE;
break;

caseTW_NO_INFO://0xF8:没有相关的状态信息;TWINT=“0”
//无操作

break;
caseTW_BUS_ERROR://0x00:由于非法的START或STOP引起的总线错误

//内部硬件复位,释放总线
TWCR=TWCR&TWCR_CMD_MASK|(1//设置状态
I2cState=I2C_IDLE;
break;
}
}

//从操作
voidi2cSlaveReceiveService(unsignedcharreceiveDataLength,unsignedchar*receiveData)
{
unsignedchari;
//此函数在本机被选中为从写入时运行
//接收到的数据存入本地缓冲区
for(i=0;i{
localBuffer[i]=*receiveData++;
}
localBufferLength=receiveDataLength;

}

unsignedchari2cSlaveTransmitService(unsignedchartransmitDataLengthMax,unsignedchar*transmitData)
{
unsignedchari;

//此函数在本机被选中为从读出时运行
//要发送的数据存入发送缓冲区
for(i=0;i{
*transmitData++=localBuffer[i];
}

localBuffer[0]++;

returnlocalBufferLength;
}


#defineTARGET_ADDR0xA0
//测试(24xxyy器件)
voidtestI2cMemory(void)
{
unsignedchari;
unsignedchartxdata[66];
unsignedcharrxdata[66];

txdata[0]=0;
txdata[1]=0;

for(i=0;i<16;i++)
txdata[2+i]=localBuffer[i];
//发送地址和数据
i2cMasterSendNI(TARGET_ADDR,18,txdata);

txdata[18]=0;

//发送地址
i2cMasterSendNI(TARGET_ADDR,2,txdata);
//接收数据
i2cMasterReceiveNI(TARGET_ADDR,16,rxdata);
//
rxdata[16]=0;

}

voidmain(void)
{
i2cInit();
//设置从接收函数句柄(此函数在被选中为从接收时执行)
i2cSetSlaveReceiveHandler(i2cSlaveReceiveService);
//设置从发送函数句柄(此函数在被选中为从发送时执行)
i2cSetSlaveTransmitHandler(i2cSlaveTransmitService);
testI2cMemory();

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top