使用 PIC16F18326 的背靠背 UART 传输 - 跳过的字节

Back-to-back UART transmission with PIC16F18326 - Skipped bytes

我正在使用 PIC16F18326 通过 UART(异步,250k 波特率)传输一些数据。 MCU运行频率为32MHz,实际指令频率为8MHz

我正在使用以下汇编代码发送 4 个字节(从 0xAA 到 0xAD - 不要介意无用的重复 BANKMASK):

movlw   0xAA
banksel TX1REG
movwf   BANKMASK(TX1REG)
movlw   0xAB
banksel TX1REG
movwf   BANKMASK(TX1REG)
movlw   0xAC
banksel TX1REG
movwf   BANKMASK(TX1REG)
movlw   0xAD
banksel TX1REG
movwf   BANKMASK(TX1REG)
goto $

逻辑分析器的结果是只发送了 0xAA 和 0xAD(第一个和最后一个字节)。

我知道我不能连续发送 4 个字节(没有任何延迟,或者对 UART 寄存器进行一些检查),但我希望发送 0xAA 和 0xAB(前 2 个字节) .

根据数据表,如果 TX1REG 和 TSR 寄存器为空(这是我的情况,因为我从未传输过任何东西),我可以写入 TX1REG 以开始发送第一个字节,然后在至少 1时钟周期我可以排队第二个字节。根据下面的代码,两次写入之间有 3 个时钟周期。

那么,出了什么问题?

查看有关功能列表的 this 第 367 页:

  • 全双工异步收发
  • 双字符输入缓冲区
  • 单字符输出缓冲区
  • 可编程 8 位或 9 位字符长度
  • 9 位模式下的地址检测
  • 输入缓冲区溢出错误检测
  • 接收字符帧错误检测
  • (等等)

您遇到的问题类似于缓冲区溢出。如果这是关于正确的 USART,那么您得到的只是意料之中的结果。

一个更通用的软件位将有助于循环每个字符并等待 "buffer ready bit"(或任何它被调用的),然后再用下一个字符加载缓冲区。

找到原因了。写入 TX1REG 会覆盖寄存器中包含的任何内容。写入独立于任何状态位(在本例中为 TXIF)。
当UART准备好传输时,它只会获取TX1REG的内容并发送。

在我上面的例子中:

Write 0xAA
0xAA is sent immediately
Write 0xAB
0xAB is stored, but not sent because the first send has not finished yet
Write 0xAC
0xAC is stored, but not sent because the first send has not finished yet
Write 0xAD
0xAD is stored, but not sent because the first send has not finished yet

一段时间后0xAA的传输完成,此时UART发送0xAD,因为它是TX1REG的(最后)内容。