2

问题:我将一个值发送到 UART,而另一个 UART 上出现空值。

- - 细节 - -

这些都是 PIC 处理器(PIC24 和 PIC32)

它们都硬连线到印刷电路板上。

它们通过其中一个 UART 模块进行通信。

它们(表面上;根据文档)都配置为 115200 bps,8-N-1

没有握手,没有启用 CTS,没有启用 RTS;我只是把字节放在线上,然后它们就出来了。

(这些是简短的 4 字节命令和响应,非常适合)

PIC32 的频率为 80 MHz。

PIC24 的 F[cy] = 14745600

即,它是 14.7456 MHz

PIC24 发送四个字节(一个特定的命令序列)

当我在 UART 的中断服务程序中设置断点时,PIC32 显示空值,然后我看到在前四个断点上重复命中(PIC32 代码),并且我继续看到空值(因为 PIC24没有发送任何东西)

即,UART 似乎在没有原因的情况下重复产生中断

我没有在 PIC32 端编写代码,我每天都在学习它是如何工作的。

然后我让代码运行,我不可避免地会在一行上写着

    52570 1D01_335C 9D01_335C  _general_execption_handler  sdbbp 0x0

当我到那的时候,

  • 原因寄存器持有0080181C
  • EPC 寄存器持有9D00F228
  • SP寄存器持有9F8FFFA0

