您好!
勘误表中没有提到有关 DMA 的任何内容。 因此、我想知道我应该如何使 DMA 在被停止并重新启用后正常工作。
上下文:
-使用 ADC MEM0转换通道1。 ADC 每312.5us 由 TimerA0触发一次。
-使用 DMA 将64个连续结果移动到 SRAM 中的缓冲区。 DMA 工作正常。
-在64次传输后禁用 DMA
-使用 ADC MEM0转换通道2一次
-重新启用 DMA
-再次使用 ADC MEM0转换通道1。 使用 DMA 将64个连续结果移动到 SRAM 中的缓冲区。 此时 DMA 不起作用(没有传输发生)。
下面是我使用的代码。
#include
#include
#define transfer_size 64
unsigned int result_a3=0;
unsigned int result_array[100];
void InitClock ()
{
//时钟系统设置
CSCTL0_H = CSKKEY_H; //解锁 CS 寄存器
CSCTL1 = DCOFSEL_0; //将 DCO 设置为1MHz
// CSCTL2 = SELA_LFMODCLK | SELESS__DCOCLK | SELM_DCOCLK;
//设置 ACLK = 32kHz 晶振、SMCLK = MCLK = DCO
CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
//每个器件勘误表在将频率更改为之前将分频器设置为4
//防止因过冲瞬态而超出规格运行
CSCTL3 = DIVA__4 | DIVM_4;//针对勘误表将所有相应的时钟源设置为4分频
CSCTL1 = DCOFSEL_3; //将 DCO 设置为4MHz
//延迟~10us 以使 DCO 稳定。 60个周期= 20个周期缓冲器+(10us /(1/4MHz))
_DELAY_CYCLES (100);
CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;// MCLK = 4MHz、SMCLK = 4MHz、ACLK = 4MHz
CSCTL0_H = 0; //锁定 CS 寄存器
}
空 InitTimer()
{
/*
TA0CCR0 = 1249;
TA0CCTL1 = OUTMOD_3;// TACCR1输出模式=设置/复位
TA0CCR1 = 1200; // TACCR1 PWM 占空比
TA0CTL = tassel_SMCLK | MC__UP; // SMCLK,向上计数模式*/
TA0CCTL0 = CCIE; //启用 TACCR0中断
TA0CCR0 = 1249; // ADC 的触发周期为312.5us =(4MHz/3200)
TA0CCTL1 = OUTMOD_3;// TACCR1输出模式=设置/复位
TA0CCR1 = 1200; // TACCR1是 ADC 的触发源
TA0CTL = tassel_SMCLK | MC__UP; // SMCLK,向上计数模式
}
void InitDMA()
{
/*
//配置 DMA 通道0
__data20_write_long ((uintptr_t)&DMA0SA、(uintptr_t) 0x1C20);
//源块地址
__data20_write_long ((uintptr_t)&DMA0DA、(uintptr_t) 0x1C40);
//目标单个地址
DMA0SZ = 16; //块大小
DMA0CTL = DMADD_5 | DMASRCINCR_3 | DMADSTINCR_3;// Rpt、inc *
DMACTL0 |= DMA0TSEL__ADC12IFG;
__data16_write_addr ((unsigned short)&DMA0SA、(unsigned long)&ADC12MEM0);
__data16_write_addr ((无符号短整型)&DMA0DA、(无符号长整型)&Result_array[0]);
DMA0SZ = transfer_size; // 64次转换
DMA0CTL = DMADD_4 + DMADSTINCR_3 + DMAEN;
}
void InitADC ()
{
P1SEL1 |= BIT3 + BIT4; //为 ADC 光传感器配置 P1.3 (A3)、为 ADC 电池电压配置 P1.4 (A4)
P1SEL0 |= BIT3 + BIT4;
ADC12CTL1 = 0;
ADC12CTL0 = 0;
ADC12CTL0 |= ADC12ON;//打开。 无采样或转换开始
ADC12CTL1 = ADC12PDIV__1
+ ADC12SH_1 // TA0 CCR1触发转换
+ ADC12SHP
+ ADC12CONSEQ_2;//重复单通道
ADC12CTL2 = ADC12RES_12位;
ADC12CTL3 = 0;//起始地址= MEM0
ADC12LO = 0; //比较器高阈值和低阈值
ADC12HI = 0x0FFF;
ADC12IFGR0 = 0; //清除所有挂起标志(如果有)
ADC12IFGR1 = 0;
ADC12IFGR2 = 0;
ADC12IER0 = 0;//中断被禁用
ADC12IER1 = 0;
ADC12IER2 = 0;
ADC12MCTL0 = ADC12EOS //序列结束
+ ADC12INCH_4;// A4单端
ADC12CTL0 |= ADC12ENC;//启用转换
}
void initio()
{
//配置 GPIO
P1OUT = 0;
P1DIR = BIT0|BIT5; //表示 LED
//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
}
//**
* main.c
*/
int main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止 WDT
InitClock();
initio();
P1OUT|= BIT5;
InitADC();
InitTimer();
InitDMA ();
//_ bis_SR_register (LPM0_bits + GIE); //输入带中断的 LPM0
// while ((ADC12IFGR0 & ADC12IFG0)=0);//等待转换完成
while (((DMA0CTL & DMAIFG)=0);//等待传输完成
_NOP();
DMA0CTL &=~DMAEN; //禁用 DMA0
//停止任何挂起的转换
ADC12CTL1 = 0;
ADC12CTL0 = 0;
_NOP();
//选择 A3
ADC12CTL0 |= ADC12ON;//打开。 无采样或转换开始
ADC12CTL1 = ADC12PDIV__1
+ ADC12SH_0 // SW 触发转换
+ ADC12SHP
+ ADC12CONSEQ_0;//单通道、单次转换
ADC12IFGR0 = 0; //清除所有挂起标志(如果有)
ADC12IFGR1 = 0;
ADC12IFGR2 = 0;
ADC12IER0 = 0;//中断被禁用
ADC12IER1 = 0;
ADC12IER2 = 0;
ADC12MCTL0 = ADC12EOS //序列结束
+ ADC12INCH_3;// A3单端
ADC12CTL0 |= ADC12ENC | ADC12SC;//启用并开始转换
while (((ADC12IFGR0 & ADC12IFG0)=0);//等待转换完成
RESULT_A3 = ADC12MEM0;
_NOP();
P1OUT&=~BIT4;
ADC12IFGR0 = 0; //清除所有挂起标志(如果有)
ADC12IFGR1 = 0;
ADC12IFGR2 = 0;
//重新初始化 DMA
DMACTL0 |= DMA0TSEL__ADC12IFG;
DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN;
InitADC();
while (((DMA0CTL & DMAIFG)=0);//等待传输完成
_NOP();
while (1);
}