stm32使用DMA传输9路ADC使用中断处理数据

使用中断方式的好处就是在其它地方不会调用到DMA传输BUF。如果不小心调用或修改,可能会死机。具体原因没有深究。

注意中断函数是否和.s文件里面一致,否则也会死机。

根据需求去修改中断函数内容。

dma_adc.h

#ifndef _DMA_ADC_
#define _DMA_ADC_

#include "sys.h"

#define ADC1_DR_Address ((u32)0x40012400+0X4C)

extern u16  ADC_buf[10];		//DMA传输BUF
extern u32  ADC_BUF[10];		//滤波后保存BUF

extern u8  ADC_BUF_flag;		//滤波后完成标志

 void ADC1_DMA_init(void);

#endif

dma_adc.c

#include "dma_adc.h"
#include "serial.h"
#include "nrf_info.h"
u16  ADC_buf[10];
u32  ADC_BUF[10];
u8  ADC_BUF_flag=0;
 void ADC1_DMA_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;	//通道引脚
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;	//通道引脚
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef	ADC_InitStructure;

	DMA_DeInit(DMA1_Channel1);
	
	
	NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* 配置DMA中断源*/
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	

	DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;	//ADC数据寄存器地址
	DMA_InitStructure.DMA_MemoryBaseAddr=(u32)ADC_buf;	//将ADC1_DR_Address数据转移到ADC_buf
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //数据传输方向,外设作为数据源
	DMA_InitStructure.DMA_BufferSize=9; //传输个数据
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址固定
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; //表示每个传输的的数据大小
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //循环传输
	DMA_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道优先级
	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //禁止内存到内存传输
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1,ENABLE);		//使能
	
	DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);  //配置DMA发送完成后产生中断
	
	
	
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
	ADC_InitStructure.ADC_ScanConvMode=ENABLE;	//扫描模式,用于多通道采集
	ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; //开启连续转换
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//b不使用外部触发转换
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//采集数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel=9;		//要转换的个数
	ADC_Init(ADC1,&ADC_InitStructure);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);	//6分频,12HZ
	
	//扫描顺序,55.5每个周期
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_4,5,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_5,6,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_6,7,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_7,8,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_8,9,ADC_SampleTime_55Cycles5);
	
	ADC_DMACmd(ADC1,ENABLE);	//向DMA发出请求
	
	ADC_Cmd(ADC1,ENABLE);
	
	ADC_ResetCalibration(ADC1);	//复位矫正寄存器
	
	while(ADC_GetResetCalibrationStatus(ADC1)); //等待矫正完成
	
	ADC_StartCalibration(ADC1);	//ADC矫正

	while(ADC_GetCalibrationStatus(ADC1));	//等待矫正完毕
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);	//软件触发ADC转换

	
}

static u8 count=0;


extern "C" void DMA1_Channel1_IRQHandler(void)		//DMA中断传输,并且处理数据。
{         
					if(ADC_BUF_flag==0)
					{
              if(count==0)
							{
								
									//AD清零
									for(int i=0;i<9;i++)
									{
										ADC_BUF[i]=0;
									}
							}
	
							for(int j=0;j<9;j++)
							{
								ADC_BUF[j]+=ADC_buf[j];
							}
							
							count++;

							if(count==30)
							{
								//取平均滤波
								for(int i=0;i<9;i++)
								{
										ADC_BUF[i]/=count;
										
								}
										//---------------------------------------拿到滤波值后------------
										nrf_info.ch1=((ADC_BUF[0]*256)/4096);
										nrf_info.ch2=((ADC_BUF[1]*256)/4096);
										nrf_info.ch3=((ADC_BUF[2]*256)/4096);
										nrf_info.ch4=((ADC_BUF[3]*256)/4096);
										nrf_info.ch5=((ADC_BUF[4]*256)/4096);
										nrf_info.ch6=((ADC_BUF[5]*256)/4096);
										nrf_info.ch7=((ADC_BUF[6]*256)/4096);
										nrf_info.ch8=((ADC_BUF[7]*256)/4096);
										//---------------------------------------发送数据-----------------
														if(nrf_info.send_mes())
													{
														//printf("send OK\r\n");
														PCout(13)=~	PCout(13);
													}
													else
													{
														PCout(13)=1;
														//printf("send ERROR\r\n");
													}
								
								count=0;
							  ADC_BUF_flag=1;
							}	
						}	
						//	printf("我进中断了\r\n");
						
              DMA_ClearITPendingBit(DMA1_IT_TC1);              
}

猜你喜欢

转载自blog.csdn.net/hes_c/article/details/79895712