后续问题。
如果我使用的是 SPI B1、根据表6-11 (SLASE54C.pdf)、应使用 DMA 触发器18和19。 但这两个都放置在通道3上。
这是否意味着我无法在 RX 和 TX 上运行 DMA、因为 DMA CHANNEL3将同时用于这两种情况?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
后续问题。
如果我使用的是 SPI B1、根据表6-11 (SLASE54C.pdf)、应使用 DMA 触发器18和19。 但这两个都放置在通道3上。
这是否意味着我无法在 RX 和 TX 上运行 DMA、因为 DMA CHANNEL3将同时用于这两种情况?
是的、主器件必须写入 TXBUF 才能使 SPI 运行。 您可以运行重复单字节的 Tx (无增量模式)、但某些实体必须执行 TXBUF 写入。
我曾经尝试过但从未真正尝试过的一种方法是使用计时器为 TXBUF 馈送电流(DMA 触发器之一1-9)。 您可以对计时器进行调优、以在每个字节时间触发并从复制到 TXBUF 。 此设置中没有 Tx 流控制、但 SPI (非常简单)简单且具有确定性。
DMA 会将触发源复位,而不受寄存器读/写操作的影响,因此您可以获得重复的触发。 当定时器和 SPI 都从同一个时钟(SMCLK)运行时、应该存在一个与 SPI 数据速率匹配的理想定时器计数(如16)(即无间隙)。
这可能有一些原因不起作用、但考虑到您已经拥有了大部分基础架构、我认为尝试它可能只需要10行附加代码。 我不确定我的 gizmo 框中是否有合适的从器件(在没有某种命令的情况下发送有趣的内容)。
我的神经元终于点火了、我意识到我可以将主机用作从设备(环回)。 我设置了简单的情况(有变体)、它似乎按预期工作。
[编辑:我忘记了提及:这是在 FR5994 Launchpad (修订版1.2)、修订版 C 器件上运行的]
这是在 TA2CCR0=20时:
这是在 TA2CCR0=16的情况下进行的(我不确定该初始 GAP 的含义):
下面是我使用的程序:
#include #include define Hz 1000000UL //大致 #define GAP 4 #define XSIZE 16. //事务大小 uint8_t Tx[XSIZE]、Rx[XSIZE]; #define NOP () do{__no_operation ();}while (0) int main (void) { uint16_t I; WDTCTL = WDTPW | WDTHOLD;//停止看门狗定时器 P1OUT &=~(BIT0|BIT1); P1DIR |=(BIT0|BIT1); //每个人都需要 LED PM5CTL0 &=~LOCKLPM5; //为 (i = 0;i < XSIZE;++I) {启用 GPIO TX[i]= i; RX[i]=~i; // Poison } //主设备、MSB 优先、SMCLK、3线同步 UCB1CTLW0 = UCMST|UCMSB|UCSSEL_2|UCSSEMODE_0|UCSYNC|UCSWRST; UCB1BRW = 2; UCB1CTLW0 &=~UCSWRST; PIT0|BIT0|B0 // P5.0-2作为 UCB1SIMO/SOMI/CLK (DS 表6-31 //在 UCB1RXIFG 上触发 Rx 侧、在 TA2CCR0上触发 Tx 侧 DMACTL1 = DMA3TSEL__UCB1RXIFG|DMA2TSEL_TA2CCR0上触发 Rx 侧;//每个 SLASE54C = DMACTL1、 Rx 侧增量、不是 SPI 字节/字节(单个字节)。 __data20_write_long ((uintptr_t)&DMA3SA、(uintptr_t)&UCB1RXBUF);//__SFR_FARPTR 胡说 __data20_write_long ((uintptr_t)&DMA3DA、(uintptr_t)&rx[0]); //__SFR_FARPTR 胡言 DMA3SZ = XSIZE; DMA3CTL = DMADD_0 | DMADSTINCR_3 | DMASRCINCR_0 | DMADSTBYTE | DMASRCBYTE; // Timer+SPI Tx 端:单个、字节、增量源、而不是 dest __data20_write_long ((uintptr_t)&DMA2SA、(uintptr_t)&Tx[0]); //__SFR_FARPTR 胡言 __data20_write_long ((uintptr_t)&DMA2DA、(uintptr_t)&UCB1TXBUF);//__SFR_FARPTR 胡说 DMA2SZ = XSIZE; DMA2CTL = DMADD_0 | DMADSTINCR_0 | DMASRCINCR_3 | DMADSTBYTE | DMASRCBYTE; //每字节时间触发一次的计时器 TA2CCR0 =(2*8)+GAP-1; // BR=2*8位,加上 GAP TA2CCTL0 =(0*CCIFG); //保持整洁 TA2CTL = tassel_2 | ID_0 | MC_0 | TACLR;// SMCLK/1 [、上行 RSN][、CLEAR] while (1) { P1OUT ^= BIT0; DMA3CTL |= DMAEN; // Rx 端优先 DMA2CTL |= DMAEN; // Tx 侧 TA2CCTL0 =(0*CCIFG); //保持整洁 TA2CTL |= MC_1 | TACLR; //向上计数模式 while (DMA3CTL & DMAEN) NOP(); //等待完成 TA2CTL &=~MC; //停止计时器 P1OUT ^=(BIT0|BIT1); // P1.0持续时间、P1.1心跳 __DELAY_CYCLES (Hz/2); }/*NOTREACHED*/ 返回0; }