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.

[参考译文] MSP430FR6989:使用 DMA 在 RAM 中存储 RX 数据的 SPI 从站不起作用

Guru**** 2604225 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/651674/msp430fr6989-spi-slave-using-dma-to-store-rx-data-in-ram-not-works

器件型号:MSP430FR6989

你(们)好

我想使用 DMA Ch0  将 UCA0RXBUF 直接存储到 RAM 中、

 SPI 的每个数据包有1536字节、在使用 DMA 函数之前 、我 可以 确保 SPI 从器件函数运行良好、  所有1536字节数据都可以存储在 SPI ISR 中的 RAM 成功中。

但是、当我将代码切换到 DMA 模式时、一切都发生了错误、1>它永远不会进入 DMA ISR、2>我将 UCA0RXIFG 设置为 DMA0的触发源、并且使用 CCS 调试模式、我可以确保 UCA0RXIFG 在接收数据时可以变为高电平、但不知道 DMA 为什么不起作用。 3> DMA 功能无法成功将任何数据存储到存储器空间中。

下面是我的测试代码、需要您的帮助才能找出问题所在、谢谢。

#include "msp430.h"
#define DMA 1.
#define SPI_RX_BYTE_NUM 1536

void GPIO_Init (void);
void Clock_Init (void);
void SPI_A0_Init (void);
#if (DMA)
void dma_Init (void);
#endif
#if (!dma)
静态无符号字符 RX_BUF[SPI_RX_BYTE_NUM];
静态无符号 int RX_Index;
#endif

int main (空)

 WDTCTL = WDTPW | WDTHOLD;                //停止看门狗
 GPIO_Init();
 PM5CTL0 &=~LOCKLPM5;
 Clock_Init();
 SPI_A0_Init();
#if (DMA)
 DMA_Init();
#endif

 __no_operation();
 __bis_SR_register (/*CPUOFF +*/ GIE);
 while (1)
 {
     __no_operation();
 }

void GPIO_Init (void)

   P1SEL1 |= BIT5 | BIT4;                   //配置从器件选择和 clk
   P2SEL0 |= BIT0 | BIT1;                   //配置 SOMI 和 MISO


空时钟初始化(空)

   FRCTL0 = FRCTLPW | NWAITS_1;
   //时钟系统设置
   CSCTL0_H = CSKEY >> 8;                   //解锁 CS 寄存器
   CSCTL1 = DCOFSEL_4 | DCORSEL;           //将 DCO 设置为16MHz
   CSCTL2 = SELA_VLOCLK | SELS__DCOCLK | SELM_DCOCLK;//设置 SMCLK = MCLK = DCO、
   CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;    //设置所有分频器
   CSCTL0_H = 0;                            //锁定 CS 寄存器

void SPI_A0_Init (void)

   //为 SPI 操作配置 USCI_A0
   UCA0CTLW0 = UCSWRST;                     //**将状态机置于复位状态**
                                             // 4引脚、8位 SPI 从器件
   UCA0CTLW0 |= UCSYNC | UCCKPH | UCMSB | UCMODE_2 | UCSTEM;

   UCA0CTLW0 |= UCSSEL_SMCLK;
   UCA0BR0 = 0x01;                          ///1
   UCA0BR1 = 0;                             //
   UCA0MCTLW = 0;                           //无调制
   UCA0CTLW0 &=~UCSWRST;                   //**初始化 USCI 状态机**
#if (!dma)
   UCA0IE |= UCRXIE;                        //启用 USCI_A0 RX 中断
#endif

#if (DMA)
空 DMA_Init (空)

    DMACTL0 |= DMA0TSEL_14;           // UCA0RXIFG 触发器
    DMA0CTL = DMADD_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMADSTBYTE + DMASRCBYTE;
   __data16_write_addr ((unsigned short)&DMA0SA、(unsigned short)&UCA0RXBUF);//源单地址

   __data16_write_addr ((unsigned short)&DMA0DA、(unsigned short) 0x1c00);//目标数组地址

   DMA0SZ = 1536;


#endif

#if (!dma)
#pragma vector=USCI_A0_Vector
_interrupt void USCI_A0_ISR (void)

 RX_BUF[RX_Index]= UCA0RXBUF;
 RX_Index++;
 if (RX_Index = SPI_RX_BYTE_NUM)
 {
     RX_Index = 0;
     __no_operation(); //在此设置断点
 }


#endif

#if (DMA)
#pragma vector=dma_vector
_interrupt void DMA0_ISR (void)

 switch (__evo_in_range (DMAIV、16))
 {
   情况 0:中断;                         //无中断
   案例 2:
       __no_operation(); //在此设置断点
    //__BIC_SR_REGISTER_ON_EXIT (CPUOFF);    //退出 LPM
     中断;                                // DMA0IFG
   案例 4:中断;                         // DMA1IFG
   案例 6:中断;                         // DMA2IFG
   案例 8:中断;                         //保留
   案例10:中断;                         //保留
   案例12:中断;                         //保留
   案例14:中断;                         //保留
   案例16:中断;                         //保留
   默认值:break;
 }

#endif

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Erik、

    您是否在命令链接器文件中为该数据正确分配 RAM 空间? 我建议改用 RX_BUF 阵列位置(FRAM)、因为将数据放入 RAM 的开头肯定会导致问题。 您还应确保在启动 DMA 之前将 UCA0RXIFG 清零、因为它是边沿敏感的、因此在启用后只会在 UAC0RXIFG 上升沿触发。

    此致、
    Ryan