下面是 UART 模式下用于 USCI_A0的 ISR 函数的精简版本(某些宏也部分扩展)。 通过 BACnet MS/MS 协议运行时、我会看到一些溢出错误、但我也会看到大量的中断、其中 IV 值为0并下降到默认情况。 我们的 BACnet 堆栈有时会在接收到的帧丢失几个字节 (生成最终的 CRC 错误)时发生故障、但我无法确认这些故障是否仅 来自溢出错误。
- IV 寄存器值为0时、如何触发中断?
- 是否有可能某些接收到的字节在不设置 USCI_UART_UCRXIFG 标志的情况下生成中断(导致数据丢失)?
- 在启用/禁用 UCA0IE 寄存器中的中断和清除 UCA0IFG 寄存器中的标志时、是否应该避免可能的竞争情况?
void _uartISR(void)
{
uint16_t err;
switch(_even_in_range(HWREG16((0x05C0) + OFS_UCAxIV), USCI_UART_UCTXCPTIFG))
{
case USCI_UART_UCRXIFG:
// Read the error status before unloading the rx buffer.
err = HWREG16((0x05C0) + OFS_UCAxSTATW);
*m_rx.pHead = HWREG16((0x05C0) + OFS_UCAxRXBUF);
if(err & (UCFE | UCOE | UCPE))
{
if(err & UCFE)
g_nRxErrors.framing++;
else if(err & UCOE)
g_nRxErrors.overrun++;
else if(err & UCPE)
g_nRxErrors.parity++;
else
g_nRxErrors.undefined++;
}
break;
case USCI_UART_UCTXCPTIFG:
if(!(HWREG16((0x05C0) + OFS_UCAxSTATW) & UCBUSY))
{
// Disable UART tx complete interrupt.
do {HWREG16((0x05C0) + OFS_UCAxIE) &= ~((0x0008)); _nop();} while(0);
do {HWREG16((0x05C0) + OFS_UCAxIFG) &= ~((0x0008)); _nop();} while(0);
// Enable rx interrupt.
do {HWREG16((0x05C0) + OFS_UCAxIFG) &= ~((0x0002)); _nop();} while(0);
do {HWREG16((0x05C0) + OFS_UCAxIE) |= ((0x0001));} while(0);
}
break;
default:
g_nRxErrors.ivZero++;
break;
}
}
