This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2755 I2C做从机,通讯中MSP430复位。

I2C做从机,MSP430概率性自动复位。受不了了,贴上code,高手帮忙看一下,数据收发都是在中断完成。感觉问题就出在中断处理上。

void (*TI_receive_callback)(unsigned char receive);
void (*TI_transmit_callback)(unsigned char volatile *send_next);
void (*TI_start_callback)(void);
void (*TI_stop_callback)(void);
void USCI_I2C_Enable(void);
void USCI_I2C_DisEnable(void);
unsigned char TI_USCI_I2C_notready(void);

void TI_USCI_I2C_slaveinit(void (*SCallback)(),
void (*TCallback)(unsigned char volatile *value),
void (*RCallback)(unsigned char value),
void (*StCallback)(),
unsigned char slave_address){
P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 10; // Set prescaler 1M/10~100KHZ
UCB0BR1 = 0;
UCB0I2COA = slave_address; // set own (slave) address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
// IE2 |= UCB0TXIE + UCB0RXIE; // Enable TX RX interrupt
// UCB0I2CIE |= UCSTTIE+UCSTPIE; // Enable STT STP interrupt
TI_start_callback = SCallback;
TI_stop_callback = StCallback;
TI_receive_callback = RCallback;
TI_transmit_callback = TCallback;
}
void USCI_I2C_Enable(void)
{
IE2 |= (UCB0TXIE + UCB0RXIE); // Enable TX RX interrupt
UCB0I2CIE |= (UCSTTIE+UCSTPIE); // Enable STT STP interrupt
}

// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if (IFG2 & UCB0TXIFG)
{
TI_transmit_callback(&UCB0TXBUF);
}
else
{
TI_receive_callback(UCB0RXBUF);
}

}

// USCI_B0 State ISR
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
if(UCB0STAT&UCSTTIFG)
{
UCB0STAT &= ~UCSTTIFG; // Clear start condition int flag
rxnum=0;//接收到开始信号清零
}
if(UCB0STAT&UCSTPIFG)
{
UCB0STAT&=~UCSTPIFG;
TI_stop_callback();
}
}

