主题中讨论的其他器件:C2000WARE
您好!
我使用微控制器的 SCI-A 外设与 THVD1450DGK 连接。 我观察到、外设遇到溢出错误(OE) 大约10-15次后、它停止生成中断。
通过检查外设寄存器可以看到 SCIRXST 寄存器中的所有 RXRDY 和 OE 标志都被置位、RXBKINTENA 和 RXERRINTENA 位也被置位。 中断也在 PIE 级别启用。
以下是我的 RX 中断的代码。 感谢您的帮助。
__interrupt void sciaRX_isr(void)
{
// Check if interrupt was entered because of an error. In that case put SCI module into a reset state.
if (SciaRegs.SCIRXST.bit.RXERROR == 1)
{
//check which error happened.
if (SciaRegs.SCIRXST.bit.OE)
sciOEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.PE)
sciPEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.FE)
sciFEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.BRKDT)
sciBRKDTErrorCountThvd++;
//SW_RESET SCI
SciaRegs.SCICTL1.bit.SWRESET = 0;
SciaRegs.SCICTL1.bit.SWRESET = 1;
sciErrorCountThvd++;
enter_mute();
}
/*enter this if the errors have not caused the interrupt*/
else if (SciaRegs.SCIRXST.bit.RXRDY) //rx caused the interrupt
{
if (SciaRegs.SCIRXST.bit.RXWAKE == 1) // Address byte has been received. RXWAKE is set when address bit is detected in the word.
{
rxIndexThvd = 0;
}
rxPackThvd[rxIndexThvd] = SciaRegs.SCIRXBUF.bit.SAR;
switch (rxIndexThvd)
{
case 0: //Looking for address byte.
{
if (rxPackThvd[0] == SENSOR_ID) // If address byte matches sensor_id
{
rxIndexThvd++; //increase rxIndexthvd to accept next character.
SciaRegs.SCICTL1.bit.SLEEP = 0; //bring the uart peripheral out of sleep as it is being addressed!
break;
}
else
{
rxIndexThvd = 0; //reset rxindexThvd
enter_mute(); //if the address byte received doesn't match the one set by software stay in sleep
}
break;
}
case 1:
{
//index 1 will be the instruction type.
//insert code here to evaluate rxPackLenThvd based on isntruction type.
//if rxPackLenThvd is fixed leave this if statement empty.
rxIndexThvd++;
break;
}
default:
{
if (rxIndexThvd == (rxPackLenThvd - 1)) //last byte in packet has been received.
{
if (calculate_crc(rxPackThvd, rxPackLenThvd)
== ((rxPackThvd[rxPackLenThvd - 2] | (rxPackThvd[rxPackLenThvd - 1] << 8)))) //crc check over here
{
rxPackCount++;
// Return type code Start
/*
* */
// Return Type Code End
if (txPackLenThvd > 0) // means that data has to be sent back to the uC
{
GpioDataRegs.GPBSET.bit.GPIO33 = 1; //NRE
GpioDataRegs.GPASET.bit.GPIO16 = 1; //DE
thvd_copy_shdbuff(); // functions copies shadow buffer into main transmit buffer.
SciaRegs.SCICTL1.bit.RXENA = 0;
SciaRegs.SCICTL1.bit.RXERRINTENA = 0;
SciaRegs.SCICTL2.bit.RXBKINTENA = 0; // disable RX interrupts and RX
SciaRegs.SCICTL1.bit.TXENA = 1;// enable TX and TXINT
SciaRegs.SCICTL2.bit.TXINTENA = 1;
SciaRegs.SCITXBUF.bit.TXDT = txPackThvd[0]; //put the first packet of data to be sent
txIndexThvd = 1; //set txIndexThvd to 1 as first byte has already been loaded.
}
else //if there is nothing to transmit then enter mute again.
{
enter_mute();
}
break;
}
else //crc failed
{
crcErrorCountThvd++;
enter_mute();
break;
}
}
rxIndexThvd++;
}
}
}
//acknowledge Group interrupt
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}ENTER_MUTE()函数
void enter_mute(void)
{
GpioDataRegs.GPBCLEAR.bit.GPIO33 = 1; // clear NRE
GpioDataRegs.GPACLEAR.bit.GPIO16 = 1; // clear DE
SciaRegs.SCICTL1.bit.SWRESET = 0; // reset
SciaRegs.SCICTL1.bit.RXENA = 1; //enable rx
SciaRegs.SCICTL1.bit.RXERRINTENA = 1; //enable rx error interrupt
SciaRegs.SCICTL2.bit.RXBKINTENA = 1; //enable rxrdy/ break detect interrupt
SciaRegs.SCICTL1.bit.TXENA = 0; // Disable transmistter
SciaRegs.SCICTL1.bit.SWRESET = 1; //bring out from reset
SciaRegs.SCICTL1.bit.SLEEP = 1; //set the UART module in sleep mode till the module receives a stream of data is addressing it
}calculate_crc()函数
uint16_t calculate_crc(volatile uint16_t *packet, uint16_t packLen)
{
uint16_t index = 0;
uint16_t crc = 0;
for (int h = 0; h < packLen - 2; h++)
{
index = ((crc >> 8) ^ ((int16_t) packet[h])) & 0xFF;
crc = (crc << 8) ^ crc_table[index];
}
return crc;
}