1. 项目概述深入理解8251A的“三字真言”搞嵌入式或者玩过老式单板机的朋友对Intel 8251A这款通用同步/异步收发器USART芯片一定不陌生。它曾是连接CPU与串行世界比如电传打字机、调制解调器的经典桥梁。但很多初学者甚至一些有经验的工程师在面对8251A的编程时总会对模式字、控制字和状态字这三个核心概念感到困惑它们到底有什么区别写入和读出的时机怎么把握配置错了为什么数据死活发不出去今天我们就抛开枯燥的数据手册从一个实际调试者的角度把这“三字真言”掰开揉碎了讲清楚。你可以把这篇文章看作是一份“避坑指南”和“实战手册”。我将结合具体的代码片段和示波器抓到的波形带你理解模式字是如何为通信奠定基础的“宪法”控制字是如何实时指挥芯片行动的“命令”而状态字又是如何反馈战场实况的“侦察报告”。无论你是正在学习微机原理的学生还是需要维护老旧系统的工程师理解这三者的关系都能让你在调试串口时从“盲人摸象”变成“心中有图”。2. 核心概念拆解模式字、控制字、状态字到底是谁在深入细节之前我们必须建立一个清晰的顶层认知。8251A内部有几个关键的寄存器CPU通过向特定端口写入或读取来与它们交互。而“模式字”、“控制字”、“状态字”就是这些寄存器内容的代称它们各自承担着截然不同的使命。2.1 模式字通信协议的“奠基者”想象一下你要和一个人建立通信首先得约定好我们是打电话同步还是写信异步写信的话信封格式数据位、停止位什么样打电话的话时钟节奏同步字符怎么跟模式字就是用来回答这些基础问题的。作用时机在8251A上电复位或通过命令字软复位后第一个必须写入的操作。这相当于给芯片“开机初始化”告诉它你打算用哪种模式工作。核心功能设定通信的基本框架。同步/异步模式选择这是最根本的选择。同步模式用于高速、有时钟线伴随的数据传输异步模式则是常见的“起止式”串口如RS-232。数据格式定义异步模式下设定数据位长度5、6、7、8位、停止位长度1, 1.5, 2位、校验位类型奇校验、偶校验、无校验以及波特率因子时钟频率与波特率的倍数关系如x1, x16, x64。同步模式下设定同步字符个数单同步或双同步、是否进行同步字符的奇偶校验等。关键特性一次性设定长期有效。除非芯片复位否则模式字在通信过程中不会改变。它定义了“游戏规则”但不直接触发任何动作。注意这是一个极易出错的地方如果在未复位的情况下错误地向模式寄存器端口写入了一个控制字芯片会将其误认为是模式字从而导致整个通信协议错乱后续所有操作都将失败。确保操作顺序是调试的第一步。2.2 控制字芯片行为的“指挥官”规则定好了接下来就要发号施令了。控制字就是CPU向8251A下达的实时命令它控制芯片的具体动作和状态切换。作用时机在模式字写入之后在通信过程之中可以随时写入。每次写入都相当于下达一条新指令。核心功能控制芯片的实时操作。收发使能TxEN发送允许和RxE接收允许。想发送数据必须置位TxEN想接收数据必须置位RxE。这是最常用的控制位。错误复位ER错误标志复位。当状态字显示有帧错误、溢出错、奇偶错时写入此位可以清除这些错误标志以便继续通信。发送中止字符SBRK发送中止字符。强制将TxD线拉低逻辑0一段时间用于向对方发送一个“中断”信号。内部复位IR内部复位。此位置1会使8251A回到初始状态相当于软复位之后必须重新写入模式字。这是纠错的重要手段。请求发送RTS请求发送。控制RTS输出引脚的电平用于硬件流控。搜索同步字符EH进入搜索模式。仅用于同步模式命令接收器开始搜索同步字符。关键特性动态可写即时生效。它是CPU主动控制8251A的手段。一个控制字可以同时包含多个命令位例如同时使能发送和接收。2.3 状态字通信状况的“晴雨表”指挥官下了命令前线的战况如何状态字就是8251A向CPU汇报的内部状态寄存器。作用时机在通信过程之中CPU可以随时读取以查询芯片当前状态。核心功能反映芯片的实时状态和错误信息。收发就绪TxRDY发送器就绪为1表示发送缓冲器空CPU可以写入新数据。注意TxRDY引脚的状态还受TxEN控制位和CTS引脚的影响。RxRDY接收器就绪为1表示接收缓冲器已有一个完整字符CPU可以读取。错误指示PE奇偶错误接收字符的奇偶校验与设定不符。OE溢出错CPU还未读取上一个字符新字符又已接收完毕造成数据丢失。FE帧错误异步模式下未在预期位置检测到有效的停止位。其他状态SYNDET/BD同步检测/中止检测同步模式下指示同步字符已找到异步模式下指示检测到中止字符BREAK。DSR数据设备就绪直接反映DSR输入引脚的状态。关键特性只读反映实时状况。它是CPU进行查询式I/O编程的基础。程序通过循环读取状态字判断TxRDY或RxRDY来决定何时写入数据或读取数据。三者的关系总结顺序复位 -写模式字(定规则) -写控制字(发命令如使能收发) -读写数据(期间循环读状态字查状态必要时写控制字改命令)。类比模式字宪法控制字行政命令状态字政府工作报告。端口模式字和控制字写入同一个端口命令端口依靠操作顺序区分状态字从另一个独立的端口读取。3. 模式字详解从位定义到配置实战理解了宏观概念我们深入到二进制位层面。模式字是一个8位寄存器其每一位的组合决定了8251A的“世界观”。3.1 异步模式下的位解析当模式字的最高两位D7 D6 00, 01, 10时芯片工作于异步模式。此时模式字的格式如下D7 D6 | D5 D4 | D3 D2 | D1 D0 波特率因子 | 字符长度 | 校验控制 | 停止位长度D1 D0 - 停止位长度00: 无效01: 1位停止位10: 1.5位停止位常用于5位数据字时11: 2位停止位D3 D2 - 校验控制x0: 无校验x表示0或1均可通常取001: 奇校验11: 偶校验D5 D4 - 字符长度00: 5位01: 6位10: 7位11: 8位D7 D6 - 波特率因子00: 同步模式此编码在异步模式下不用01: 波特率因子 1 (时钟频率 波特率)10: 波特率因子 16 (时钟频率 16 x 波特率)11: 波特率因子 64 (时钟频率 64 x 波特率)配置示例我们需要一个最常见的串口配置8位数据无校验1位停止位波特率因子16。 那么D7D610(因子16)D5D411(8位数据)D3D200(无校验)D1D001(1位停止位)。 拼起来10 11 00 010xB1。 所以向命令端口写入0xB1即完成了异步模式的初始化。实操心得波特率因子直接影响对输入时钟CLK和TxC/RxC的要求。例如目标波特率是9600因子选16则TxC引脚输入的时钟频率必须是9600 * 16 153.6 kHz。这个时钟通常由波特率发生器如8253/8254定时器提供。如果时钟不对通信必然失败。3.2 同步模式下的位解析当模式字的最高两位D7 D6 00时芯片工作于同步模式。此时格式有所不同D7 D6 | D5 D4 | D3 D2 | D1 D0 00 | 同步方式 | 校验控制 | 字符长度D1 D0 - 字符长度定义同异步模式005位...118位。D3 D2 - 校验控制定义同异步模式x0无01奇11偶。D5 D4 - 同步方式00: 内同步双同步字符01: 内同步单同步字符10: 外同步双同步字符11: 外同步单同步字符D7 D6固定为00表示同步模式。同步字符的写入在同步模式下写完模式字后需要紧接着向数据端口注意不是命令端口写入一个或两个同步字符如0x16SYN字符。芯片会将这些字符存储在同步字符寄存器中用于帧同步。配置示例配置为内同步、单同步字符、偶校验、7位数据。 那么D7D600(同步)D5D401(内同步单字符)D3D211(偶校验)D1D010(7位数据)。 拼起来00 01 11 100x1E。 写入0x1E后再向数据端口写入同步字符例如0x16。4. 控制字详解精细操控的每一个比特控制字是CPU的指挥棒它的8个位各自独立又相互配合。控制字格式如下D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 EH | IR | RTS | ER | SBRK| RxE | DTR | TxEN我们来详细解读每个位的威力D0 - TxEN (Transmit Enable)发送使能。这是发送数据的“总开关”。TxEN1发送器才可能工作。即使发送缓冲器空如果TxEN0TxRDY状态位也不会置1引脚TxRDY也不会有效。常见坑点程序写了数据但发不出去第一个要查的就是TxEN是否已置1。D1 - DTR (Data Terminal Ready)数据终端就绪。此位置1会使DTR输出引脚变为低电平有效通知调制解调器等设备终端已准备好。这是一个硬件握手信号。D2 - RxE (Receive Enable)接收使能。这是接收数据的“总开关”。RxE1接收器才开始监听线路。如果RxE0接收器被禁用不会接收任何数据RxRDY状态也不会置位。D3 - SBRK (Send Break Character)发送中止字符。此位置1强制TxD输出线变为低电平间隔状态直到此位被软件清零。用于发送一个长于完整字符时间的低电平信号通常表示通信中断。D4 - ER (Error Reset)错误标志复位。此位置1将清除状态寄存器中的三个错误标志位PE,OE,FE。这是一个“瞬态”命令通常的编程模式是读取状态字发现错误 - 处理错误如重发- 写入控制字ER1清除错误标志 - 继续通信。写入后该位无需保持为1。D5 - RTS (Request To Send)请求发送。此位置1会使RTS输出引脚变为低电平有效向调制解调器请求发送数据。这也是硬件流控的一部分。D6 - IR (Internal Reset)内部复位。这是最重要的纠错命令。此位置1会使8251A回到上电后的初始状态。这意味着之前写入的模式字和控制字全部失效执行此操作后必须重新进行初始化流程先写模式字再写控制字。当通信出现无法解释的混乱时“软复位”往往是最后一招。D7 - EH (Enter Hunt Mode)进入搜索模式。仅用于同步模式。此位置1命令接收部分开始搜索同步字符。在成功同步后芯片会自动清除此状态。组合命令示例假设我们要启动通信使能发送和接收同时让DTR和RTS信号有效。 那么需要置位的位有TxEN(D01),DTR(D11),RxE(D21),RTS(D51)。 其他位为0。所以控制字为0010 01110x27。 向命令端口写入0x27芯片即开始工作。5. 状态字详解如何正确解读芯片的“心跳”状态字是调试的眼睛。盲目地读写数据而不看状态就像开车不看仪表盘。状态字格式如下D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 DSR | SYNDET/BD | FE | OE | PE | TxE | RxRDY | TxRDYD0 - TxRDY (Transmitter Ready)发送器就绪。这是查询式发送的关键标志。当发送缓冲器为空且TxEN1且CTS引脚为低有效时此位置1。重要区别状态位TxRDY和引脚TxRDY信号逻辑略有不同引脚TxRDY还要求CTS有效。编程时我们通常查询状态位。D1 - RxRDY (Receiver Ready)接收器就绪。这是查询式接收的关键标志。当接收缓冲器中已有一个组装好的完整字符时此位置1。CPU读取数据后此位自动清零。D2 - TxE (Transmitter Empty)发送器空。当发送移位寄存器已将数据全部移出且发送缓冲器也为空时此位置1。它比TxRDY更能指示“发送完全结束”。在发送一串数据的末尾可以查询此位确认所有数据已离开芯片。D3 - PE (Parity Error)奇偶校验错。当接收到的字符奇偶校验位与设定不符时置1。此位由控制字的ER位清零。D4 - OE (Overrun Error)溢出错。CPU未及时读取接收缓冲器中的数据而新字符又已接收完毕并准备送入缓冲器时旧数据被覆盖此位置1。这是数据丢失的直接标志。同样由ER位清零。D5 - FE (Framing Error)帧错误。异步模式下在预期的停止位位置检测到低电平空号时置1。通常意味着波特率不匹配或线路干扰。由ER位清零。D6 - SYNDET/BD (Sync Detect/Break Detect)同步模式作为输入时由外部电路提供同步检测信号作为输出时当芯片内部检测到同步字符时此位置1/输出高电平。异步模式当RxD线保持低电平超过一个完整字符传输时间起始位数据位校验位停止位时此位置1表示检测到“中止”BREAK信号。此位在读状态字或复位后清零。D7 - DSR (Data Set Ready)数据设备就绪。此位直接反映DSR输入引脚的电平状态取反后。低电平表示调制解调器等数据设备已就绪。查询法编程示例 发送一个字符‘A’(0x41) 的典型代码逻辑假设命令端口地址为0x3F9数据端口为0x3F8; 等待发送就绪 Wait_Tx: in al, 0x3F9 ; 读状态字 and al, 0x01 ; 检查TxRDY位 (D0) jz Wait_Tx ; 未就绪继续等待 ; 发送数据 mov al, ‘A‘ out 0x3F8, al ; 向数据端口写入字符接收一个字符的典型逻辑; 等待接收就绪 Wait_Rx: in al, 0x3F9 ; 读状态字 and al, 0x02 ; 检查RxRDY位 (D1) jz Wait_Rx ; 未就绪继续等待 ; 检查错误 test al, 0x38 ; 检查PE(D3)、OE(D4)、FE(D5)位 jnz Handle_Error ; 有错误跳转到错误处理 ; 读取数据 in al, 0x3F8 ; 从数据端口读取字符6. 实战编程流程与避坑指南理论最终要服务于实践。下面我们以一个完整的异步模式通信初始化及收发流程串联起“三字真言”并指出每个环节的坑点。6.1 标准初始化与收发序列步骤1硬件复位或软件复位硬件复位通过8251A的RESET引脚施加一个足够宽的高电平脉冲。软件复位向命令端口写入控制字0x40(IR1即0100 0000)。这是最常用的方式。关键点复位后芯片等待第一个写入命令端口的字被解释为模式字。步骤2写入模式字根据通信需求计算模式字值。例如0xB1(异步x168N1)。向命令端口写入该值。避坑点1确保这是复位后的第一次写命令端口操作。如果之前误写过最好先执行一次软件复位。步骤3写入控制字根据需求计算控制字值。例如0x27(使能收发DTR和RTS有效)。向命令端口写入该值。避坑点2此时芯片已就绪。如果使用硬件流控CTS/RTS请确保对方设备使能了相应信号否则TxRDY可能永远不为真。步骤4数据收发查询法循环发送循环读状态字检查TxRDY(D0)。为1则写数据端口。接收循环读状态字检查RxRDY(D1)。为1则先检查PE/OE/FE错误位若无错误则读数据端口。避坑点3读取数据后RxRDY位会自动清零。但错误标志位PE/OE/FE不会自动清零必须通过写控制字ER1来清除否则它们会一直保持影响后续的状态判断。步骤5错误处理与恢复一旦检测到状态字中的错误位应进入错误处理例程。对于OE溢出错说明程序处理速度跟不上接收速度可能需要提高查询频率或改用中断方式。对于FE帧错误或PE奇偶错可能是线路干扰或波特率微小的不匹配可以考虑重发或记录错误。处理完错误后务必写入控制字0x10(ER1即0001 0000) 来清除错误标志。避坑点4如果通信完全挂起状态字读取异常最后的“大招”是执行一次软件复位IR1然后从步骤2重新开始初始化。这能解决大部分因意外干扰导致的芯片内部状态机错乱问题。6.2 中断方式下的注意事项8251A的TxRDY和RxRDY引脚可以作为中断请求信号连接到CPU的中断控制器如8259A。这比查询法效率高得多。发送中断当TxRDY有效且中断被使能时会触发中断。中断服务程序ISR中写入数据后TxRDY会变低直到发送缓冲器再次为空。注意如果发送完一串数据后没有新数据可发应在关闭发送中断前确保最后一个字符已移出可查询TxE位。接收中断当RxRDY有效时触发中断。ISR中必须先读取状态字判断错误再读取数据。因为读取数据端口后RxRDY会清零。关键配置中断方式下控制字的TxEN和RxE位同样必须置1。此外需要确保中断控制器和CPU的中断系统已正确配置。7. 典型问题排查实录在实际调试中问题往往不是单一的。下面是一个常见问题排查表你可以像查字典一样使用它现象可能原因排查步骤与解决方法数据根本发不出去1. 初始化序列错误2.TxEN未使能3.CTS硬件流控未满足1. 确认严格遵循复位 - 写模式字 - 写控制字含TxEN1的序列。2. 检查控制字值确认D0位(TxEN)为1。3. 用示波器或逻辑分析仪检查CTS引脚电平如果使用流控确保其为低电平。或者暂时在初始化时不使用流控控制字中RTS位置1但忽略CTS状态。能发送但接收不到数据1.RxE未使能2. 波特率/数据格式不匹配3. 线路连接错误1. 检查控制字值确认D2位(RxE)为1。2.双机互发测试用同一配置的程序和硬件自发自收。如果成功则问题在对方配置。确保双方波特率、数据位、停止位、校验位完全一致。3. 检查RxD和TxD线是否交叉连接一方的TxD接另一方的RxD。接收数据乱码1. 波特率轻微不匹配时钟精度2. 地线未共地3. 干扰严重1. 计算双方时钟源产生的实际波特率误差通常要求误差小于2.5%。使用更高精度的晶振或时钟源。2. 确保发送端和接收端有可靠的共地连接。3. 检查线路避免长线并行使用屏蔽线。偶尔丢失数据1. 溢出错(OE)导致2. 程序查询/处理速度慢1. 在接收程序中每次读数据前检查状态字OE位。如果置位说明上一个数据未被及时读取就被覆盖了。2. 优化代码提高查询频率。或者改用中断方式接收数据确保数据到来时能被即时响应。发送一段时间后死机1. 状态机紊乱2. 错误标志未清除1. 最可靠的解决方法是在发送函数中加入超时判断。如果等待TxRDY超时例如循环查询超过一定次数则执行一次软件复位写控制字0x40然后重新初始化芯片。2. 确保在检测到任何错误(PE/OE/FE)后都执行了错误标志清除操作写控制字0x10。同步模式无法锁定1. 同步字符未写入或错误2.EH位未正确设置1. 确认在写同步模式字后立即向数据端口写入了一个或两个正确的同步字符。2. 在初始化控制字时对于内同步模式可能需要将EH位置1以启动搜索。查阅具体型号的数据手册确认。理解8251A的模式字、控制字和状态字本质上是在理解一个状态机如何被配置、驱动和监控。它虽然是一个老旧的芯片但其体现的“初始化-命令-查询”的编程模型在今天的许多外设控制器中依然能看到影子。掌握了这套方法你再面对任何需要精细控制的硬件接口时都会有一种“庖丁解牛”般的自信。调试时别忘了一边看代码一边用示波器看看TxD线上的波形那才是最真实的语言。当你看到按照自己配置产生的、规整的串行波形时那种成就感就是硬件编程最原始的乐趣所在。
深入解析8251A USART:模式字、控制字与状态字的实战指南
1. 项目概述深入理解8251A的“三字真言”搞嵌入式或者玩过老式单板机的朋友对Intel 8251A这款通用同步/异步收发器USART芯片一定不陌生。它曾是连接CPU与串行世界比如电传打字机、调制解调器的经典桥梁。但很多初学者甚至一些有经验的工程师在面对8251A的编程时总会对模式字、控制字和状态字这三个核心概念感到困惑它们到底有什么区别写入和读出的时机怎么把握配置错了为什么数据死活发不出去今天我们就抛开枯燥的数据手册从一个实际调试者的角度把这“三字真言”掰开揉碎了讲清楚。你可以把这篇文章看作是一份“避坑指南”和“实战手册”。我将结合具体的代码片段和示波器抓到的波形带你理解模式字是如何为通信奠定基础的“宪法”控制字是如何实时指挥芯片行动的“命令”而状态字又是如何反馈战场实况的“侦察报告”。无论你是正在学习微机原理的学生还是需要维护老旧系统的工程师理解这三者的关系都能让你在调试串口时从“盲人摸象”变成“心中有图”。2. 核心概念拆解模式字、控制字、状态字到底是谁在深入细节之前我们必须建立一个清晰的顶层认知。8251A内部有几个关键的寄存器CPU通过向特定端口写入或读取来与它们交互。而“模式字”、“控制字”、“状态字”就是这些寄存器内容的代称它们各自承担着截然不同的使命。2.1 模式字通信协议的“奠基者”想象一下你要和一个人建立通信首先得约定好我们是打电话同步还是写信异步写信的话信封格式数据位、停止位什么样打电话的话时钟节奏同步字符怎么跟模式字就是用来回答这些基础问题的。作用时机在8251A上电复位或通过命令字软复位后第一个必须写入的操作。这相当于给芯片“开机初始化”告诉它你打算用哪种模式工作。核心功能设定通信的基本框架。同步/异步模式选择这是最根本的选择。同步模式用于高速、有时钟线伴随的数据传输异步模式则是常见的“起止式”串口如RS-232。数据格式定义异步模式下设定数据位长度5、6、7、8位、停止位长度1, 1.5, 2位、校验位类型奇校验、偶校验、无校验以及波特率因子时钟频率与波特率的倍数关系如x1, x16, x64。同步模式下设定同步字符个数单同步或双同步、是否进行同步字符的奇偶校验等。关键特性一次性设定长期有效。除非芯片复位否则模式字在通信过程中不会改变。它定义了“游戏规则”但不直接触发任何动作。注意这是一个极易出错的地方如果在未复位的情况下错误地向模式寄存器端口写入了一个控制字芯片会将其误认为是模式字从而导致整个通信协议错乱后续所有操作都将失败。确保操作顺序是调试的第一步。2.2 控制字芯片行为的“指挥官”规则定好了接下来就要发号施令了。控制字就是CPU向8251A下达的实时命令它控制芯片的具体动作和状态切换。作用时机在模式字写入之后在通信过程之中可以随时写入。每次写入都相当于下达一条新指令。核心功能控制芯片的实时操作。收发使能TxEN发送允许和RxE接收允许。想发送数据必须置位TxEN想接收数据必须置位RxE。这是最常用的控制位。错误复位ER错误标志复位。当状态字显示有帧错误、溢出错、奇偶错时写入此位可以清除这些错误标志以便继续通信。发送中止字符SBRK发送中止字符。强制将TxD线拉低逻辑0一段时间用于向对方发送一个“中断”信号。内部复位IR内部复位。此位置1会使8251A回到初始状态相当于软复位之后必须重新写入模式字。这是纠错的重要手段。请求发送RTS请求发送。控制RTS输出引脚的电平用于硬件流控。搜索同步字符EH进入搜索模式。仅用于同步模式命令接收器开始搜索同步字符。关键特性动态可写即时生效。它是CPU主动控制8251A的手段。一个控制字可以同时包含多个命令位例如同时使能发送和接收。2.3 状态字通信状况的“晴雨表”指挥官下了命令前线的战况如何状态字就是8251A向CPU汇报的内部状态寄存器。作用时机在通信过程之中CPU可以随时读取以查询芯片当前状态。核心功能反映芯片的实时状态和错误信息。收发就绪TxRDY发送器就绪为1表示发送缓冲器空CPU可以写入新数据。注意TxRDY引脚的状态还受TxEN控制位和CTS引脚的影响。RxRDY接收器就绪为1表示接收缓冲器已有一个完整字符CPU可以读取。错误指示PE奇偶错误接收字符的奇偶校验与设定不符。OE溢出错CPU还未读取上一个字符新字符又已接收完毕造成数据丢失。FE帧错误异步模式下未在预期位置检测到有效的停止位。其他状态SYNDET/BD同步检测/中止检测同步模式下指示同步字符已找到异步模式下指示检测到中止字符BREAK。DSR数据设备就绪直接反映DSR输入引脚的状态。关键特性只读反映实时状况。它是CPU进行查询式I/O编程的基础。程序通过循环读取状态字判断TxRDY或RxRDY来决定何时写入数据或读取数据。三者的关系总结顺序复位 -写模式字(定规则) -写控制字(发命令如使能收发) -读写数据(期间循环读状态字查状态必要时写控制字改命令)。类比模式字宪法控制字行政命令状态字政府工作报告。端口模式字和控制字写入同一个端口命令端口依靠操作顺序区分状态字从另一个独立的端口读取。3. 模式字详解从位定义到配置实战理解了宏观概念我们深入到二进制位层面。模式字是一个8位寄存器其每一位的组合决定了8251A的“世界观”。3.1 异步模式下的位解析当模式字的最高两位D7 D6 00, 01, 10时芯片工作于异步模式。此时模式字的格式如下D7 D6 | D5 D4 | D3 D2 | D1 D0 波特率因子 | 字符长度 | 校验控制 | 停止位长度D1 D0 - 停止位长度00: 无效01: 1位停止位10: 1.5位停止位常用于5位数据字时11: 2位停止位D3 D2 - 校验控制x0: 无校验x表示0或1均可通常取001: 奇校验11: 偶校验D5 D4 - 字符长度00: 5位01: 6位10: 7位11: 8位D7 D6 - 波特率因子00: 同步模式此编码在异步模式下不用01: 波特率因子 1 (时钟频率 波特率)10: 波特率因子 16 (时钟频率 16 x 波特率)11: 波特率因子 64 (时钟频率 64 x 波特率)配置示例我们需要一个最常见的串口配置8位数据无校验1位停止位波特率因子16。 那么D7D610(因子16)D5D411(8位数据)D3D200(无校验)D1D001(1位停止位)。 拼起来10 11 00 010xB1。 所以向命令端口写入0xB1即完成了异步模式的初始化。实操心得波特率因子直接影响对输入时钟CLK和TxC/RxC的要求。例如目标波特率是9600因子选16则TxC引脚输入的时钟频率必须是9600 * 16 153.6 kHz。这个时钟通常由波特率发生器如8253/8254定时器提供。如果时钟不对通信必然失败。3.2 同步模式下的位解析当模式字的最高两位D7 D6 00时芯片工作于同步模式。此时格式有所不同D7 D6 | D5 D4 | D3 D2 | D1 D0 00 | 同步方式 | 校验控制 | 字符长度D1 D0 - 字符长度定义同异步模式005位...118位。D3 D2 - 校验控制定义同异步模式x0无01奇11偶。D5 D4 - 同步方式00: 内同步双同步字符01: 内同步单同步字符10: 外同步双同步字符11: 外同步单同步字符D7 D6固定为00表示同步模式。同步字符的写入在同步模式下写完模式字后需要紧接着向数据端口注意不是命令端口写入一个或两个同步字符如0x16SYN字符。芯片会将这些字符存储在同步字符寄存器中用于帧同步。配置示例配置为内同步、单同步字符、偶校验、7位数据。 那么D7D600(同步)D5D401(内同步单字符)D3D211(偶校验)D1D010(7位数据)。 拼起来00 01 11 100x1E。 写入0x1E后再向数据端口写入同步字符例如0x16。4. 控制字详解精细操控的每一个比特控制字是CPU的指挥棒它的8个位各自独立又相互配合。控制字格式如下D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 EH | IR | RTS | ER | SBRK| RxE | DTR | TxEN我们来详细解读每个位的威力D0 - TxEN (Transmit Enable)发送使能。这是发送数据的“总开关”。TxEN1发送器才可能工作。即使发送缓冲器空如果TxEN0TxRDY状态位也不会置1引脚TxRDY也不会有效。常见坑点程序写了数据但发不出去第一个要查的就是TxEN是否已置1。D1 - DTR (Data Terminal Ready)数据终端就绪。此位置1会使DTR输出引脚变为低电平有效通知调制解调器等设备终端已准备好。这是一个硬件握手信号。D2 - RxE (Receive Enable)接收使能。这是接收数据的“总开关”。RxE1接收器才开始监听线路。如果RxE0接收器被禁用不会接收任何数据RxRDY状态也不会置位。D3 - SBRK (Send Break Character)发送中止字符。此位置1强制TxD输出线变为低电平间隔状态直到此位被软件清零。用于发送一个长于完整字符时间的低电平信号通常表示通信中断。D4 - ER (Error Reset)错误标志复位。此位置1将清除状态寄存器中的三个错误标志位PE,OE,FE。这是一个“瞬态”命令通常的编程模式是读取状态字发现错误 - 处理错误如重发- 写入控制字ER1清除错误标志 - 继续通信。写入后该位无需保持为1。D5 - RTS (Request To Send)请求发送。此位置1会使RTS输出引脚变为低电平有效向调制解调器请求发送数据。这也是硬件流控的一部分。D6 - IR (Internal Reset)内部复位。这是最重要的纠错命令。此位置1会使8251A回到上电后的初始状态。这意味着之前写入的模式字和控制字全部失效执行此操作后必须重新进行初始化流程先写模式字再写控制字。当通信出现无法解释的混乱时“软复位”往往是最后一招。D7 - EH (Enter Hunt Mode)进入搜索模式。仅用于同步模式。此位置1命令接收部分开始搜索同步字符。在成功同步后芯片会自动清除此状态。组合命令示例假设我们要启动通信使能发送和接收同时让DTR和RTS信号有效。 那么需要置位的位有TxEN(D01),DTR(D11),RxE(D21),RTS(D51)。 其他位为0。所以控制字为0010 01110x27。 向命令端口写入0x27芯片即开始工作。5. 状态字详解如何正确解读芯片的“心跳”状态字是调试的眼睛。盲目地读写数据而不看状态就像开车不看仪表盘。状态字格式如下D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 DSR | SYNDET/BD | FE | OE | PE | TxE | RxRDY | TxRDYD0 - TxRDY (Transmitter Ready)发送器就绪。这是查询式发送的关键标志。当发送缓冲器为空且TxEN1且CTS引脚为低有效时此位置1。重要区别状态位TxRDY和引脚TxRDY信号逻辑略有不同引脚TxRDY还要求CTS有效。编程时我们通常查询状态位。D1 - RxRDY (Receiver Ready)接收器就绪。这是查询式接收的关键标志。当接收缓冲器中已有一个组装好的完整字符时此位置1。CPU读取数据后此位自动清零。D2 - TxE (Transmitter Empty)发送器空。当发送移位寄存器已将数据全部移出且发送缓冲器也为空时此位置1。它比TxRDY更能指示“发送完全结束”。在发送一串数据的末尾可以查询此位确认所有数据已离开芯片。D3 - PE (Parity Error)奇偶校验错。当接收到的字符奇偶校验位与设定不符时置1。此位由控制字的ER位清零。D4 - OE (Overrun Error)溢出错。CPU未及时读取接收缓冲器中的数据而新字符又已接收完毕并准备送入缓冲器时旧数据被覆盖此位置1。这是数据丢失的直接标志。同样由ER位清零。D5 - FE (Framing Error)帧错误。异步模式下在预期的停止位位置检测到低电平空号时置1。通常意味着波特率不匹配或线路干扰。由ER位清零。D6 - SYNDET/BD (Sync Detect/Break Detect)同步模式作为输入时由外部电路提供同步检测信号作为输出时当芯片内部检测到同步字符时此位置1/输出高电平。异步模式当RxD线保持低电平超过一个完整字符传输时间起始位数据位校验位停止位时此位置1表示检测到“中止”BREAK信号。此位在读状态字或复位后清零。D7 - DSR (Data Set Ready)数据设备就绪。此位直接反映DSR输入引脚的电平状态取反后。低电平表示调制解调器等数据设备已就绪。查询法编程示例 发送一个字符‘A’(0x41) 的典型代码逻辑假设命令端口地址为0x3F9数据端口为0x3F8; 等待发送就绪 Wait_Tx: in al, 0x3F9 ; 读状态字 and al, 0x01 ; 检查TxRDY位 (D0) jz Wait_Tx ; 未就绪继续等待 ; 发送数据 mov al, ‘A‘ out 0x3F8, al ; 向数据端口写入字符接收一个字符的典型逻辑; 等待接收就绪 Wait_Rx: in al, 0x3F9 ; 读状态字 and al, 0x02 ; 检查RxRDY位 (D1) jz Wait_Rx ; 未就绪继续等待 ; 检查错误 test al, 0x38 ; 检查PE(D3)、OE(D4)、FE(D5)位 jnz Handle_Error ; 有错误跳转到错误处理 ; 读取数据 in al, 0x3F8 ; 从数据端口读取字符6. 实战编程流程与避坑指南理论最终要服务于实践。下面我们以一个完整的异步模式通信初始化及收发流程串联起“三字真言”并指出每个环节的坑点。6.1 标准初始化与收发序列步骤1硬件复位或软件复位硬件复位通过8251A的RESET引脚施加一个足够宽的高电平脉冲。软件复位向命令端口写入控制字0x40(IR1即0100 0000)。这是最常用的方式。关键点复位后芯片等待第一个写入命令端口的字被解释为模式字。步骤2写入模式字根据通信需求计算模式字值。例如0xB1(异步x168N1)。向命令端口写入该值。避坑点1确保这是复位后的第一次写命令端口操作。如果之前误写过最好先执行一次软件复位。步骤3写入控制字根据需求计算控制字值。例如0x27(使能收发DTR和RTS有效)。向命令端口写入该值。避坑点2此时芯片已就绪。如果使用硬件流控CTS/RTS请确保对方设备使能了相应信号否则TxRDY可能永远不为真。步骤4数据收发查询法循环发送循环读状态字检查TxRDY(D0)。为1则写数据端口。接收循环读状态字检查RxRDY(D1)。为1则先检查PE/OE/FE错误位若无错误则读数据端口。避坑点3读取数据后RxRDY位会自动清零。但错误标志位PE/OE/FE不会自动清零必须通过写控制字ER1来清除否则它们会一直保持影响后续的状态判断。步骤5错误处理与恢复一旦检测到状态字中的错误位应进入错误处理例程。对于OE溢出错说明程序处理速度跟不上接收速度可能需要提高查询频率或改用中断方式。对于FE帧错误或PE奇偶错可能是线路干扰或波特率微小的不匹配可以考虑重发或记录错误。处理完错误后务必写入控制字0x10(ER1即0001 0000) 来清除错误标志。避坑点4如果通信完全挂起状态字读取异常最后的“大招”是执行一次软件复位IR1然后从步骤2重新开始初始化。这能解决大部分因意外干扰导致的芯片内部状态机错乱问题。6.2 中断方式下的注意事项8251A的TxRDY和RxRDY引脚可以作为中断请求信号连接到CPU的中断控制器如8259A。这比查询法效率高得多。发送中断当TxRDY有效且中断被使能时会触发中断。中断服务程序ISR中写入数据后TxRDY会变低直到发送缓冲器再次为空。注意如果发送完一串数据后没有新数据可发应在关闭发送中断前确保最后一个字符已移出可查询TxE位。接收中断当RxRDY有效时触发中断。ISR中必须先读取状态字判断错误再读取数据。因为读取数据端口后RxRDY会清零。关键配置中断方式下控制字的TxEN和RxE位同样必须置1。此外需要确保中断控制器和CPU的中断系统已正确配置。7. 典型问题排查实录在实际调试中问题往往不是单一的。下面是一个常见问题排查表你可以像查字典一样使用它现象可能原因排查步骤与解决方法数据根本发不出去1. 初始化序列错误2.TxEN未使能3.CTS硬件流控未满足1. 确认严格遵循复位 - 写模式字 - 写控制字含TxEN1的序列。2. 检查控制字值确认D0位(TxEN)为1。3. 用示波器或逻辑分析仪检查CTS引脚电平如果使用流控确保其为低电平。或者暂时在初始化时不使用流控控制字中RTS位置1但忽略CTS状态。能发送但接收不到数据1.RxE未使能2. 波特率/数据格式不匹配3. 线路连接错误1. 检查控制字值确认D2位(RxE)为1。2.双机互发测试用同一配置的程序和硬件自发自收。如果成功则问题在对方配置。确保双方波特率、数据位、停止位、校验位完全一致。3. 检查RxD和TxD线是否交叉连接一方的TxD接另一方的RxD。接收数据乱码1. 波特率轻微不匹配时钟精度2. 地线未共地3. 干扰严重1. 计算双方时钟源产生的实际波特率误差通常要求误差小于2.5%。使用更高精度的晶振或时钟源。2. 确保发送端和接收端有可靠的共地连接。3. 检查线路避免长线并行使用屏蔽线。偶尔丢失数据1. 溢出错(OE)导致2. 程序查询/处理速度慢1. 在接收程序中每次读数据前检查状态字OE位。如果置位说明上一个数据未被及时读取就被覆盖了。2. 优化代码提高查询频率。或者改用中断方式接收数据确保数据到来时能被即时响应。发送一段时间后死机1. 状态机紊乱2. 错误标志未清除1. 最可靠的解决方法是在发送函数中加入超时判断。如果等待TxRDY超时例如循环查询超过一定次数则执行一次软件复位写控制字0x40然后重新初始化芯片。2. 确保在检测到任何错误(PE/OE/FE)后都执行了错误标志清除操作写控制字0x10。同步模式无法锁定1. 同步字符未写入或错误2.EH位未正确设置1. 确认在写同步模式字后立即向数据端口写入了一个或两个正确的同步字符。2. 在初始化控制字时对于内同步模式可能需要将EH位置1以启动搜索。查阅具体型号的数据手册确认。理解8251A的模式字、控制字和状态字本质上是在理解一个状态机如何被配置、驱动和监控。它虽然是一个老旧的芯片但其体现的“初始化-命令-查询”的编程模型在今天的许多外设控制器中依然能看到影子。掌握了这套方法你再面对任何需要精细控制的硬件接口时都会有一种“庖丁解牛”般的自信。调试时别忘了一边看代码一边用示波器看看TxD线上的波形那才是最真实的语言。当你看到按照自己配置产生的、规整的串行波形时那种成就感就是硬件编程最原始的乐趣所在。