求助lms9b96的I2C通信问题



我是一个初学者,第一次弄I2C通信,出现了几个问题,在此求助下各位前辈了。

我用lms9b96做从机,接收来自主机的命令帧,通过解析命令上报相关的信息。

问题是这样的:

1、每次主机发送地址时,我从机这边不能每次都有应答,也就是偶尔回响应偶尔不响应,通过串口打印信息发现偶尔能够进入数据接收中断,偶尔不能进入;

2、另外就是,即使进入了中断,通过串口打印接收数据,发现与主机发送的不吻合;

是不是程序中的函数设置有误?还是有没有考虑到的问题?确实没有解决思路了,请教大家了,非常感谢。

#include "iic.h"

volatile unsigned char g_ucDataRx = LED_ON;
volatile unsigned long ulStatus = 0;
volatile unsigned long ulSrisStatus=0;

unsigned char *pucI2CDataOut;
unsigned char ucDataReady;
unsigned char ucI2CDataIn[16]={16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char ReceDataFlag = 0;
unsigned char ucCRC8Table[]={};
void DebugInfo()
{
UARTprintf("DataIn[0] %d\n",ucI2CDataIn[0]);
UARTprintf("DataIn[1] %d\n",ucI2CDataIn[1]);
UARTprintf("DataIn[2] %d\n",ucI2CDataIn[2]);
UARTprintf("DataIn[3] %d\n",ucI2CDataIn[3]);
UARTprintf("DataIn[4] %d\n",ucI2CDataIn[4]);
UARTprintf("DataIn[5] %d\n",ucI2CDataIn[5]);
UARTprintf("DataIn[6] %d\n",ucI2CDataIn[6]);
UARTprintf("DataIn[7] %d\n",ucI2CDataIn[7]);
UARTprintf("DataIn[8] %d\n",ucI2CDataIn[8]);
UARTprintf("DataIn[9] %d\n",ucI2CDataIn[9]);
UARTprintf("DataIn[10] %d\n",ucI2CDataIn[10]);
}

void I2C1_Init()
{

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // 使能I2C1相应的引脚时钟
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);// 配置PA0和PA1引脚的类型
//
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);// 配置PA6和PA7为SCL和SDA
//
GPIOPinConfigure(GPIO_PA6_I2C1SCL);//bule
GPIOPinConfigure(GPIO_PA7_I2C1SDA);//yellow

I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS);// 设置本身地址
//
I2CSlaveEnable(I2C1_SLAVE_BASE);// 使能I2C模块
//
I2CSlaveIntEnable(I2C1_SLAVE_BASE);// 使能从机中断源
//
IntEnable(INT_I2C1); // 开启I2C1的中断

I2CSlaveIntEnableEx(I2C1_SLAVE_BASE, I2C_SLAVE_INT_DATA|I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP);//中断条件选择//I2C_SLAVE_INT_DATA|
//I2CSlaveIntEnableEx(I2C1_SLAVE_BASE,I2C_SLAVE_INT_DATA);
}

unsigned char ucSendByteCounter = 0;
unsigned char ucReceByteCounter = 0;

void I2C1IntHandler(void)
{

//GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, LED_OFF);
//UARTprintf("IIC_In");

I2CSlaveIntClear(I2C1_SLAVE_BASE);// 清除中断
//
ulStatus = I2CSlaveStatus(I2C1_SLAVE_BASE); // 读取中断状态
//
ulStatus = ulStatus & (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_TREQ | I2C_SLAVE_CSR_FBR);// 屏蔽不需要的位
//
//
// 读取原始中断状态
//
ulSrisStatus = I2CSlaveIntStatusEx(I2C1_SLAVE_BASE,SLAVE_ADDRESS);
//
// 屏蔽原始中断不需要的位
//
ulSrisStatus = ulSrisStatus & (I2C_MASTER_CS_STOP | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN);

I2CSlaveIntClearEx(I2C1_SLAVE_BASE,I2C_SICR_STOPIC | I2C_SICR_DATAIC | I2C_SICR_STARTIC);
switch(ulSrisStatus){
//
// 停止信号中断
//
case I2C_MASTER_CS_STOP:
ucReceByteCounter = 0;
ReceDataFlag = 1;
UARTprintf("D#Cnt_stop %d\n",ucReceByteCounter);

break;
//
// 停止信号中断
//
case I2C_MASTER_CS_START:
ucReceByteCounter = 1;
UARTprintf("D#Cnt_start %d\n",ucReceByteCounter);

break;
default:
break;
}
switch(ulStatus){ // 判断状态

// 有发送请求,发送数据
case I2C_SLAVE_CSR_TREQ: // Transmit request received
if(ucSendByteCounter < *(pucI2CDataOut+1)+1){
I2CSlaveDataPut(I2C1_SLAVE_BASE , *(pucI2CDataOut + ucSendByteCounter));
ucSendByteCounter ++ ;
}
else
I2CSlaveDataPut(I2C1_SLAVE_BASE,0xaa);
break;

// 接收数据
case (I2C_SLAVE_CSR_RREQ): // Receive data from I2C master
ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE);
ucReceByteCounter++;
UARTprintf("DCnt %d\n",ucReceByteCounter);
ReceDataFlag = 1;
break;

// 接受到第一个字节
case (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_FBR ): // First byte received from master
ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE);
UARTprintf("D#Cnt %d\n",ucReceByteCounter);
ucReceByteCounter++;
/ReceDataFlag = 1;
break;

default:
break;

}
}