下面是 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; } }