求助-中颖sh79f326 硬件I2C从机,接收硬件地址正常,从地址也正常,数据开始就接收异常,请问大家有成功案例,可以参考一下吗
void init_i2c()
{
select_bank1();
TWICR = 0x45; // SCK = P4.2 SDA = P3.4
select_bank0();
P4CR&=~0x0c; // 端口定义
P4PCR|=0x0c;
TWITOUT = 0x02; //TURN ON RESISTOR OF SCL,SDA
TWIBR=0x02; //配置发送波特率,禁止总线超时判断 f=fsys/(16+2*CR*TWIBR)
TWISTA=0x0; //64分频
TWICON = 0x48; //ENTWI ,禁止高电平超时
TWTFREE = 0xff; //最大超时配置
TWIADR=0x5A; //从机地址设定
TWICON=0x44;
IEN1|=0x01;
}
void INT_TWI(void) interrupt 7 /*TWI INT*/ //TWI中断子程
{
_push_(INSCON);
#if 1
twius=TWISTA&0xF8; //去除状态寄存器低三位并送至twius来判断状态码
if (twius==0x60) // /*IF twius=60,call 08H*/ 如果twius=60H
TWI_60H(); //调用TWI_60H子函数
else if (twius==0x80) ///*IF twius=70,call 08H*/ 如果twius=70H
TWI_80H(); //调用TWI_80H子函数
else if (twius==0x88) // /*IF twius=88,call 08H*/ 如果twius=88H
TWI_88H(); //调用TWI_88H子函数
else if (twius==0xA0) ///*IF twius=A0,call 08H*/ 如果twius=A0H
TWI_A0H(); //调用TWI_A0H子函数
else if (twius==0xA8) // /*IF twius=A8,call 08H*/ 如果twius=A8H
TWI_A8H(); //调用TWI_A8H子函数
else if (twius==0xB8) // /*IF twius=B8,call 08H*/ 如果twius=B8H
TWI_B8H(); //调用TWI_B8H子函数
else if (twius==0xC0) ///*IF twius=C0,call 08H*/ 如果twius=C0H
TWI_C0H(); //调用TWI_C0H子函数
else if (twius==0xC8) ///*IF twius=C8,call 08H*/ 如果twius=C8H
TWI_C8H(); //调用TWI_C8H子函数
else
{
TWINT=0;
isda = 1;
isma = 1;
}
#endif
TWINT=0;
_pop_(INSCON);
}
void TWI_60H() //从机接收模式已收到自己SLA+W;已回应ACK
{
TWINT=0;
if (isda)
{isda = 0;} //处理RECV事件(RECV DEVICE ADDR)
} //清TWI中断
void TWI_80H() //处于已寻址状态;已收到数据;已回应ACK
{
_nop_();
if (isma)
{
isma = 0; //处理RECV事件(RECV MEMORY ADDR)
cmd = TWIDAT;
rxCnt=0;
buffer[1]=0;
buffer[2]=0;
buffer[3]=0;
buffer[4]=0;
buffer[0]=cmd;
}
else
{
if(rxCnt<I2C_MAXBUF) //处理RECV事件(RECV DATA)
{buffer[++rxCnt] = TWIDAT;}
}
AA=1; ///*NACK*/ 从机答应位清0
TWINT=0; //清TWI中断
}
void TWI_88H() //处于已寻址状态;已收到数据;已回应NACK
{
_nop_();
_nop_();
buffer[++rxCnt] = TWIDAT;
AA=0; ///*ACK*/ 从机答应位置1
TWINT=0; // 清TWI中断
}
void TWI_A0H()
{
_nop_();
_nop_();
_nop_();
isda = 1;
isma = 1;
TWINT=0; // 清TWI中断
}
void TWI_A8H() //接收到读指令 已收到自己SLA+R;已经回应ACK
{
_nop_();
txCnt=0;
// TWIDAT = buffer[0];
TWIDAT = 1;
_nop_();
_nop_();
TWINT=0; // 清TWI中断
}
void TWI_B8H() //已发送TWIDAT数据;已接收ACK回应
{
_nop_();
_nop_();
AA=0; // /*NACK*/ 从机答应位清0
// TWIDAT = IIC_transmit(cmd);
TWIDAT = 2;
TWINT=0; // 清TWI中断
}
void TWI_C0H() //已发送TWIDAT数据;已接收NACK回应
{
_nop_();
_nop_();
isda = 1;
isma = 1;
TWINT=0; // 清TWI中断
_nop_();
_nop_();
AA=1; ///*ACK*/ 从机答应位置1
}
void TWI_C8H()
{
AA=1; ///*ACK*/ 从机答应位置1
TWINT=0; // 清TWI中断
}
|