你(们)好
我想使用 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