本帖最后由 thammer 于 2015-3-27 20:03 编辑
主从机都是KL16,从机以中断方式接收,中断服务程序如下:主机能正确读到第一次的数据0x23,之后SCL,SDA被拉低。错误发生在:
if (I2C0->S & 0x01 ) //从机发送 主机ACK应答失败 停止发送
{/* 应答检测 */
/* 主机应答失败,停止发送 */
I2C0->C1 &= ~(1 << 4); //设置为接收模式 /* 接收模式 */
if (I2C0->D) ; /* 读一次 */
printf("I2C ACK error \r\n");
}
从机接收流程:
地址匹配中断-->切换为接收模式--->接收数据--->地址匹配中断--->切换为发送模式紧跟着发送第一个字节---->接收到停止中断,非应答,从机一个字节发送完成
但是看打印实际跑的流程是:
地址匹配中断-->切换为接收模式--->接收数据--->地址匹配中断--->切换为发送模式紧跟着发送第一个字节---->(未收到停止中断)准备发送第二个字节前检测到主机对第一一个字节无应答,卡死。
这里,应该不是主机没应答,而是SCL,SDA被从机拉死。请问这是什么原因?
下面是主机发送程序:
- unsigned char I2C0_ReadRegister(unsigned char SlaveID,unsigned char u8RegisterAddress)
- {
- unsigned char result;
- //unsigned char SlaveID;
- uint8_t I2C_Temp;
- /* Send Slave Address */
- I2C0_StartTransmission(SlaveID,MWSR);
- i2c0_Wait;
- /* Write Register Address */
- I2C0->D = u8RegisterAddress;
- i2c0_Wait;
- /* Do a repeated start */
- I2C0->C1 |= I2C_C1_RSTA_MASK;
- /* Send Slave Address */
- //I2C0->D = ((unsigned char) (ACCEL_I2C_ADDRESS << 1)|0x01); //read address
- I2C0->D = (unsigned char) (SlaveID|0x01); //read address
- i2c0_Wait;
- /* Put in Rx Mode */
- I2C0->C1 &= (~I2C_C1_TX_MASK);
- /* Turn off ACK since this is second to last byte being read*/
- I2C0->C1 |= I2C_C1_TXAK_MASK;
- /* Dummy read */
- result = I2C0->D ;
- I2C_Temp = result;
- i2c0_Wait;
- /* Send stop since about to read last byte */
- i2c0_Stop;
- /* Read byte */
- result = I2C0->D ;
- I2C_Temp = result;
- return I2C_Temp;
- }
|