STM32F103 ADC整理

                                          STM32F103 ADC整理

一、单通道配置模式

1.配置:PA4

void ADC1_CH4_Init()//PA4--ADC1-CH4
{
		GPIO_InitTypeDef GPIO_InitStructure;
		ADC_InitTypeDef ADC_InitStructure;
		NVIC_InitTypeDef NVIC_InitStructure;

		RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA, ENABLE );
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

		RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE );
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
		ADC_InitStructure.ADC_ScanConvMode = DISABLE;
		ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
		ADC_InitStructure.ADC_NbrOfChannel = 4;
		ADC_Init(ADC1, &ADC_InitStructure);
		RCC_ADCCLKConfig(RCC_PCLK2_Div8);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1,ADC_SampleTime_55Cycles5);
//		ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);//转换完成中断
		ADC_Cmd(ADC1, ENABLE);
		ADC_ResetCalibration(ADC1);
		while (ADC_GetResetCalibrationStatus(ADC1));
		ADC_StartCalibration(ADC1);
		while (ADC_GetCalibrationStatus(ADC1));
		ADC_SoftwareStartConvCmd(ADC1, ENABLE);
		NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
}

2.转换函数封装:

unsigned short Get_ADC1_Value(unsigned char CHx)   
{
	ADC_RegularChannelConfig(ADC1, CHx,1,ADC_SampleTime_239Cycles5 );	  			    
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
	return ADC_GetConversionValue(ADC1);
}
float Get_ADC1_Average(unsigned char ch,unsigned char times)
{
	unsigned int temp_val=0;
	unsigned char t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_ADC1_Value(ch);
	}
	temp_val= temp_val/times;
	return (float)temp_val/4096*3.3;
} 

3.测试输出:

void main()
{
  ...
  while (1)
  {
    delay_ms(500);
    ADC_ConvertedValue=Get_ADC1_Average(ADC_Channel_4,8);
    printf("Conver value is  %f,ADC_ConvertedValue);
  }
}

上面为最简单的单通道AD采样测试函数。


参数说明:

ADC_Mode:配置 ADC 的模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是
双模式,在双模式下还有很多细分模式可选
ScanConvMode:可选参数为 ENABLE 和 DISABLE,配置是否使用扫描。如果是单通
道 AD 转 换 使 用 DISABLE , 如 果 是 多 通 道 AD 转 换 使 用 ENABLE
ADC_ContinuousConvMode:可选参数为 ENABLE 和 DISABLE,配置是启动自动连续
转换还是单次转换。使用 ENABLE 配置为使能自动连续转换;使用 DISABLE 配置为单次
转换,转换一次后停止需要手动控制才重新启动转换

ADC_ExternalTrigConv:外部触发选择,可根据项目需求配置触发来源。实际上,我们一般使用软件自动触发。
ADC_NbrOfChannel: AD 转换通道数目,根据实际设置即可。 具体的通道数和通道的
转换顺序是配置规则序列或注入序列寄存器。
ADC 输入时钟 ADC_CLK 由 PCLK2 经过分频产生,最大是 14M。注意配置时钟时分频!!
 


二、独立模式多通道采集

解释:独立代表只适用ADC1,多通道就是读取多个通道,此模式需要适用DMA。适用场景:连续采集四个通道的ADC,比如PA4-PA7,那么可以DMA循环读取ad的值。

注意配置:

void ADC1_CH4_Init()//PA4--ADC1-CH4...
{
		GPIO_InitTypeDef GPIO_InitStructure;
		ADC_InitTypeDef ADC_InitStructure;
		NVIC_InitTypeDef NVIC_InitStructure;
		DMA_InitTypeDef DMA_InitStructure;
	
	
		RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA, ENABLE );
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

		RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
		DMA_DeInit(DMA1_Channel1);
		DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&( ADC1->DR ));
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_Buffer;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
		DMA_InitStructure.DMA_BufferSize = 4;
		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_M2M = DMA_M2M_Disable;
		DMA_Init(DMA1_Channel1, &DMA_InitStructure);
		DMA_Cmd(DMA1_Channel1 , ENABLE);	
	
		RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE );
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
		ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
		ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
		ADC_InitStructure.ADC_NbrOfChannel = 4;
		ADC_Init(ADC1, &ADC_InitStructure);
		RCC_ADCCLKConfig(RCC_PCLK2_Div8);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1,ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2,ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3,ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4,ADC_SampleTime_55Cycles5);
//		ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
		ADC_Cmd(ADC1, ENABLE);
		ADC_DMACmd(ADC1, ENABLE);
		ADC_ResetCalibration(ADC1);
		while (ADC_GetResetCalibrationStatus(ADC1));
		ADC_StartCalibration(ADC1);
		while (ADC_GetCalibrationStatus(ADC1));
		ADC_SoftwareStartConvCmd(ADC1, ENABLE);		
		
		NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
}

注意点:

1.DMA的读取buffer,DMA模式为循环模式,意思是一直接着传输,不停止。

2.ADC是多通道,所以扫描模式打开,并且设为联系转换模式。包括打开:ADC_DMACmd(ADC1, ENABLE);

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页