关于STM32F0系列多路ADC单独采样数据相同问题的处理

先看一下,大家认为“正确”的代码

void MYADC_init(void) {
	//时钟使能
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	//GPIO配置
	GPIO_InitTypeDef PORT_ADC;
	PORT_ADC.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	PORT_ADC.GPIO_Mode = GPIO_Mode_AN;
	PORT_ADC.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &PORT_ADC);
	//ADC配置
	ADC_InitTypeDef ADC_InitStuctrue;
	ADC_InitStuctrue.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStuctrue.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStuctrue.ADC_ExternalTrigConv= ADC_ExternalTrigConvEdge_None;
	ADC_InitStuctrue.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStuctrue.ADC_ScanDirection = ADC_ScanDirection_Backward;
	ADC_Init(ADC1, &ADC_InitStuctrue);
	//ADC使能
	ADC_Cmd(ADC1, ENABLE);
}

unsigned short MYADC_getValue(unsigned char arg0) {
	if(arg0==1){
		ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
	}else if(arg0==2){
		ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);
	}else if(arg0==3){
		ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_239_5Cycles);
	}
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY) == RESET);
	ADC_StartOfConversion(ADC1);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

int main(void){
	//此处完成你的各种初始化
	MYADC_init();

	unsigned short adcValue1;
	unsigned short adcValue2;
	unsigned short adcValue3;
	while(1){
		adcValue1=MYADC_getValue(1);
		//此处加入程序,如将adcValue打印发送出来
		adcValue2=MYADC_getValue(2);
		//此处加入程序,如将adcValue打印发送出来
		adcValue3=MYADC_getValue(3);
		//此处加入程序,如将adcValue打印发送出来
	}
}

以上代码,是我之前认为“正确”的代码,但是当执行while时,一开始打印出来的3个值adcValue1,adcValue2和adcValue3都是正确的,但是后面继续打印的数据都是同adcValue3。

那是什么原因造成的吗?

原来,问题出在ADC_ChannelConfig()函数。

大家可以在STM32库源文件中找到如下图所示代码。




问题在于,库函数中对ADC通道选择寄存器的赋值用的是或“|”,当while(1)第一次执行该函数时,ADC_Channel=0x00000001,CHSELR=0x00000001,ADC转换数据对应第一通道,第二次执行该函数的时候,ADC_Channel=0x00000010,CHSELR=0x00000011,因为是独立采样模式,系统对高位有效通道进行采样,对应结果为第2通道的值。第三次执行该函数时,ADC_Channel=0x0000100,CHSELR=0x00000111,同样,因为是独立采样模式,对应结果为第3通道的值。在while再次循环时,我们预期结果希望是第一通道,但是实际上此时的CHSELR值已经是0x00000111了,在和0x00000001相或,值还是0x00000111,所以实际结果是最高位,即第3通道的值。


针对多通道单独采样模式,个人建议直接对CHSELR寄存器进行赋值,使用方法如下:

unsigned short MYADC_getValue(unsigned char arg0) {
	if(arg0==1){
		ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
		ADC1->CHSELR =ADC_Channel_1;
	}else if(arg0==2){
		ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);
		ADC1->CHSELR =ADC_Channel_2;
	}else if(arg0==3){
		ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_239_5Cycles);
		ADC1->CHSELR =ADC_Channel_3;
	}
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY) == RESET);
	ADC_StartOfConversion(ADC1);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}




猜你喜欢

转载自blog.csdn.net/mrlixirong/article/details/78930275