[MM32 eMiniBoard Review] Part 4: Questions about multi-channel ADC
[Copy link]
1. Introduction
This time I originally wanted to use ADC and send serial port data to the host computer, but I found that the official routine had already implemented it, so there was no point in writing it again. I saw that the official routine was in single-cycle scanning mode and only read one ADC at a time. I thought about changing it to multi-channel ADC and gave it a try. Then I started reading the official manual and began to modify the code.
2. Modify the routine
I first looked at the official manual and found that only one ADC1 can realize multiple channel conversion. I looked at the sliding resistors on the development board and they were on the PA1, PA4, and PA5 pins.
Then I looked at the logic and timing diagram of continuous scanning and roughly understood it.
Then I started to modify the code, changing the single-cycle scan to a continuous-cycle scan. It seems that it is okay not to modify it here, and then changed the serial port output to the collected ADC channel instead of the collected ADC voltage value. The code is as follows.
void ADC1_SingleChannel(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOA; //enable GPIOA clock
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //enableADC1clock
GPIOA->CRL &= ~(GPIO_CNF_MODE_MASK << GPIO_CRL_CNF_MODE_1_Pos);
GPIOA->CRL |= GPIO_CNF_MODE_AIN << GPIO_CRL_CNF_MODE_1_Pos;
RCC->APB2RSTR |= RCC_APB2RSTR_ADC1RST; //ADC1reset
RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADC1RST); //reset end
//ADC configure single soft trigger transform mode
ADC1->ADCFG |= ADCFG_ADCPRE_8 | ADCFG_ADCPRE_10; //8 fractional frequency
ADC1->ADCR &= ~(ADCR_ADMD_PERIOD | ADCR_ADMD_CONTINUE | ADCR_ALIGN_LEFT); //singleregister mode , Data right-justified
ADC1->ADCR |= ADCR_ADMD_CONTINUE;
ADC1->ADCHS = ADCHS_CHEN1 | ADCHS_CHEN4; //enable channel 1
ADC1->ADCFG |= ADCFG_ADEN;//ADC1enable
ADC1->ADCR |= ADCR_ADST;//Start Conversion
}
/////////////////////////////////////////////////////////////////////////////////
/// @brief getADC1 transform data
/// @param None
/// @retval None
/////////////////////////////////////////////////////////////////////////////////
u16 ADC1_SingleChannel_Get(void)
{
u16 puiADData;
//ADCR deviceADSTbit enable, soft start transform
ADC1->ADCR |= ADC_CR_ADST;
while(((ADC1->ADSTA ) & ADC_SR_ADIF) == 0);
ADC1->ADSTA |= ADC_SR_ADIF;
puiADData = ADC1->ADDATA & 0xfff;
return puiADData;
}
void ADC1_DoubleChannel_Get(u16 *adc_array)
{
u16 puiADData = 0;
//ADCR deviceADSTbit enable, soft start transform
ADC1->ADCR |= ADC_CR_ADST;
while(puiADData < 2)
{
while(((ADC1->ADSTA ) & ADC_SR_ADIF) == 0);
ADC1->ADSTA |= ADC_SR_ADIF;
adc_array[puiADData++] = (ADC1->ADDATA >> 16 & 0x0F);
}
}
But there has always been a problem. The value collected is always the ADC value of channel 4. It seems that some register is not configured properly, but I can't find it. The following is the content of the serial port output.
Once this problem is solved, we will start working on the host computer.
|