First look at the code that people think is "right"
void Myadc_init (void) {//Clock enable Rcc_ahbperiphclockcmd (RCC_AHBPERIPH_GPIOA, enable);
Rcc_apb2periphclockcmd (RCC_APB2PERIPH_ADC1, ENABLE);
GPIO configuration 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 configuration 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 Enable Adc_cmd (ADC1, enable); } unsigned short myadc_getvalue (unsigned char arg0) {if (arg0==1) {adc_channelconfig (ADC1, Adc_channel_1, Adc_sampleti
Me_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) {///here to complete your various initialization myadc_init ();
unsigned short adcValue1;
unsigned short adcValue2;
unsigned short adcValue3;
while (1) {adcvalue1=myadc_getvalue (1);
Add a program here, such as Send Adcvalue print out adcvalue2=myadc_getvalue (2);
Add a program here, such as Send Adcvalue print out adcvalue3=myadc_getvalue (3); Add a program here, such as Send Adcvalue print out}}
The code above is the code I thought was "correct", but when you execute while, the 3 values adcvalue1,adcvalue2 and AdcValue3 are correct at the beginning of the print, but the data that continues to print is the same as adcValue3.
What is the cause of that?
It turns out that the problem is in the Adc_channelconfig () function.
You can find the code in the STM32 library source file as shown in the following figure.
The problem is that the value assigned to the ADC channel selection register in the library function is or "|", and when the function is first executed while (1), the ADC_CHANNEL=0X00000001,CHSELR=0X00000001,ADC transforms the data to the first channel, The second time the function is executed, adc_channel=0x00000010,chselr=0x00000011, because it is the independent sampling mode, the system to the high-efficient channel sampling, the corresponding result is the value of the 2nd channel. The third time the function is executed, adc_channel=0x0000100,chselr=0x00000111, again, because it is an independent sampling mode, the corresponding result is the value of the 3rd channel. In the while loop again, we expect the result to be the first channel, but in fact at this time the CHSELR value is already 0x00000111, in and 0x00000001 phase or, the value is 0x00000111, so the actual result is the highest, that is, the value of the 3rd channel.
for multi-channel individual sampling mode, the personal recommendation is to assign the CHSELR register directly, using the following method:
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);
}