单通道ADC DMA丢失数据!!!

2019-07-21 02:30发布

[mw_shl_code=c,true]void Adc_Init(void) { //先初始化IO口 RCC->APB2ENR|=1<<8; //使能ADC1时钟 RCC->AHB1ENR|=1<<0; //使能PORTA时钟 GPIO_Set(GPIOA,PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU); //PA5,模拟输入,下拉 RCC->APB2RSTR|=1<<8; //ADCs复位 RCC->APB2RSTR&=~(1<<8); //复位结束 ADC->CCR=3<<16; //ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz ADC1->CR1=0; //CR1设置清零 ADC1->CR2=0; //CR2设置清零 ADC->CCR&=0XFFFFE0; //工作模式清零 ADC1->CR1|=0<<24; //12位模式 ADC1->CR1|=1<<8; //扫描模式 ADC1->CR2|=1<<1; //连续转换模式 ADC1->CR2&=~(1<<11); //右对齐 ADC1->CR2|=0<<28; //软件触发 ADC1->CR2|=1<<9; ADC1->SQR1&=~(0XF<<20); ADC1->SQR1|=0<<20; //1个转换在规则序列中 也就是只转换规则序列1 //设置通道5的采样时间 ADC1->SMPR2&=~(7<<(3*5));//通道5采样时间清空 ADC1->SMPR2|=7<<(3*5); //通道5 480个周期,提高采样时间可以提高精确度 ADC1->CR2|=1<<0; //开启AD转换器 ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch ADC1->SQR3|=5; ADC1->CR2|=1<<30; //启动规则转换通道 while(!(ADC1->SR&1<<1));//等待转换结束 } 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 存储器0地址 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|=1<<11; //外设数据长度:8位 DMA_Streamx->CR|=1<<13; //存储器数据长度:8位 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传输 //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传输 } u32 ADCData[500]; int main(void) { u16 i; u16 t=0; Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz delay_init(168); //延时初始化 uart_init(84,115200); //初始化串口波特率为115200 LED_Init(); //初始化LED Adc_Init(); //初始化ADC MYDMA_Config(DMA2_Stream0,0,(u32)&ADC1->DR,(u32)ADCData,500); MYDMA_Enable(DMA2_Stream0,500); ADC1->CR2|=1<<8; //使能DMA i=0; while(1) { if(DMA2->LISR&(1<<5)) { DMA2->LIFCR|=1<<5; while(DMA2->LISR&(1<<5)); } for(t=0;t<500;t++) { printf(" %d %d ",ADCData[t],t); i++; delay_ms(10); if(i==20) { LED0=!LED0;//提示系统正在运行 i=0; } } } } [/mw_shl_code] 大家帮忙看看!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
xuexianwei163
1楼-- · 2019-07-21 07:36
 精彩回答 2  元偷偷看……
xmetoo
2楼-- · 2019-07-21 10:20
程序写的不错啊。   这个DMA 我现在还在学习。
正点原子
3楼-- · 2019-07-21 16:02
帮顶....
坏男孩
4楼-- · 2019-07-21 18:25
回复【4楼】xuexianwei163:
---------------------------------
哥们你试试多通道,我的四个通道,循环模式,我看看你的是单次的,我的循环模式就进行一次,貌似是因为ADC的数据丢失(溢出)而导致的不在接受DMA请求
xuexianwei163
5楼-- · 2019-07-21 21:54
回复【5楼】坏男孩:
---------------------------------
恩。我的的确也是这个原因,不过已经解决了,呵呵
坏男孩
6楼-- · 2019-07-22 00:50
 精彩回答 2  元偷偷看……

一周热门 更多>