基于DMA 控制STM32F407两(多)路AD通道配置

基于DMA 控制STM32F407两(多)路AD通道配置

      本文完整代码下载地址: http://download.csdn.net/detail/edroid1530/9682662
      在用 STM32 做开发或学习的时候难免需要同时采集多路 AD 信号,在此仅以两路 AD 配置为例,多路 AD 按照相同的方法配置。

    我想阅读此文的朋友对于ADC单通道配置都应该已经没有问题了,所以也就不啰嗦单通道配置过程,直接列出双通道配置不同的地方。关于双通道配置特殊部分给出注释。

说明

 实验现象:用stm32的PA4,PA6分别采集不同的电压信号(我以PA4采集高电平3.3V电压,PA6采集低电平0V为例)。将低电平电压值保存在LowValue数                      组中,高电平电压值保存在HighValue数组中。并通过串口输出到屏幕。如图:

                         


ADC配置

Tips:

1.    配置两(多)个输入引脚

1.    开启扫描模式

2.    开启连续转换

3.    设定AD转换通道数为2

4.    分别配置各通道先后顺序


void ADC_config(void)
{

  ADC_InitTypeDef       ADC_InitStructure;
 
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
 
  GPIO_InitTypeDef      GPIO_InitStructure;
  
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_4;//配置PA6、PA4为输入通道	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;  
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	

  RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);
	
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);  	
 
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
  
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
  
  ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
  
  ADC_CommonInit(&ADC_CommonInitStructure);
 
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 
  
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//开启扫描模式
  
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换
  
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
												
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  
  ADC_InitStructure.ADC_NbrOfConversion = 2;//设定AD要转换的通道数目
  
  ADC_Init(ADC1, &ADC_InitStructure);


/*******配置ADC1的通道6和通道4的转换先后顺序以及采样间隔时间为15个采样周期*******/  
 ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_15Cycles);
 ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_15Cycles);
 

  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

  ADC_DMACmd(ADC1, ENABLE);  

  ADC_Cmd(ADC1, ENABLE);
  
  ADC_SoftwareStartConv(ADC1);

}

2  DMA配置

Tips:

                i.         设定要转换的DMA通道数目

               ii.         内存地址增量模式

void DMA_config(void)
{
  DMA_InitTypeDef      DMA_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_DeInit(DMA2_Stream0);
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCvalue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 2;	//设定要转换的DMA通道数目
  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_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);         

}

3.中断服务程序
//溢出时间Tout = (period*prescaler)/Tclk,Tclk=84Mhz,这里设置采样率为2KHz  
void TIM3_Config(void)
{
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //84MHz 
	
  TIM_TimeBaseInitStructure.TIM_Period = 500-1; 	
	TIM_TimeBaseInitStructure.TIM_Prescaler =84-1 ;  
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 
	TIM_Cmd(TIM3,ENABLE); 
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; 
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}
//DirectValue PA4  
//CurrentValue PA6  
void   TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) 
	{
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

		if(count<=100)
		{			
		 turn_led(LED_Red,ON);
         //ADC通道4采样的数据通过DMA通道0送到数组CurrentValue中保存
		 CurrentValue[count] = (float)ADCvalue[0];
         //ADC通道6采样的数据通过DMA通道1送到数组DirectValue中保存  
		 DirectValue[count] = (float)ADCvalue[1];
		 count++;
		}
		else
	  {
		 count=0;
		 turn_led(LED_Red,OFF);
		 TIM_Cmd(TIM3,DISABLE);
		}		
	}
}





  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值