单片机型号MSP430FR6972
我想用ADC序列通道采样,通道0-1,触发DMA,把ADC采样的数据存到flash里去。单片机打断点的情况下,定时器每次触发ADC采样后,flash里更新了一个采样值,但是,实际情况是,采样完1s的数据,我看内存中的数据,两两是相同的,如下图,
给我的感觉像两个ADC12IFGx标志触发了DMA,但是pdf也写了,由最后的ADC12IFGx触发DMA,
不知道是不是还需要别的设置。
做过的测试:
1.保留DMA0,注释DMA1,0-1通道序列采,值还是两两重复的。
2.保留DMA0,注释DMA1,0通道序列采样,值是正常的。
3.保留DMA0,注释DMA1,0-1通道单次序列采,flash里更新了两个值,的确触发了两次。
ADC和DMA配置如下:
void startADC(void) {while(REFCTL0 & REFGENBUSY);// If ref generator busy, WAITREFCTL0 |= REFVSEL_2 | REFON;// Select internal ref = 2.5V// Internal Reference ON// Configure ADC12ADC12CTL0 = ADC12ON | ADC12SHT0_2;// Turn on ADC12, set sampling time 16 ADC12CLKADC12CTL1 = ADC12SHP |ADC12SHS_1 | ADC12CONSEQ_3 ; // Timer_A TA0 CCR1触发采样,序列通道采样 0-1ADC12CTL3 = ADC12CSTARTADD_0;ADC12MCTL0 = ADC12INCH_2 | ADC12VRSEL_1 ;ADC12MCTL1 = ADC12INCH_3 | ADC12VRSEL_1 | ADC12EOS;//ADC12IER0 = ADC12IE1;ADC12CTL0 |= ADC12ENC | ADC12SC;// Configure DMA channel 0__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0);// Source block address__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) 0x10000);// Destination address 0x10000DMA0SZ = 4000;// Block sizeDMACTL0 |= DMA0TSEL_26;//触发源选择ADC12采样完成DMA0CTL = DMADT_4 | DMASRCINCR_0 | DMADSTINCR_3; // Rpt, incDMA0CTL |= DMAEN;// Enable DMA0// Configure DMA channel 1__data16_write_addr((unsigned short) &DMA1SA,(unsigned long) &ADC12MEM1);// Source block address__data16_write_addr((unsigned short) &DMA1DA,(unsigned long) 0x12000);// Destination address 0x12000DMA1SZ = 4000;// Block sizeDMACTL0 |= DMA1TSEL_26;//触发源选择ADC12采样完成DMA1CTL = DMADT_4 | DMASRCINCR_0 | DMADSTINCR_3; // Rpt, inc//DMA1CTL |= DMAEN;// Enable DMA1 }
Butterfly:
DMA有字节,字以及混合字节和字的搬运模式
给一个1C20-1C2Fh DMA搬到 1C40h-1C4fh的例子
int main(void){ WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Configure GPIO P1OUT = 0; P1DIR = BIT0; // For LED
// Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5;
// Configure DMA channel 0 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) 0x1C20); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) 0x1C40); // Destination single address DMA0SZ = 16; // Block size DMA0CTL = DMADT_5 | DMASRCINCR_3 | DMADSTINCR_3; // Rpt, inc DMA0CTL |= DMAEN; // Enable DMA0
while(1) { P1OUT |= 0x01; // P1.0 = 1, LED on DMA0CTL |= DMAREQ; // Trigger block transfer P1OUT &= ~0x01; // P1.0 = 0, LED off }}
m:
请问一下楼主是怎么把DMA目标地址(就是0x10000)中的数据读出来写入文件的?
aimin hou:
回复 m:
用指针啊,改一下数据类型,让编译器变成20位指针地址,然后就可以指向0x10000的地址了。
aimin hou:
回复 m:
用指针啊,改一下数据类型,让编译器变成20位指针地址,然后就可以指向0x10000的地址了。
m:
回复 aimin hou:
是在DMA中断里面吗?当目标地址数据达到DMA0SZ时触发中断,然后通过指针读取数据?能不能看一下你的具体代码
aimin hou:
回复 m:
早就不用这个方案了,后来没用DMA了,用我这边的配置的话,就是定时器触发触发ADC采样,ADC采样完成又触发DMA 将采样结果转存至0X10000-0X12000的地址 。不知道你具体有什么样的需求,
m:
回复 aimin hou:
基本也是这样,定时器触发ADC连续采样,然后把数据通过DMA发到RAM,到达一定量后读取并写入SD卡
chaofeng zhao:
回复 m:
help,pls, i wanna us adc on msp432 to sample data and transfer to sd card via spi ,how should i do,is there any example code?
aimin hou:
回复 chaofeng zhao:
不是有官方的demo 嘛,现成的代码,当然没有。我之前也稍微用了一下msp432,感觉还是有很多区别的。自己多试试,在官方的demo上修改