当前位置: 首页 > news >正文

PC16550串口中断接收与异常处理程序

1.标准中断服务程序的处理流程(最佳实践)

void UART_ISR(void) {// 1. 读取IIR来判断中断源(注意:读IIR不会清除任何中断)unsigned char iir = inportb(UART_BASE + IIR_OFFSET);// 2. 循环处理,直到所有pending的中断都被处理完毕(IIR.0 = 1)while ((iir & 0x01) == 0) { // IIR.0 = 0 表示有中断待处理switch (iir & 0x0E) { // 屏蔽低位的0,检查中断ID位case 0x06: // 110: 最高优先级 - 线路状态错误handle_line_status_error();break;case 0x04: // 100: 接收数据可用handle_receive_data();break;case 0x0C: // 1100: 注意,IIR是3位,但超时中断用了高位// 实际上,在16550中,超时中断的IIR值通常也是 0x0C (1100)handle_receive_timeout();break;case 0x02: // 010: 发送保持寄存器空handle_transmit_empty();break;case 0x00: // 000: 最低优先级 - MODEM状态改变handle_modem_status_change();break;default:// 未知中断类型,可能是硬件问题break;}// 再次读取IIR,检查是否还有其他pending的中断iir = inportb(UART_BASE + IIR_OFFSET);}
}

2.线路状态错误中断处理

/*** 处理UART线路状态错误中断* 这是最高优先级的中断,必须首先处理*/
void handle_line_status_error(void) {// 读取线路状态寄存器(LSR) - 这个操作会清除线路状态中断标志unsigned char lsr = inportb(UART_BASE + LSR_OFFSET);// 检查各种错误标志位if (lsr & LSR_OE) {  // 位1: 溢错误handle_overrun_error();}if (lsr & LSR_PE) {  // 位2: 奇偶校验错误handle_parity_error();}if (lsr & LSR_FE) {  // 位3: 帧错误handle_framing_error();}if (lsr & LSR_BI) {  // 位4: 中止中断handle_break_interrupt();}// 注意:位0 (DR) 是数据就绪标志,不是错误,不需要在这里处理// 位5 (THRE) 和 位6 (TEMT) 是发送状态,也不是错误
}

3.具体错误处理函数实现

/*** 处理溢错误* 原因:CPU没有及时读取接收缓冲器,新数据覆盖了旧数据*/
void handle_overrun_error(void) {// 记录错误日志uart_log_error("UART: Overrun Error - Data lost due to slow reading");// 溢错误发生时,最新的数据可能已经丢失// 建议清空接收FIFO,重新开始outportb(UART_BASE + FCR_OFFSET, 0x07); // 设置FCR: 启用FIFO,清空RX FIFO,清空TX FIFO// 在严重情况下,可能需要重新初始化UARTif (++overrun_error_count > MAX_OVERRUN_ERRORS) {uart_log_error("UART: Too many overrun errors, reinitializing");initialize_uart();overrun_error_count = 0;}
}/*** 处理奇偶校验错误* 原因:数据传输过程中受到干扰,奇偶校验不匹配*/
void handle_parity_error(void) {// 记录错误日志uart_log_error("UART: Parity Error - Data corruption detected");// 对于奇偶校验错误,通常只是记录,不采取激进措施// 因为可能是暂时的线路干扰// 如果使用流量控制,可以临时暂停数据传输if (uart_flow_control_enabled) {// 发送XOFF字符,请求对方暂停发送outportb(UART_BASE + THR_OFFSET, XOFF_CHAR);}parity_error_count++;
}/*** 处理帧错误* 原因:缺少有效的停止位,通常表示波特率不匹配或线路断开*/
void handle_framing_error(void) {// 记录错误日志uart_log_error("UART: Framing Error - Invalid stop bit or baud rate mismatch");// 帧错误通常比较严重,可能表示配置问题// 尝试从接收缓冲器读取一个字节(尽管有错误)// 这样可以清除错误状态,但数据不可靠unsigned char bad_data = inportb(UART_BASE + RBR_OFFSET);// 记录错误数据(用于调试)uart_log_debug("UART: Framing error byte: 0x%02X", bad_data);framing_error_count++;// 如果帧错误持续发生,可能需要检查波特率设置if (framing_error_count > MAX_FRAMING_ERRORS) {uart_log_error("UART: Excessive framing errors, check baud rate configuration");// 可以在这里触发重新配置流程}
}
/*** 处理中止中断* 原因:接收线路上检测到长时间的逻辑0(Break信号)*/
void handle_break_interrupt(void) {// 记录事件uart_log_info("UART: Break Signal detected");// Break信号通常用于通信协议的重置或特殊命令// 清空接收FIFO,因为Break期间接收的数据无效outportb(UART_BASE + FCR_OFFSET, 0x06); // 清空RX FIFO,不清TX FIFO// 通知上层应用Break信号发生if (uart_break_callback != NULL) {uart_break_callback();}break_detected_count++;
}

http://www.dtcms.com/a/419042.html

相关文章:

  • 自动化脚本提升效率
  • mysql旧版本存储嵌入模型的向量数据
  • 公司网站建设宣传话语申请一个域名可以建设一个网站吗
  • 合川做网站临汾网站建设
  • HGAME 2023 week1]a_cup_of_tea
  • vue 打包element plus组件生成对应css文件的问题
  • 网站 接入微信公众号登陆入口
  • 做网站和做appwordpress category模板
  • Windows---进程状态信息获取的核心接口<Psapi.h>
  • flink状态管理
  • 有成功案例的网站汉口北做网站
  • k8s的kube-prosy
  • 手机网站费用电商都有哪些平台
  • 自动驾驶中的传感器技术56——USS(2)
  • 快速上手 iFlow CLI:你的终端 AI 助手
  • AI编程工具:ChatGPT + Copilot使用体验
  • vue3+ts 封装跟随弹框组件,支持多种模式【多选,分组,tab等】
  • 网站开发注意事项wordpress 专业版主题
  • 2025甄选范文“论事件驱动的架构”,软考高级,系统架构设计师论文
  • 高通平台WiFi学习--深入解析 WCN39xx/PMIC GPIO/LDO 状态读取与调试
  • 评估止损算法在历史极端行情中表现的一些复盘
  • 英飞凌Coolgan提升Poe性能
  • 网站解析多久网站开发是做什么?
  • 有哪些好的做兼职网站有哪些做网站域名需哪些
  • FFmpeg过滤器实战:水印处理
  • 网站推广好难免费建网站代理
  • 东莞网站建设主要学什么北京有哪些著名网站
  • 英文版科技网站网站推广套餐
  • 网站建设与开发课程内容wordpress 启动wordpress mu
  • 10.4 线性规划