以下是针对提供的UART3中断服务函数(ISR)的详细解释及注意事项:
函数声明
c
复制
void Uart3Isr() interrupt 17
interrupt 17:表明这是一个中断服务函数,中断号为17。在8051架构或其兼容芯片(如8H8K 64PIN)中,不同中断源有固定的中断号。此处17号中断通常对应UART3的特定事件(如接收完成或发送完成)。
局部变量
c
复制
char ii = 0, i = 0;
定义了两个字符变量ii和i并初始化为0,但后续代码中未使用它们。可能是冗余代码或未完成的功能,建议删除以提高代码清晰度。
发送中断处理
c
复制
if (S3CON & 0x02) {
S3CON &= ~0x02; // 清除发送中断标志
busy3 = 0; // 标记发送完成
}
S3CON & 0x02:检查UART3控制寄存器的第1位(假设为发送中断标志位,类似8051的TI位)。
S3CON &= ~0x02:通过位操作清除发送中断标志,防止重复进入中断。
busy3 = 0:自定义全局变量,用于指示UART3发送器空闲,可发送下一字节。
接收中断处理
c
复制
if (S3CON & 0x01) {
S3CON &= ~0x01; // 清除接收中断标志
NB_VOT_RS[frt] = S3BUF; // 读取接收缓冲区的数据
frt++; // 递增缓冲区索引
}
S3CON & 0x01:检查UART3控制寄存器的第0位(假设为接收中断标志位,类似8051的RI位)。
S3CON &= ~0x01:清除接收中断标志,允许下次接收触发中断。
NB_VOT_RS[frt] = S3BUF:将UART3接收缓冲区(S3BUF)的数据存入全局数组NB_VOT_RS的frt位置。
frt++:递增索引,指向下一个存储位置。需确保frt不会超出数组长度,否则会导致缓冲区溢出。
关键注意事项
寄存器定义验证:
确认S3CON寄存器位定义与数据手册一致。例如,0x01和0x02是否确实对应接收和发送中断标志位。
中断标志清除顺序:
部分硬件要求在读取数据寄存器(如S3BUF)后清除中断标志。调整代码顺序以避免数据丢失:
c
复制
if (S3CON & 0x01) {
NB_VOT_RS[frt] = S3BUF; // 先读取数据
S3CON &= ~0x01; // 再清除标志
frt++;
}
缓冲区溢出防护:
添加对frt的边界检查,防止数组越界:
c
复制
if (frt < MAX_BUFFER_SIZE) {
NB_VOT_RS[frt] = S3BUF;
frt++;
} else {
// 处理缓冲区满的情况(如复位frt或报错)
}
全局变量保护:
如果frt和busy3在中断外被修改,需使用volatile关键字声明,防止编译器优化导致意外行为:
c
复制
volatile char busy3 = 0;
volatile int frt = 0;
中断效率:
保持ISR简短,避免复杂操作。如需处理大量数据,可设置标志位在主循环中处理。
示例优化代码
c
复制
volatile char busy3 = 0;
volatile unsigned int frt = 0;
#define MAX_BUFFER 128
volatile char NB_VOT_RS[MAX_BUFFER];
void Uart3Isr() interrupt 17 {
if (S3CON & 0x02) { // 发送中断处理
S3CON &= ~0x02; // 清除发送中断标志
busy3 = 0; // 允许发送新数据
}
if (S3CON & 0x01) { // 接收中断处理
char data = S3BUF; // 先读取数据
S3CON &= ~0x01; // 后清除标志
if (frt < MAX_BUFFER) {
NB_VOT_RS[frt++] = data;
} else {
// 缓冲区溢出处理
}
}
}
总结
此ISR负责处理UART3的发送和接收中断:发送完成后释放busy3,接收时存储数据到缓冲区。需确保寄存器操作正确、缓冲区安全,并保持中断高效。