RA8D2 SCI时钟同步通信:从原理到实战的嵌入式驱动开发指南
1. 时钟同步通信从基础概念到RA8D2的工程实现在嵌入式系统开发中设备间的可靠数据通信是构建复杂应用的基石。无论是读取传感器数据、控制外设还是实现多处理器间的协同都离不开一个稳定、高效的通信机制。在众多通信方式中时钟同步模式因其简单、高速和可靠的特性成为许多场景下的首选方案。它不像异步通信那样依赖起始位和停止位来界定数据帧而是通过一根独立的时钟线由主设备发出节拍从设备严格跟随这个节拍来发送或接收每一位数据从而实现精确的同步。这种通信方式正是SPI、Microwire等常见总线协议的核心。对于使用瑞萨RA8D2这类高性能微控制器的工程师来说其内置的SCISerial Communications Interface模块提供了强大的时钟同步通信支持。但仅仅知道如何配置寄存器是远远不够的。在实际项目中时钟极性与相位CPOL/CPHA理解偏差导致的数据错位、硬件流控制CTS/RTS配置不当引发的通信死锁、或者中断与DMA使用时机错误造成的缓冲区溢出都是新手乃至有经验的工程师常踩的“坑”。本文将从一个一线嵌入式工程师的视角彻底拆解SCI时钟同步模式的原理并结合RA8D2的用户手册深入到寄存器配置、时序波形、中断处理流程等细节。我会分享在多个实际产品中应用此模式的经验特别是那些手册上不会写的“潜规则”和调试技巧目标是让你不仅能看懂手册更能写出稳定、高效的驱动代码。2. 时钟同步模式的核心原理与配置逻辑要驾驭RA8D2的SCI时钟同步模式不能只停留在“配置寄存器使能通信”的层面。我们必须深入理解其工作机制才能做出正确的设计决策并在出现问题时快速定位。2.1 数据格式与同步机制的本质在时钟同步模式下数据以帧Frame为单位进行传输RA8D2的SCI固定使用8位数据长度且不支持奇偶校验位。这与异步模式有显著区别。数据位的采样和锁存完全依赖于同步时钟SCKn引脚的边沿。手册中的图38.61清晰地展示了数据格式在同步时钟的每个周期内传输一位数据。这里的关键在于LSBLeast Significant Bit最低有效位优先的传输顺序。这意味着当你向发送数据寄存器TDR写入一个字节例如0xA1二进制1010 0001第一位在线上出现的将是LSB即1最后一位是MSB1二进制最左边的位。注意许多工程师容易混淆字节在内存中的存储顺序大端/小端与串行通信的位顺序。SCI的LSB-first是固定的与你处理器的字节序无关。在编写数据打包/解包代码时务必注意这一点。同步的核心在于时钟与数据的相位关系这由两个关键参数决定CPOLClock Polarity时钟极性和CPHAClock Phase时钟相位。CPOL (CCR3.CPOL位)定义同步时钟的空闲状态电平。CPOL 0时钟空闲时为低电平。CPOL 1时钟空闲时为高电平。CPHA (CCR3.CPHA位)定义数据采样的时钟边沿。CPHA 0数据在同步时钟的第一个边沿若CPOL0则为上升沿CPOL1则为下降沿被采样并在下一个边沿改变。CPHA 1数据在同步时钟的第二个边沿被采样并在同一个边沿改变。这两者的组合形成了四种模式Mode 0-3这是与SPI从设备通信时必须严格匹配的。不匹配将导致数据完全错位。2.2 主从模式与时钟源选择RA8D2的SCI在时钟同步模式下通过配置CCR3寄存器的CKE[1:0]位来选择时钟源从而决定自身是主设备Master还是从设备Slave。CKE[1:0]模式时钟源SCKn引脚方向描述00b内部时钟主内部波特率发生器输出产生并输出时钟。用于驱动从设备。01b内部时钟主内部波特率发生器输出同上特定条件下的另一种主模式。10b外部时钟从SCKn引脚输入输入接收外部主设备提供的时钟。11b外部时钟从SCKn引脚输入输入同上通常用于带特定功能的从模式。内部时钟主模式要点作为主设备SCI负责生成通信时钟。只有在开始传输数据时才会在SCKn引脚上输出8个时钟脉冲。传输间隙时钟线会保持在高电平或低电平取决于CPOL的设置。手册中特别警告当设置SCK最大速度为1/(2*TCLK)时必须确保外设时钟PCLK不低于TCLK速度的一半否则可能发生故障。这是一个硬件限制在超频或分频系统时钟时需要仔细计算。主模式下禁止只接收不发送Reception-only。因为时钟由主设备产生如果主设备不发送数据就不会有时钟输出从设备自然也无法接收。全双工或仅发送是允许的。外部时钟从模式要点作为从设备SCI的时钟来自外部主设备。数据传输的启动和停止完全由主设备控制。从模式支持仅接收操作这在作为数据采集从机时非常有用。2.3 硬件流控制CTS与RTS功能详解在高速或实时性要求高的通信中防止数据丢失至关重要。RA8D2的SCI提供了CTSClear To Send和RTSRequest To Send硬件流控制功能但它们的使用有明确的限制和场景。CTS功能当SCI使用内部时钟主模式时通过CTSn_RTSn引脚输入低电平来允许自身开始发送或接收数据。这相当于主设备询问“从设备你准备好了吗” 从设备通过拉低CTS线回答“准备好了请发送。”使能设置CCR1.CTSE 1。行为CTSn_RTSn引脚为低时主设备开始输出时钟和数据为高时主设备暂停输出。但手册明确指出在传输或接收进行中时将该引脚拉高不会中断当前帧只影响下一帧的开始。这意味着流控制是以“帧”为粒度的。RTS功能当SCI使用外部时钟从模式时通过CTSn_RTSn引脚输出低电平向主设备请求开始传输。这相当于从设备向主设备请求“我有数据要收/发请给我时钟。”行为当SCI使能RE或TE置1且准备好进行下一次通信时例如发送缓冲区非空或接收缓冲区未满会自动拉低CTSn_RTSn引脚。通信完成后或条件不满足时引脚恢复高电平。关键限制CTS和RTS功能不能同时使用。因为一个引脚CTSn_RTSn不能同时作为输入和输出。你需要根据设备的主从角色来选择RA8D2作为主设备启用CTS功能监听从设备的“准备好”信号。RA8D2作为从设备启用RTS功能向主设备发出“准备好”信号。实操心得在很多简单的传感器应用中硬件流控制可能被省略以节省引脚。但当你连接的是像蓝牙模块、GPS模块或其他微处理器时启用流控制能极大提升通信可靠性避免因一端处理不及时导致的数据覆盖Overrun。务必在硬件设计阶段就规划好这些控制引脚。3. SCI时钟同步模式的初始化与配置实战理解了原理我们进入实战环节。配置RA8D2的SCI进行时钟同步通信是一个精细的“搭积木”过程每一步的顺序和细节都至关重要。手册中的表38.38提供了一个标准的初始化流程但我们需要理解每一步背后的“为什么”。3.1 初始化流程的逐步骤解析以下是基于手册流程结合工程实践的详细步骤和代码示例以SCI通道0为例使用非FIFO模式步骤1停止SCI并设置CCR0在修改任何关键配置尤其是通信模式前必须首先停止收发器。这是防止配置过程中产生不可预测通信行为的安全措施。/* 停止发送和接收关闭所有SCI中断 */ R_SCI0-CCR0_b.TE 0; R_SCI0-CCR0_b.RE 0; R_SCI0-CCR0_b.TIE 0; R_SCI0-CCR0_b.RIE 0; R_SCI0-CCR0_b.TEIE 0; /* 等待当前操作完成可选但建议 */ while (R_SCI0-CSR_b.TEND 0) { /* 等待发送结束 */ } /* 确保没有接收错误标志置位 */ if (R_SCI0-CSR_b.ORER || R_SCI0-CSR_b.FER || R_SCI0-CSR_b.PER) { // 进行错误处理并清除标志位 R_SCI0-CFCLR ...; // 清除错误标志 }步骤2复位FIFO如果使用FIFO如果计划使用FIFO功能需要在此处复位发送和接收FIFO将其清空。R_SCI0-FCR_b.TFRST 1; // 复位发送FIFO R_SCI0-FCR_b.RFRST 1; // 复位接收FIFO // 设置FIFO触发阈值例如发送缓冲区空时产生中断 R_SCI0-FCR_b.TTRG 0x01; // 发送FIFO空时产生TXI中断 R_SCI0-FCR_b.RTRG 0x08; // 接收FIFO有8个数据时产生RXI中断步骤3配置CCR3通信格式这是设置通信模式的核心。必须注意顺序先设置CPOL、CPHA等参数最后设置MOD[2:0]来选择时钟同步模式。/* 首先清零CCR3避免残留位影响 */ R_SCI0-CCR3 0x0000; /* 配置时钟同步模式参数 */ R_SCI0-CCR3_b.CPHA 1; // 时钟相位根据从设备规格选择 R_SCI0-CCR3_b.CPOL 0; // 时钟极性根据从设备规格选择 R_SCI0-CCR3_b.CHR 0; // 字符长度时钟同步固定为8位 R_SCI0-CCR3_b.STP 0; // 停止位时钟同步模式无效 R_SCI0-CCR3_b.MP 0; // 多处理器模式通常禁用 /* 最后设置为时钟同步模式 */ R_SCI0-CCR3_b.MOD 0x2; // 010b时钟同步模式步骤4配置CCR2波特率与时钟源设置通信的“速度”。如果使用外部时钟从模式则跳过此步骤。/* 假设系统时钟PCLK100MHz目标SCK时钟5MHz */ /* 计算波特率发生器设置值 N PCLK / (2 * 目标波特率) - 1 */ uint32_t pclk_freq 100000000; // 100 MHz uint32_t target_baud 5000000; // 5 Mbps uint16_t n_value (uint16_t)((pclk_freq / (2 * target_baud)) - 1); /* 检查是否超出范围并设置寄存器 */ if (n_value 0xFFFF) { R_SCI0-CCR2_b.BRRS 0; // 选择波特率发生器 R_SCI0-CCR2_b.BRR n_value; // 设置分频值 } /* 选择内部时钟作为源主模式 */ R_SCI0-CCR2_b.CKS 0x0; // 具体值参考手册选择内部时钟源步骤5配置CCR1引脚与流控制配置TXD、RXD、SCK引脚的功能以及是否启用CTS/RTS。R_SCI0-CCR1_b.LOOP 0; // 禁用回环测试正常模式 R_SCI0-CCR1_b.CTSE 0; // 假设禁用CTS功能 R_SCI0-CCR1_b.REVP 0; // 不反转引脚极性 // 注意RTS功能是通过配置CCR0.RE/TE以及硬件自动管理的CCR1中可能无直接使能位需参考具体章节。步骤6配置CCR4采样调整在高速主模式通信下为了补偿PCB走线延迟确保接收采样点位于数据位中央可以使用采样调整功能。R_SCI0-CCR4_b.ASEN 1; // 使能采样调整 R_SCI0-CCR4_b.AST 0x1; // 设置延迟量例如1个TCLK周期。需根据实际信号完整性测试调整。步骤7配置I/O端口将MCU的物理引脚功能切换到SCI的TXD、RXD、SCK。这一步高度依赖于你的具体硬件连接和RA8D2的引脚复用功能。/* 假设TXD0连接在P400 RXD0连接在P401 SCK0连接在P402 */ R_PMISC-PmnPFS[4].PmnPFS_b.PSEL 0x0A; // 将P400设置为SCI0_TXD (具体值查手册) R_PMISC-PmnPFS[4].PmnPFS_b.PDR 1; // 设置为输出 // ... 类似配置RXD和SCK引脚步骤8清除所有状态标志在开启通信前清除所有可能残留的错误或状态标志确保一个干净的开始。R_SCI0-CFCLR 0xFFFF; // 写入1清除所有相关标志具体位域需参考手册定义 R_SCI0-FFCLR 0xFFFF; // 清除帧错误等标志步骤9使能SCI并开启中断这是最后一步也是最关键的一步。对于发送和接收使能位TE, RE以及它们对应的中断使能位TIE, RIE手册强烈建议使用一条指令同时设置以避免在使能过程中出现意外的中断或竞争条件。/* 使用位域操作结构体通过一次赋值完成 */ R_SCI0-CCR0 (uint16_t)((1u CCR0_TE_Pos) | (1u CCR0_RE_Pos) | (1u CCR0_TIE_Pos) | (1u CCR0_RIE_Pos)); /* 或者使用寄存器整体赋值 */ R_SCI0-CCR0 0x0033; // 假设TE、RE、TIE、RIE的位掩码为此值完成这一步后TXDn和RXDn引脚将开始工作。如果配置为主模式且TDR中有数据或配置了RTS功能通信将立即开始。3.2 关键寄存器配置速查表为了方便查阅以下将核心配置项整理成表寄存器关键位域功能描述典型配置值示例CCR0TE, RE发送/接收使能。必须在最后一步与TIE/RIE同时设置。0x0003 (使能收发)TIE, RIE, TEIE发送空、接收满、发送结束中断使能。根据需求设置CCR2CKS选择时钟源内部/外部。0x0 (内部时钟)BRR波特率分频值。决定SCK频率。根据计算设置CCR3MOD[2:0]通信模式选择。必须最后设置。0x2 (时钟同步模式)CPOL, CPHA时钟极性与相位。必须在设置MOD前配置。根据从设备要求CHR[1:0]字符长度。时钟同步模式固定为8位。0x0CCR1CTSECTS功能使能主模式用。0或1LOOP回环测试模式。调试时使用。0 (正常模式)CCR4ASEN接收采样时序调整使能。1 (高速时启用)AST[1:0]采样延迟调整值。需实测调整。0x1FCRTFRST, RFRST发送/接收FIFO复位。使用FIFO前操作。1 (复位)TTRG, RTRG发送/接收FIFO触发阈值。如0x1, 0x8避坑指南初始化顺序是“陷阱”高发区。最常见的错误是未先停止TE/RE就修改CCR3这可能导致通信状态机混乱。先设置MOD后设置CPOL/CPHA某些硬件实现中模式切换可能会锁存当前的相位极性配置导致实际生效值与预期不符。务必遵循手册的“先配置参数后设置模式”顺序。分步使能TE和TIE如果先使能TESCI可能立即尝试发送TDR中的随机值可能是上次残留的而此时中断未就绪可能导致数据丢失或错误。使用单指令同时设置是最安全的做法。4. 数据收发过程与中断/DMA编程精要配置好硬件接下来就是软件驱动的核心如何高效、可靠地收发数据。RA8D2的SCI提供了中断和DMA两种主要方式来处理数据搬运。理解其内部状态机特别是TSR、TDR、RSR、RDR寄存器之间的交互是编写稳健驱动程序的关键。4.1 发送流程与非FIFO模式下的中断处理在非FIFO模式下数据发送依赖于两个关键寄存器TDR发送数据寄存器和TSR发送移位寄存器。其工作流程如下启动当你同时设置CCR0.TE1和CCR0.TIE1后如果TDR为空SCI会立即产生一个SCIn_TXI发送数据空中断。填充缓冲区在TXI中断服务程序ISR中你的任务是将下一个要发送的字节写入TDR寄存器。写入后硬件会自动将数据从TDR加载到TSR并开始移位发送。同时TDR再次变空产生下一个TXI中断为后续数据做准备。连续发送只要你在当前帧发送完成前即TSR正在移位输出当前字节时在TXI中断中写入下一个字节到TDR就能实现无缝的连续发送。发送结束当你发送完最后一个字节后你不再向TDR写入新数据。在当前帧最后一个字节发送完成后TSR变空且TDR无新数据硬件会设置CSR.TEND发送结束标志。如果你使能了发送结束中断CCR0.TEIE1还会产生SCIn_TEI中断通知你整个发送序列已完成。手册中的图38.62至38.64以及流程图38.65完美诠释了这个过程。关键在于理解“双缓冲”机制TDR是CPU可访问的“预备区”TSR是正在发送的“前线”。TXI中断意味着“预备区已空可以准备下一发弹药了”。代码示例非FIFO模式中断发送volatile uint8_t tx_buffer[100]; volatile uint16_t tx_index 0; volatile uint16_t tx_length 0; volatile bool tx_busy false; void start_sci0_transmit(uint8_t *data, uint16_t len) { // 确保上次传输已完成 while(tx_busy); // 复制数据到缓冲区 memcpy((void*)tx_buffer, data, len); tx_index 1; // 第一个字节将通过首次TXI中断后的写入发送 tx_length len; tx_busy true; // 写入第一个字节到TDR并同时使能TE和TIE R_SCI0-TDR tx_buffer[0]; // 单指令同时设置TE和TIE启动传输并开启中断 R_SCI0-CCR0 | (1u CCR0_TE_Pos) | (1u CCR0_TIE_Pos); } // SCI0 TXI 中断服务程序 void sci0_txi_isr(void) { if (tx_index tx_length) { // 还有数据要发写入下一个字节到TDR R_SCI0-TDR tx_buffer[tx_index]; } else { // 所有数据已写入TDR关闭TXI中断准备等待发送结束 R_SCI0-CCR0_b.TIE 0; // 可选使能TEIE中断以便在全部发送完成后得到通知 R_SCI0-CCR0_b.TEIE 1; } } // SCI0 TEI 中断服务程序如果使能了TEIE void sci0_tei_isr(void) { // 整个发送序列完成 tx_busy false; R_SCI0-CCR0_b.TEIE 0; // 关闭TEI中断 // ... 可以通知主程序或开始下一轮操作 }4.2 接收流程与错误处理接收流程与发送对称但多了错误处理环节。关键寄存器是RSR接收移位寄存器和RDR接收数据寄存器。启动接收设置CCR0.RE1。如果使用RTS功能CTSn_RTSn引脚会输出低电平通知主设备“从机已就绪”。数据移入时钟边沿到来时数据从RXDn引脚移入RSR。数据就绪一个字节8位接收完成后数据从RSR自动传输到RDR。硬件设置CSR.RDRF接收数据就绪标志如果CCR0.RIE1则产生SCIn_RXI中断。读取数据在RXI中断中你必须读取RDR寄存器。读取操作会清除RDRF标志。如果你使用RTS功能读取RDR使得接收缓冲区“有空位”可能会再次拉低RTS引脚请求主设备发送更多数据。错误处理接收过程中可能发生溢出错误ORER。当CPU或DMA未及时读取RDR而下一个字节已经接收完成时就会发生溢出。此时CSR.ORER标志置1并产生SCIn_ERI接收错误中断。发生溢出后必须执行以下操作才能恢复接收 a.读取RDR寄存器即使数据可能已损坏。 b.清除ORER标志通过向CFCLR.ORERC位写1。 c. 检查并清除其他可能错误标志FER, PER。手册中的流程图38.69清晰地展示了这个流程特别是错误处理的路径。致命陷阱溢出错误ORER发生后如果不按上述步骤清除接收通道将永远挂起无法接收新数据。这是新手最容易忽略的问题。一个健壮的接收ISR必须包含对CSR错误标志的检查。4.3 FIFO模式的优势与配置要点RA8D2的SCI支持FIFOFirst In, First Out缓冲区深度为16级。启用FIFO可以大幅减少中断频率提升系统效率尤其是在高波特率或主频较低的系统中。发送FIFO你可以一次性向TDR此时是发送FIFO的入口写入最多16个字节。硬件会在内部FIFO未满时自动将数据从FIFO加载到TSR进行发送。FCR.TTRG[4:0]设置了发送FIFO的触发阈值。例如设置为1则当发送FIFO中的数据量小于或等于1时产生TXI中断提示你可以补充数据了。接收FIFO硬件会将接收到的字节依次存入接收FIFO。FCR.RTRG[4:0]设置了接收FIFO的触发阈值。例如设置为8则当接收FIFO中的数据量达到或超过8个时产生RXI中断提示你可以批量读取了。FIFO模式下的初始化差异 主要在步骤2需要配置FCR寄存器并设置合适的触发阈值。在中断处理中你不再是读写单个字节而是读写一批数据。代码片段FIFO模式发送void sci0_fifo_txi_isr(void) { uint8_t fifo_free_slots 16 - R_SCI0-FTSR_b.T; // 读取FTSR.T[5:0]获取FIFO空闲数 while (fifo_free_slots 0 tx_index tx_length) { R_SCI0-TDR tx_buffer[tx_index]; fifo_free_slots--; } if (tx_index tx_length) { // 所有数据已填入FIFO关闭TXI中断等待发送完成 R_SCI0-CCR0_b.TIE 0; R_SCI0-CCR0_b.TEIE 1; } }4.4 全双工通信与模式切换时钟同步模式天然支持全双工同时收发。在RA8D2上你需要同时使能TE和RE位。但手册警告在主模式下禁止仅接收RE1, TE0因为主设备不发送就无法产生时钟。模式切换如从仅发送切换到全双工需要谨慎发送到全双工等待当前发送完成CSR.TEND 1然后单指令同时设置TIE, RIE, TE, RE为1。接收到全双工先设置TE0, RE0确保所有接收错误标志已清除ORER, FER, PER 0然后单指令同时设置TIE, RIE, TE, RE为1。同时使用RTS功能的全双工注意事项当作为从设备且使能RTS时如果你想在接收完最后一帧数据后不让RTS引脚再次拉低即通知主设备停止发送需要在读取最后的数据之前同时清除RE和TE位CCR0.RE 0; CCR0.TE 0;然后再去读RDR。5. 高级话题调试技巧、性能优化与常见问题排查即使按照手册配置在实际硬件上仍然可能遇到各种问题。以下是一些从项目实践中总结的经验。5.1 调试技巧没有逻辑分析仪怎么办使用GPIO翻转在关键代码段如中断入口、出口、读写寄存器前后插入GPIO引脚的高低电平翻转。用示波器观察这些引脚可以精确测量代码执行时间判断中断是否及时响应。// 在ISR开始和结束处翻转一个调试引脚 void sci0_rxi_isr(void) { R_PORT-PmnPFS[DEBUG_PIN].PmnPFS_b.PODR ^ 1; // 翻转 // ... 处理数据 R_PORT-PmnPFS[DEBUG_PIN].PmnPFS_b.PODR ^ 1; // 翻转回来 }利用回环Loopback模式将CCR1.LOOP设置为1使TXD内部连接到RXD。这样MCU自己发送的数据会被自己接收。这是测试驱动程序基本功能不含外部硬件的绝佳方法。如果回环测试通过但连接外部设备失败问题很可能出在硬件电平、时序、接线或从设备配置上。检查寄存器状态在通信异常时首先读取所有SCI相关状态寄存器CSR, FTSR, FRSR等并与手册描述对比。ORER、FER等错误标志是首要排查点。5.2 性能优化考量中断 vs DMA中断实现简单适合低速或非连续通信。但在高波特率下频繁的中断可能消耗大量CPU资源。DMA将数据搬运工作交给DMA控制器CPU仅在缓冲区半满或全满时被中断效率极高。RA8D2的SCI可以触发DMA传输。对于大数据量、高速度的连续传输强烈建议使用DMA。配置DMA时注意源/目标地址、传输数据宽度8位和触发源SCI_TXI, SCI_RXI。FIFO阈值设置FIFO触发阈值的设置是平衡实时性和中断开销的关键。设置较小的RTRG如1或2接收响应快但中断频繁。设置较大的RTRG如12或14中断次数少但数据延迟增加且需确保接收FIFO不会在中断处理前溢出16字节深度。手册特别提醒在FIFO接收模式下总接收数据量最好是RTRG的整数倍否则在判断“所有数据接收完成”时容易陷入死循环需要额外的超时机制。时钟与功耗较高的SCK时钟意味着更高的功耗。在电池供电设备中应根据实际需求选择最低可用的波特率。同时注意PCLK与SCK的速度关系限制避免设置非法值导致模块失效。5.3 常见问题排查速查表现象可能原因排查步骤完全无通信1. 引脚复用未配置。2. TE/RE未使能。3. 主从设备CPOL/CPHA不匹配。4. 时钟源配置错误主设备未输出时钟。1. 用万用表或示波器检查SCK、MOSI、MISO引脚是否有输出。2. 确认CCR0.TE/RE已置1。3. 核对主从设备CPOL/CPHA设置。4. 主模式检查CCR2波特率设置测量SCK引脚波形。数据错位如0x55收成0xAA1. LSB/MSB位顺序误解。2. CPHA设置错误采样边沿不对。1. 确认数据位顺序。发送0x010000 0001用逻辑分析仪看第一位是1(LSB)还是0(MSB)。2. 调整CPHA值。只能发送一次数据1. TXI中断未正确处理未持续写入TDR。2. 发送完成后错误地关闭了TE位。1. 检查TXI ISR是否在发送完成前写入了下一个数据。2. 确保在连续发送期间TE保持为1。接收数据丢失/溢出1. RXI中断处理太慢未及时读取RDR。2. 发生溢出错误ORER后未正确清除。1. 优化RXI ISR或使用FIFODMA。2. 在ERI ISR或主循环中检查并清除ORER标志先读RDR再写ORERC。RTS/CTS流控制失效1. 主从角色与CTS/RTS功能选反。2. 引脚连接错误或未上拉。3. 从设备未及时释放CTS或响应RTS。1. 确认主设备用CTS输入从设备用RTS输出。2. 检查硬件连接必要时加上拉电阻。3. 用示波器观察CTS/RTS引脚时序是否符合预期。通信速度远低于设定值1. 系统时钟PCLK配置错误实际频率低。2. 波特率分频值BRR计算或设置错误。1. 检查系统时钟树配置确认PCLK频率。2. 重新计算BRR值使用示波器测量实际SCK频率进行验证。5.4 外部时钟从模式下的特殊注意事项当RA8D2作为从设备使用外部时钟时有一个极易忽略但可能导致通信失败的细节手册在图38.65和38.66的注释中明确警告“When the external clock is in use..., the rising edge on the SCK pin for the last bit sets the CSR.TEND flag to 1. Setting TE to 0 immediately after this, then it may lead to insufficient received data hold time on the receiver side.”翻译与解读当使用外部时钟时最后一个数据位的SCK上升沿会将TEND标志置1。如果在此之后立即将TE位清零可能会导致接收方数据保持时间不足。这是什么意思在从模式下发送完成TEND置1是由主设备提供的最后一个时钟边沿触发的。然而从设备的TXD引脚输出最后一个数据位后需要一定的“保持时间”才能改变状态或进入高阻态。如果从设备在TEND置1后立刻关闭发送器TE0TXD引脚可能过早改变而此时主设备可能还在采样这个数据位导致主设备采样到错误的数据。解决方案 在从模式下发送完成后不要立即清零TE位。可以等待一小段延时例如几个微秒或者等待一个明确的“通信会话结束”信号如主设备拉高片选信号CS后再禁用发送器。更好的做法是在从设备中除非必要否则让TE位一直保持使能状态仅通过控制是否向TDR写入数据来管理发送。