void receive_cb(unsigned char receive){
unsigned char temp[37]={0},rxtemp=0;
temp[0]=0x16;
temp[2]=0x17;
rxtemp=receive;
I2C_RXData[rxnum]= rxtemp;
rxnum++;
switch(I2C_RXData[0])
{
//Read Word
case 0x08: 
I2C_Block_TXData[0]=Battery.SMBusTemperature&0x00ff;
I2C_Block_TXData[1]=(Battery.SMBusTemperature&0xff00)>>8;
temp[1]=0x08;
temp[3]=I2C_Block_TXData[1];
temp[4]=I2C_Block_TXData[0];
I2C_Block_TXData[2]=crc8MakeBitwise(0,0x07,temp,5);
break;
case 0x09: 
I2C_Block_TXData[0]=Battery.SMBusVoltage&0x00ff;
I2C_Block_TXData[1]=(Battery.SMBusVoltage&0xff00)>>8;
temp[1]=0x09;
temp[3]=I2C_Block_TXData[1];
temp[4]=I2C_Block_TXData[0];
I2C_Block_TXData[2]=crc8MakeBitwise(0,0x07,temp,5);
break;
case 0x2a: 
I2C_Block_TXData[0]=Battery.SMBusCurrent&0x00ff;
I2C_Block_TXData[1]=(Battery.SMBusCurrent&0xff00)>>8;
temp[1]=0x2a;
temp[3]=I2C_Block_TXData[1];
temp[4]=I2C_Block_TXData[0];
I2C_Block_TXData[2]=crc8MakeBitwise(0,0x07,temp,5);
break;
//Read Block
case 0x60: //固件版本号
I2C_Block_TXData[0]=15;
for(unsigned char index=1;index<16;index++)
{
I2C_Block_TXData[index]=Software_Version[index-1];
}
temp[1]=0x60;
for(unsigned char index=3;index<19;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[16]=crc8MakeBitwise(0,0x07,temp,19);
break;
case 0x26: //序列号
I2C_Block_TXData[0]=13;
for(unsigned char index=1;index<14;index++)
{
I2C_Block_TXData[index]=Battery.SMBusManufacturerInfo[index-1];
}
temp[1]=0x26;
for(unsigned char index=3;index<17;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[14]=crc8MakeBitwise(0,0x07,temp,17);
break;
case 0x23: //报警值
I2C_Block_TXData[0]=6;
for(unsigned char index=1;index<7;index++)
{
I2C_Block_TXData[index]=Battery.SMBusAlarm[index-1];
}
temp[1]=0x23;
for(unsigned char index=3;index<10;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[7]=crc8MakeBitwise(0,0x07,temp,10);
break;
case 0x20: 
I2C_Block_TXData[0]=8;
for(unsigned char index=1;index<9;index++)
{
I2C_Block_TXData[index]=Battery.SMBusManufactureNume[index-1];
}
temp[1]=0x20;
for(unsigned char index=3;index<12;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[9]=crc8MakeBitwise(0,0x07,temp,12);
break;
case 0x21: 
I2C_Block_TXData[0]=10;
for(unsigned char index=1;index<11;index++)
{
I2C_Block_TXData[index]=Battery.SMBusDeviceName[index-1];
}
temp[1]=0x21;
for(unsigned char index=3;index<14;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[11]=crc8MakeBitwise(0,0x07,temp,14);
break;
case 0x22: 
I2C_Block_TXData[0]=4;
for(unsigned char index=1;index<5;index++)
{
I2C_Block_TXData[index]=Battery.SMBusDeviceChemistry[index-1];
}
temp[1]=0x22;
for(unsigned char index=3;index<8;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[5]=crc8MakeBitwise(0,0x07,temp,8);
break;
/*****************BootLoader Command********************/
//Write Block
case 0x89://BootLoader Jump @F000
temp[1]=0x89;
temp[0]=0x16;
if(rxnum>=4)
{
if(I2C_RXData[1]==0xCC&&I2C_RXData[2]==0xAA)
{
for(unsigned char index3=2;index3<4;index3++)
{
temp[index3]=I2C_RXData[index3-1];
}
if(I2C_RXData[3]==crc8MakeBitwise(0,0x07,temp,4))
{
EraseFlash(0,0xEE00,1,0x200);//擦除应用程序Flash区,起始地址0xEE00,页大小0x200,共1页 0xEE00-EFFF
WriteFlash(0xEE00,(unsigned char *)Updata_flag,4);//写FLASH
asm(" mov &0xFFFE, PC;");//RESET
}
}
}
break;
//Read Block
case 0x51://read status

I2C_Block_TXData[0]=3;
I2C_Block_TXData[1]=0x5f;//APP模式
I2C_Block_TXData[2]=0x00;
I2C_Block_TXData[3]=0x00;
temp[1]=0x51;
for(unsigned char index=3;index<7;index++)
{
temp[index]=I2C_Block_TXData[index-3];
}
I2C_Block_TXData[4]=crc8MakeBitwise(0,0x07,temp,7);
break;
/*******************************************/
default :
start_cb();
stop_cb();
for(unsigned char index1=0;index1<sizeof(I2C_Block_TXData);index1++)
I2C_Block_TXData[index1]=0;
break;
}

}
void start_cb(){
for(unsigned char index=0;index<sizeof(I2C_RXData);index++)
{
I2C_RXData[index]=0;
}
}
void stop_cb(){
I2C_flag=0;
}
void transmit_cb(unsigned char volatile *byte){
*byte = I2C_Block_TXData[I2C_flag];
I2C_flag++;
}

  • 无人答复,自己消灭0回复吧,问题定位在定时器中断,屏蔽掉定时器就OK。但定时器为什么会概率性引起复位,这个很奇怪,若果是定时器溢出,应该每次都会复位的啊,有没有人解答。

    还有按键中断也会概率性引起USCI——I2C SDA一直被拉低。有高手遇到过这个问题吗。求解答,很急。。。。。。。。。。。。。。。。。。。。。