F407双ADC模式DMA传输,DMA重启后不能传输

2019-07-20 22:56发布

F407双ADC模式DMA传输,DMA第一次启动后能传输完数据,再次启动后就不能传输数据了,AD还在采样,但触发不了DMA传输。
程序如下: [mw_shl_code=c,true]ADC配置: #include "adc.h" #include "delay.h" void Adc_Init(void) { //先初始化IO口 RCC->AHB1ENR|=1<<0; //使能PORTA口时钟 RCC->APB2ENR|=1<<8; //开启ADC1时钟 RCC->APB2ENR|=1<<9;//开启ADC2时钟 GPIO_Set(GPIOA,PIN1,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA1 anolog输入 GPIO_Set(GPIOA,PIN2,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA2 anolog输入 GPIO_Set(GPIOA,PIN3,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA3 anolog输入 RCC->APB2RSTR|=1<<8; //所有ADC复位 RCC->APB2RSTR&=~(1<<8);//复位结束 ADC->CCR=3<<16; //ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz ADC1->CR1=0; ADC1->CR2=0; ADC2->CR1=0; ADC2->CR2=0; ADC->CCR&=0XFFFFE0; //工作模式清零 ADC->CCR|=0X06<<0; //规则同步 ADC1->CR1|=0<<24; //12位模式,分辨率 ADC2->CR1|=0<<24; //12位模式 ADC->CCR&=~(3<<14); ADC->CCR|=2<<14;//多重ADC模式使用DMA // - - - - - - - - - - - - - - - - - - - - - - - - - --- - - - - -ADC1 - - - - - -// ADC1->CR1&=~(1<<8);//ADC1非扫描模式 //ADC1->CR1|=(1<<8);//ADC1扫描模式 ADC1->CR2&=~(1<<1);//单次转换 // - - - - - - - -- -- - - - - - -- - - - - - - - - - - -- - - -- ADC2 - - - - - - // ADC2->CR1&=~(1<<8);//ADC2非扫描模式 //ADC2->CR1|=(1<<8);//ADC2扫描模式 ADC2->CR2&=~(1<<1);//单次转换、、、、、、、、、、、 //- - - - - 规则通道组 - - - - -// ADC1->CR2&=~(15<<24); ADC1->CR2|=9<<24;//主ADC外部T4_CC4事件触发,即ADC1。。。 ADC2->CR2&=~(3<<28);//规则通道组从ADC软件触发,即ADC2。。。 ADC1->CR2&=~(3<<28); ADC1->CR2|=1<<28;//ADC1外部上升沿触发启动转换 ADC1->CR2&=~(1<<11);//右对齐 ADC1->SQR1&=~(0XF<<20);//ADC1规则通道序列长度 ADC1->SQR1|=0<<20;//1个转换(L[3:0]) ADC2->SQR1&=~(0XF<<20);//ADC2规则通道序列长度 ADC2->SQR1|=0<<20;//1个转换(L[3:0]) ADC1->SMPR2&=~(7<<6); ADC1->SMPR2|=7<<6;//2通道,采样480周期 ADC2->SMPR2&=~(7<<9); ADC2->SMPR2|=7<<9;//3通道,采样480周期 //- - - - - 注入通道组 - - - - -// ADC1->CR2&=~(3<<20);//注入通道组主ADC外部软件触发,采集内部温度 ADC2->CR2&=~(3<<20);//注入通道组从ADC软件触发,即ADC2。。。采集外部温度 ADC->CCR|=1<<23;//使能内部温度传感器 ADC2->CR2&=~(1<<11);//右对齐 ADC1->JSQR&=~(3<<20);//ADC1注入通道序列长度 ADC1->JSQR|=0<<20;//1个转换(L[3:0]) ADC2->JSQR&=~(3<<20);//ADC2注入通道序列长度 ADC2->JSQR|=0<<20;//1个转换(L[3:0]) ADC1->SMPR1&=~(7<<18); ADC1->SMPR1|=7<<18;//16通道,采样480周期 ADC2->SMPR2&=~(7<<3); ADC2->SMPR2|=7<<3;//1通道,采样480周期 //开启AD1转换 ADC1->CR2|=1<<0; ////开启AD2转换 ADC2->CR2|=1<<0; //- - - - - 设置规则通道组转换序列 - - - - -// ADC1->SQR3&=0XFFFFFFE0; ADC1->SQR3|=2; ADC2->SQR3&=0XFFFFFFE0; ADC2->SQR3|=3;//3通道 //- - - - - 设置注入通道组转换序列 - - - - -// ADC1->JSQR&=0XFFF07FFF; ADC1->JSQR|=(16<<15);//16通道,采集内部温度 ADC2->JSQR&=0XFFF07FFF; ADC2->JSQR|=(1<<15);//1通道,PA1 } DMA配置: #include "dma.h" #include "delay.h" //DMAx的各通道配置 //这里的传输形式是固定的,这点要根据不同的情况来修改 //从存储器->外设模式/8位数据宽度/存储器增量模式 //DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 //chxMA通道选择,范围:0~7 //par:外设地址 //mar:存储器地址 //ndtr:数据传输量 void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u8 chx,u32 par,u32 mar,u16 ndtr) { DMA_TypeDef *DMAx; u8 streamx; if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1 { DMAx=DMA2; RCC->AHB1ENR|=1<<22;//DMA2时钟使能 }else { DMAx=DMA1; RCC->AHB1ENR|=1<<21;//DMA1时钟使能 } while(DMA_Streamx->CR&0X01);//等待DMA可配置 streamx=(((u32)DMA_Streamx-(u32)DMAx)-0X10)/0X18; //得到stream通道号 if(streamx>=6)DMAx->HIFCR|=0X3D<<(6*(streamx-6)+16); //清空之前该stream上的所有中断标志 else if(streamx>=4)DMAx->HIFCR|=0X3D<<6*(streamx-4); //清空之前该stream上的所有中断标志 else if(streamx>=2)DMAx->LIFCR|=0X3D<<(6*(streamx-2)+16);//清空之前该stream上的所有中断标志 else DMAx->LIFCR|=0X3D<<6*streamx; //清空之前该stream上的所有中断标志 DMA_Streamx->AR=par; //DMA外设地址 DMA_Streamx->M0AR=mar; //DMA 存储器0地址 DMA_Streamx->NDTR=ndtr; //DMA 传输数据量 DMA_Streamx->CR=0; //先全部复位CR寄存器值 DMA_Streamx->CR&=0<<6; //外设到存储器模式 DMA_Streamx->CR|=0<<8; //非循环模式(即使用普通模式) DMA_Streamx->CR|=0<<9; //外设非增量模式 DMA_Streamx->CR|=1<<10; //存储器增量模式 DMA_Streamx->CR|=2<<11; //外设数据长度:32位 DMA_Streamx->CR|=2<<13; //存储器数据长度:32位 DMA_Streamx->CR|=1<<16; //中等优先级 DMA_Streamx->CR|=0<<21; //外设突发单次传输 DMA_Streamx->CR|=0<<23; //存储器突发单次传输 DMA_Streamx->CR|=(u32)chx<<25;//通道选择 //DMA_Streamx->FCR=0X21; //FIFO控制寄存器 //DMA_Streamx->CR|=1<<0; //开启DMA传输//////////////////// } //开启一次DMA传输 //DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 //ndtr:数据传输量 void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr) { DMA_Streamx->CR&=~(1<<0); //关闭DMA传输 while(DMA_Streamx->CR&0X1); //确保DMA可以被设置 DMA_Streamx->NDTR=ndtr; //DMA 存储器0地址 DMA_Streamx->CR|=1<<0; //开启DMA传输 } timer配置: #include "timer.h" void TIM4_PWM_Init(u32 arr,u32 psc) { RCC->APB1ENR|=1<<2;//TIM4时钟时能 RCC->AHB1ENR|=1<<3;//使能PORTD时钟 GPIO_Set(GPIOD,PIN15,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//复用功能,上拉输出 GPIO_AF_Set(GPIOD,15,15); TIM4->ARR=arr;//设置计数器自动重装载值 TIM4->SC=psc;//分频 //TIM4->CCMR2|=0<<8;//配置CH2为输出,开启TIM2的通道2为输出 TIM4->CCMR2|=7<<12;//CH4 PWM2模式,7代表PWM2模式 TIM4->CCMR2|=1<<11;//CH4预装载使能 TIM4->CCER|=1<<12;//OC4输出使能 TIM4->CCER|=1<<13;//OC4高电平有效 TIM4->CCR4=0x2710;////////////////////////设置占空比,计数值21000/2 //TIM1->BDTR|=1<<15; TIM4->CR1|=1<<7;//ARPE使能,即TIM4_ARR寄存器被装入缓冲器 TIM4->CR1|=1<<0; } 主程序: include "sys.h" #include "delay.h" #include "led.h" #include "usart.h" #include "dma.h" #include "timer.h" #include "adc.h" //ALIENTEK 探索者STM32F407开发板 实验1 //跑马灯实验 //技术支持:www.openedv.com //广州市星翼电子科技有限公司 u32 ADCData[4000]; int main(void) { u32 m=0; u32 num1=0; u32 num2=0; u16 t=0; // u16 i=0; // u32 temp=0; u8 PSD[12]; Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz delay_init(168); //初始化延时函数 LED_Init(); //初始化LED时钟 Adc_Init(); uart_init(84,115200); TIM4_PWM_Init(20999,0);//定时器频率为APB1的2倍,即84MHZ。(Stm32_Clock_Init函数里对APB14分频,即为42MHZ。分频系数为4,不为1 //故TIM4时钟为APB1的2倍)不分频。PWM频率=84000/(20999+1)=4KHZ MYDMA_Config(DMA2_Stream0,0,(u32)&ADC->CDR,(u32)ADCData,4000); MYDMA_Enable(DMA2_Stream0,4000); while(1) { if(DMA2->LISR&(1<<5)) { m++; LED0=!LED0; DMA2->LIFCR|=1<<5; while(DMA2->LISR&(1<<5)); num1=0; num2=0; //temp=0; for(t=0;t<4000;t++) { num2=(ADCData[t]&0xFFFF0000)>>16; num1=ADCData[t]&0xFFFF; sprintf((char*)PSD,"%04d %04d %04d ",num1,num2,t); printf(PSD); }////////////////////////////////////////4000个数据全部传输 printf(" "); printf(" "); printf(" over "); printf(" "); printf(" "); MYDMA_Enable(DMA2_Stream0,4000); } } } 求大神帮忙解惑!!![/mw_shl_code]

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。