周公好, 又来麻烦你了,最近一周一直在看I2C的相关资料和你们写的源码,也在用开发板做实验,但还是有很多问题不明白,所以这里想详细问下。 1,首先是这里 void __irq IRQ_I2C(void) { uint8 sta;
sta = I2STAT; // 读出I2C状态字 switch(sta) { case 0x08: // 己发送起始条件 if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址 else I2DAT = I2C_sla; // 否则直接发送从机地址 I2CONCLR = 0x28; // SI=0 break; Question1:为什么else后面不分情况?因为写操作时候(2==I2C_suba_en),也要写从机地址+子地址啊;2==I2C_suba_en和0==I2C_suba_en后面执行的动作肯定应该不一样啊,为什么不分情况,直接就else I2DAT = I2C_sla; ...了呢?? 2 case 0x18: // 已发送SLA+W,并已接收应答 if(0==I2C_suba_en) // 无子地址,则直接发送数据 { if(I2C_num>0) { I2DAT = *I2C_buf++; I2CONCLR = 0x28; I2C_num--; } Question2:无子地址应该是写了从机地址+子地址后就可以叫无子地址了;在18H这个状态子地址肯定是没有写入到从机的啊,所以应该还有子地址,所以我的疑问是怎么会在case 18H的时候出现无子地址直接发送数据这个语句呢(就是我上面贴出来这句)?? 3 case 0x40: // 己发送SLA+R,并已接收到应答 if(1==I2C_num) // 最后一字节,接收数据后发送非应答信号 { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答 } else // 接收数据并发送应答信号 { I2CONSET = 0x04; // AA=1,接收到数据后产生应答 I2CONCLR = 0x28; } break; case 0x50: *I2C_buf++ = I2DAT; // 读取数据 I2C_num--; if(1==I2C_num) { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答 } else { I2CONSET = 0x04; // AA=1,接收到数据后产生应答 I2CONCLR = 0x28; } break; Question3:40H是从机已经给主机发送了应答位,在case 40H这个语句里为什么没有象case 50H接受数据的语句?我分析是case 40H语句里是能够接受数据的。 Question4:为什么最后一字节用if(1==I2C_num)判断而不是if(0==I2C_num)?? |