我有其他人编写的代码(对于 dsPIC33FJ128MC706A) - 它初始化UART1
和 PWM 并在中断中使用忙等待U1Rx
来获取 14 个字节,如果新数据到达,则 timer1 中断以更新 PWM 寄存器(已调试 - 它进入_U1RXInterrupt
数据何时发送)
我尝试修改它以使用 DMA 而不是忙等待。我在初始化中没有任何改变,但在初始化 UART 后调用了以下函数:
unsigned char received_data1 [0x0f] __attribute__((space(dma)));
unsigned char received_data2 [0x0f] __attribute__((space(dma)));
void dma_init(void)
{
DMA0REQ = 0x000b; // IRQSEL = 0b0001011 (UART1RX))
DMA0PAD = (volatile unsigned int) &U1RXREG;
DMA0STA = __builtin_dmaoffset(received_data1);
DMA0STB = __builtin_dmaoffset(received_data2);
DMA0CNT = 0xe;//15 bytes in
DMA0CON = 0x0002; //continuous ping-pong + post-increment
IFS0bits.DMA0IF = 0;
IEC0bits.DMA0IE = 1;
DMA0CONbits.CHEN = 1;
}
这是基于FRM 中的示例 22-10,有一些细微的变化(UART1
receiver 而不是UART2
)。我似乎找不到其他不使用库函数的示例(在遇到这些示例之前我什至不知道存在)。(另外,为了与我得到的代码保持一致,我在_ISR
之后void
而不是创建interrupt
一个属性,但这并没有改变任何东西)
在示例中,接收器没有中断UART1
- 但根据 FRM,它应该被启用。对我来说,我不需要自己清除中断标志是有道理的(如果我需要使用 CPU,它会有点违背 DMA 的目的)。
然而,当我发送数据时,DMA0Interrupt
不会触发断点,但默认中断上的断点会触发,而且我有PWMIF=1
and U1RXIF=1
。我还尝试注释掉默认 ISR 并添加一个_U1ErrInterrupt
即使检查标志我没有注意到任何错误标志被引发,只是正常的U1RXIF
.
我不明白为什么会发生这种情况。我根本没有更改 PWM 代码,当我在_U1RxInterrupt
. 我什至不明白 DMA 设置如何导致 PWM 错误。
该U1RXIF
标志似乎告诉我 DMA 没有处理传入的字节(我假设是 DMA 清除了标志),这再次与“我在这个 DMA 设置中做错了什么”这个问题有关
UART初始化代码:
在一般初始化函数中(由 调用main()
)
TRISFbits.TRISF2 = 1; /* U1RX */
TRISFbits.TRISF3 = 0; /* U2TX */
也被 main 调用:
void UART1_init_USB (void)
{
/* Fcy 7.3728 MHZ */
U1MODE = 0x8400; /* U1ATX Transmit status and control register */
U1STA = 0x2040; /* Receve status and control register Transmit disabled*/
U1BRG = 0x000f; /* Baund rate control register 115200 bps */
IPC2bits.U1RXIP = 3; /* Receiver Interrupt Priority bits */
IEC0bits.U1RXIE = 1; /* Enable RS232 interrupts */
IFS0bits.U1RXIF = 0;
}
(原始代码作者的评论)