这就像发条一样发生,所以我对不会停止的 __ISR 产生了怀疑。MpLab向我展示了这个......

           432:
           433:                 //*********************************************************//
           434:                 void __ISR(_UART1_VECTOR, ipl5) IntUart1Handler(void)   //MCU communication port
           435:                 {
           9D00F204  415DE800   rdpgpr      sp,sp
           9D00F208  401A7000   mfc0        k0,EPC
           9D00F20C  401B6000   mfc0        k1,Status
           9D00F210  27BDFF88   addiu       sp,sp,-120
           9D00F214  AFBA0074   sw          k0,116(sp)
           9D00F218  AFBB0070   sw          k1,112(sp)
           9D00F21C  7C1B7844   ins         k1,zero,1,15
           9D00F220  377B1400   ori         k1,k1,0x1400
           9D00F224  409B6000   mtc0        k1,Status
           9D00F228  AFBF0064   sw          ra,100(sp) ;<<<-------EPC register always points here
           9D00F22C  AFBE0060   sw          s8,96(sp)
           9D00F230  AFB9005C   sw          t9,92(sp)
           9D00F234  AFB80058   sw          t8,88(sp)
           9D00F238  AFAF0054   sw          t7,84(sp)
           9D00F23C  AFAE0050   sw          t6,80(sp)
           9D00F240  AFAD004C   sw          t5,76(sp)
           9D00F244  AFAC0048   sw          t4,72(sp)
           9D00F248  AFAB0044   sw          t3,68(sp)
           9D00F24C  AFAA0040   sw          t2,64(sp)
           9D00F250  AFA9003C   sw          t1,60(sp)
           9D00F254  AFA80038   sw          t0,56(sp)
           9D00F258  AFA70034   sw          a3,52(sp)
           9D00F25C  AFA60030   sw          a2,48(sp)
           9D00F260  AFA5002C   sw          a1,44(sp)
           9D00F264  AFA40028   sw          a0,40(sp)
           9D00F268  AFA30024   sw          v1,36(sp)
           9D00F26C  AFA20020   sw          v0,32(sp)
           9D00F270  AFA1001C   sw          at,28(sp)
           9D00F274  00001012   mflo        v0
           9D00F278  AFA2006C   sw          v0,108(sp)
           9D00F27C  00001810   mfhi        v1
           9D00F280  AFA30068   sw          v1,104(sp)
           9D00F284  03A0F021   addu        s8,sp,zero

我更仔细地查看了这些数字,我发现当时,如果我们将 100 (0x64) 加到 FFA0(SP 的底部 16 位),我们得到 0x10004,我猜这个数字是 4 太多了。

PIC 手册 DS61143E 第 50 页说该命名法意味着,SW Store Word Mem[Rs+offset> = Rt其他专家告诉我原因寄存器告诉我 EXCCODE 位是 7,这是加载或存储时总线异常的代码。

或者,我在这里完全猜测(希望获得一些专家的知识)某些东西没有清除某些东西,我在 int 处理程序上遇到了无限递归。

所有这些都开始变得有意义了。

问题

有人可以建议像这样的 int 反复打击我的最常见原因吗?

有没有人看到来自 UART 的虚假 nuls 之间的任何共同关系,这可能以某种方式与这个无休止生成的 int 相关联?我什至走在正确的轨道上吗?

在您的回答中,请告诉我如何从 UART 确认 Int。我知道我是如何在 PIC24 中做到这一点的(我完全用 ASM 编写了该代码),但我不知道这是如何在 PIC32 上的 C 语言中完成的。组装会好的。我会内联它。我正在使用我没有在这里编写的代码,感谢您的回答

UART(在这种情况下为#1)会重复产生中断的最常见原因是什么?

4

4 回答 4

6

在许多设备上,必须明确清除中断以防止 ISR 在完成后简单地重新进入。

在大多数情况下,UART 将具有指示中断源的状态位,知道这可能会告诉您一些事情,但不告诉我们会很难为您提供帮助。您可以直接在调试器中检查 UART 寄存器,但是在某些设备中,读取位的行为实际上可能会清除位,在调试器中也是如此,因此请注意这种可能性(检查数据表/用户手动的)。

一些 UARTS 要求明确关闭其发送器以停止发送空值,而另一些 UARTS 在数据放入 tx 寄存器时自动触发,并在移出必要数量的位后停止。再次检查零件的数据表/手册。如果已知 PIC32 代码可以正常工作,那么由于 PIC24 代码可能出现此错误,因此它似乎很合适。您可以通过在 PIC24 的 Tx 线上使用示波器来简单地检查这一点,如果它正在发送,您将至少看到开始/停止位转换(帧)。如果什么都没有,那么问题很可能出在 PIC32 端。

当您有示波器时,您可以检查位时序是否正确,并且您实际上在 115200 传输。很容易弄错时钟,这应该是您的第一个检查。如果波特率不正确,PIC32 可能会产生帧错误中断,如果不加以处理,可能会无限期地持续存在。

另一种可能性是在传输后 PIC24 使线路处于“中断”状态,而 PIC32 UART 正在生成“线路中断”中断。这就是为什么查看 UART 状态寄存器以确定中断原因很重要的原因。

如您所见,有很多可能性;我想我已经介绍了最有可能的那些,但是需要您进行更有条理的调试工作和信息收集。我希望我在这方面也为您提供了指导。

于 2013-02-23T08:39:26.413 回答
6

反复调用中断子程序的最常见原因是中断请求在程序中从未得到确认。你确定你清除了相应的IRQ位吗?

为了简化 UART 调试,您应该首先将 UART 连接到 PC,并确保您的目标可以与 PC 进行双向通信。同时使用两个目标,除了用示波器检查信号外,您无法确定问题出在哪一个上。

于 2013-02-22T22:15:55.387 回答
1

存在三个根本原因...

  • 在 UART1 的初始化代码中,中断优先级设置为值 6
  • 中断服务程序的第一行被编码为中断优先级为 5
  • UART 数据的前三个字节从数据流中消失(这仍未解决)

这是他们导致问题的不那么明显的方式

  • 前三个字节从未出现
  • 第四个字节确实出现了
  • 中断命中(如第 6 级)和调用__ISR例程
  • __ISR担任ipl5代理人
  • 执行的第一条指令(可能更多,我无法准确调试)
  • 第一条指令完成后,“更高”优先级 6 中断立即启动
  • 这再次导致了相同的中断
  • 这个过程无限重复。
  • 很快,Stack Overflow 就产生了

修复

确保这两行代码彼此一致...

初始化代码中的 IPL 行,错误的方式然后正确的方式

     //IPC6bits.U1IP=6; //// Wrong !!! Uart 1 IPL should not be 6 !!!
     
     IPC6bits.U1IP=5;   //// Uart 1 IPL = 5  Correct way; matches __ISR

中断服务程序

     void __ISR(_UART1_VECTOR, ipl5) IntUart1Handler(void)  //// Operating as IPL 5
     :
     :
     :
     :
于 2013-02-26T01:17:28.480 回答
0

糟糕的设计决策。如果两者都在同一块板上,那么 SPI 会更可行且速度更快。

于 2013-07-22T06:45:13.843 回答