现用MSP430G2755做串口通讯,115200,遵照协议:头码1(AA)+头码2(55)+长度+命令+数据+校验
用上位机和430通讯,430接收到完整数据包后根据命令回传响应,其中数据的处理都是在接收中断完成的。现在存在一个问题:上位机如果两条指令发送间隔过小,则430接收不到完整数据包。
请教高手 对于这种串口协议有没有更高效的处理方法。
附上code:
void USCI_USART(unsigned char Baud)
{
P3SEL|= BIT4 + BIT5;// P3SEL2 = BIT4 + BIT5; UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 8; // 1MHz 115200
UCA0BR1 = 0; // 1MHz 115200
UCA0MCTL = UCBRS2 + UCBRS1; // Modulation UCBRSx = 6
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
__enable_interrupt();
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
UCA0TXBUF=TXData[TXBytes++];
if(TXBytes==TXData_Length)
{
IE2 &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt
TXBytes=0;
}
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
USCI_USART_RX();
}
void USCI_USART_RX(void)
{
RXData[RXBytes++]=UCA0RXBUF;
switch(RXBytes)
{
case 1:
if(RXData[0]!=HeadCode1)
{
// //数据出错
// TXData_Length=5;
// TXData[2]=TXData_Length-3;
// TXData[3]=RXData[0];
// TXData[4]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1);// IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
break;
case 2:
if(RXData[1]!=HeadCode2)
{
// //数据出错
// TXData_Length=5;
// TXData[2]=TXData_Length-3;
// TXData[3]=CMD_Data_Error;
// TXData[4]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1);// IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
break;
default :
if(RXBytes==(RXData[2]+3))//数据接收完成
{ switch(RXData[3])
{
case CMD_Temperature:
TXData_Length=7;
if(RXData[RXBytes-1]==crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,RXData,4))
{
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Temperature;
TXData[4]=Battery.SMBusTemperature&0x00ff;
TXData[5]=(Battery.SMBusTemperature&0xff00)>>8;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
else
{
//数据出错
TXData_Length=5;
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Data_Error;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
break;
case CMD_Voltage:
TXData_Length=7;
if(RXData[RXBytes-1]==crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,RXData,4))
{
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Voltage;
TXData[4]=Battery.SMBusVoltage&0x00ff;
TXData[5]=(Battery.SMBusVoltage&0xff00)>>8;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
else
{
//数据出错
TXData_Length=5;
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Data_Error;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
break;
case CMD_Current:
TXData_Length=7;
if(RXData[RXBytes-1]==crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,RXData,4))
{
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Current;
TXData[4]=Battery.SMBusCurrent&0x00ff;
TXData[5]=(Battery.SMBusCurrent&0xff00)>>8;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
else
{
//数据出错
TXData_Length=5;
TXData[2]=TXData_Length-3;
TXData[3]=CMD_Data_Error;
TXData[TXData_Length-1]=crc8MakeBitwise(SMBUS_CRC8_INIT_REM,SMBUS_CRC8_POLY,TXData,TXData_Length-1); IE2 |= UCA0TXIE; // Enable USCI_A0 TX interrupt
RXBytes=0;
}
break;
}
}
灰小子:
楼主的问题属于通讯数据丢失。可能的原因是msp430速度太慢,或者cpu被占用,接收不及时。看楼主的代码觉得是后者。
中断占用cpu太多时间,就会影响后续的通讯。
建议尽量不要把程序放在中断中执行。
Seven Han:
HI,
中断中不应该有太多程序,中断应该仅做为消除中断,拿到数据应该清除中断标志位,让其他程序处理中断取得数据。您可以用TI MSPWare 提供demo进行修改为回显检查发送和接收的数据是否一致。