这个问题 你看看 LPC2214的勘误表就晓得了 这个问题确实比较麻烦的
我也是弄了很久 才完全搞定 主要是他的标志一定要处理完 还有收发处理的先后顺序
下面的代码可以稳定工作 就是啰嗦了点 自己看着精简下吧
//__irq void Comm1IntISR (void)
void Comm1_Exception (void)
{
#if OS_CRITICAL_METHOD == 3
// OS_CPU_SR cpu_sr;
#endif
INT8U IIRValue;
INT8U LSRValue;
INT8U Dummy;
// COMM_ENTER_CRITICAL();
while (((IIRValue = U1IIR) & 0x01) == 0) { // 处理完全部中断
// IIRValue = U1IIR; // 读中断状态 能进入到这里 一般表示是有中断发生的 检查状态
IIRValue >>= 1; // 所以不用在对U0IIR 0bit检查
IIRValue &= 0x07; // check bit 1~3, interrupt identification
switch (IIRValue) { // 根据中断信息来处理
case IIR_RLS : // -- 中断标志 接收线状态 暂时未处理
while (1) {
LSRValue = U1LSR; // 读线状态标志
if (LSRValue == 0x60) { // 未有未处理的状态
break; //
}
if (GETBIT(LSRValue, LSR_RDR)) { // U1RBR种有数据
CLRBIT(LSRValue, LSR_RDR); // 清除标志
Dummy = U1RBR; // 读数据
if (Comm1RxBufCtr < COMM1_RXD_SIZE) { // 检查缓冲大小
Comm1RxBufCtr++; // 接收缓存计数器加1
Comm1RxBuf[Comm1RxInIx++] = Dummy; // 接收到的数据进缓存
if (Comm1RxInIx >= COMM1_RXD_SIZE) { // 处理索引
Comm1RxInIx = 0; // 进入索引复位
}
}
}
if (GETBIT(LSRValue, LSR_OE)) { // 溢出错误
CLRBIT(LSRValue, LSR_OE); //
Dummy = U1RBR; // 读数据
if (Comm1RxBufCtr < COMM1_RXD_SIZE) { // 检查缓冲大小
Comm1RxBufCtr++; // 接收缓存计数器加1
Comm1RxBuf[Comm1RxInIx++] = Dummy; // 接收到的数据进缓存
if (Comm1RxInIx >= COMM1_RXD_SIZE) { // 处理索引
Comm1RxInIx = 0; // 进入索引复位
}
}
}
if (GETBIT(LSRValue, LSR_PE)) { // 奇偶错误 不处理
CLRBIT(LSRValue, LSR_PE);
}
if (GETBIT(LSRValue, LSR_FE)) { // 帧错误 不处理
CLRBIT(LSRValue, LSR_FE); //
}
if (GETBIT(LSRValue, LSR_BI)) { // 间隔中断
CLRBIT(LSRValue, LSR_BI);
}
if (GETBIT(LSRValue, LSR_THRE)) { // 发送保持寄存器空
CLRBIT(LSRValue, LSR_THRE);
if (Comm1TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
Comm1TxBufCtr--; // 缓存计数器减1
U1THR = Comm1TxBuf[Comm1TxOutIx++]; // 读走一个数据到发送寄存器
if (Comm1TxOutIx >= COMM1_TXD_SIZE) { // 判断
Comm1TxOutIx = 0; // 复位
}
} else {
Comm1bCanSend = 0; // 发送标志为0表示 可以直接发送信息
}
}
if (GETBIT(LSRValue, LSR_TEMT)) { // 发送器空
CLRBIT(LSRValue, LSR_TEMT);
if (Comm1TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
Comm1TxBufCtr--; // 缓存计数器减1
U1THR = Comm1TxBuf[Comm1TxOutIx++]; // 读走一个数据到发送寄存器
if (Comm1TxOutIx >= COMM1_TXD_SIZE) { // 判断
Comm1TxOutIx = 0; // 复位
}
} else {
Comm1bCanSend = 0; // 发送标志为0表示 可以直接发送信息
}
}
if (GETBIT(LSRValue, LSR_RXFE)) { // RX 错误
CLRBIT(LSRValue, LSR_RXFE);
}
}
break;
case IIR_CTI: // -- 中断标志 超时
// U1IER = U1IER & (~0x01); // 禁止接收及字符超时中断 暂时未处理
case IIR_RDA: // -- 中断标志 接收数据
Uart1IntRxCtr++;
Dummy = U1RBR; // 读数据
if (Comm1RxBufCtr < COMM1_RXD_SIZE) { // 检查缓冲大小
Comm1RxBufCtr++; // 接收缓存计数器加1
Comm1RxBuf[Comm1RxInIx++] = Dummy; // 接收到的数据进缓存
if (Comm1RxInIx >= COMM1_RXD_SIZE) { // 处理索引
Comm1RxInIx = 0; // 进入索引复位
}
}
break;
case IIR_THRE: // -- 中断标志 发送数据
Uart1IntTxCtr++;
if (Comm1TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
Comm1TxBufCtr--; // 缓存计数器减1
U1THR = Comm1TxBuf[Comm1TxOutIx++]; // 读走一个数据到发送寄存器
if (Comm1TxOutIx >= COMM1_TXD_SIZE) { // 判断
Comm1TxOutIx = 0; // 复位
}
} else {
Comm1bCanSend = 0; // 发送标志为0表示 可以直接发送信息
}
break;
default : // 未定义
break;
}
}
// COMM_EXIT_CRITICAL();
VICVectAddr = 0; // Acknowledge Interrupt
}
|