2024-04-07 09:01 AM - last edited on 2024-04-08 07:25 AM by SofLit
Hello All,
I am trying to implement baremetal implementation for Continous Conversion Mode. I have wrote the below code. I am expecting that the ADC will read A0-B0-A1-B0 in this sequence. However the code is only reading A0 and not any other pins.
I am using STM32F401RE nucleo Board.
I am not able to clear EOC as well!!
typedef struct{
float AN[4];
}ADC_Vals_t;
int main(void)
{
uint16_t data;
float ADC_volt;
ADC_Vals_t ADCVal;
int i=0;
/*Enable clock to GPIO peripheral*/
RCC->AHB1ENR|= (0x1<<RCC_AHB1ENR_GPIOAEN_Pos); //Enable GPIOA
RCC->AHB1ENR |= (0x1<<RCC_AHB1ENR_GPIOBEN_Pos); //Enable GPIOB
/*Set GPIO to Analog Mode*/
GPIOA->MODER |= (0x3<<GPIO_MODER_MODER0_Pos); // GPIO A0
GPIOA->MODER |= (0x3<<GPIO_MODER_MODER1_Pos); //GPIO A1
GPIOA->MODER |= (0x3<<GPIO_MODER_MODER4_Pos); //GPIO A4
GPIOB->MODER |= (0x3<<GPIO_MODER_MODER0_Pos); //GPIO B0
/*Enable clock to ADC peripheral*/
RCC->APB2ENR |=(0x1<<RCC_APB2ENR_ADC1EN_Pos);
/*Configure ADC trigerring and resolution*/
ADC1->CR2=0;
//Enable COntinous Mode
ADC1->CR2 |= (0x1<<ADC_CR2_CONT_Pos);
/*Set conversion sequence and length*/
ADC1->SQR1 |= (0x3<<ADC_SQR1_L_Pos); //Set length of sequence
ADC1->SQR3 |= (0x0 << ADC_SQR3_SQ1_Pos); //Set Sequence number ADC1_IN0
ADC1->SQR3 |= (0x8<<ADC_SQR3_SQ2_Pos); //ADC1_IN8
ADC1->SQR3 |= (0x1<<ADC_SQR3_SQ3_Pos); //ADC1_IN1
ADC1->SQR3 |= (0x4<<ADC_SQR3_SQ4_Pos); //ADC1_IN4
/*SCAN mode*/
ADC1->CR1 |= (1<<ADC_CR1_SCAN_Pos);
/*Enable ADC*/
ADC1->CR2 |=(0x1<<ADC_CR2_ADON_Pos);
for(;;){
/*Start conversion*/
ADC1->CR2 |= (1<<ADC_CR2_SWSTART_Pos);
/*Wait for conversion to end*/
while(!(ADC1->SR & 0x2));
/*REad Data*/
data = ADC1->DR;
/*Multiply with prescaler
* data is 12Bit resolution
*
* */
ADC_volt = ((3.3/4095)*data);
ADCVal.AN[i++] =ADC_volt;
if(i==4){
i=0;
}
}
}
2024-04-08 01:34 AM
Read again the ADC chapter of the reference manual. At least, I miss Calibration and ADC_CR_ADVREGEN_0 in your code. Using numbers and not the proprt defines obscures readlitity and enables more typos.
2024-04-08 01:43 AM
Things to research:
I also agree with comments of the previous post regarding readability. Best to be consistent with hex for most of the register data manipulations in my opinion. i.e. 0x01 << 3U rather than 1 << 3.
2024-04-08 07:22 AM
@Uwe Bonnes @###### Thanks for the feedback. I have udpated the code. In scan mode I am getting values that are not in expected sequence. Any suggestion for that?
Thank you
2024-04-08 07:58 AM
Are you now correctly reading sequenced vales? What sequence do you want?
Your comment and code don't seem to match in my opinion.
PA0 = ADC_IN0
PA1 = ADC1_IN1
PA4 = ADC1_IN4
PB0 = ADC1_IN8
ADC1->SQR3 |= (0x0 << ADC_SQR3_SQ1_Pos); //Set Sequence number ADC1_IN0 ADC1->SQR3 |= (0x8<<ADC_SQR3_SQ2_Pos); //ADC1_IN8 ADC1->SQR3 |= (0x1<<ADC_SQR3_SQ3_Pos); //ADC1_IN1 ADC1->SQR3 |= (0x4<<ADC_SQR3_SQ4_Pos); //ADC1_IN4
If your configuration of ADCs is correct the sequence should be A0, B0, A1, A4
Your question above requests the following:
"I am expecting that the ADC will read A0-B0-A1-B0 in this sequence."
2024-04-08 07:58 AM
Decipher the resulting sequence and re-check your actual register settings and compare to the reference manual.
2024-04-08 10:29 AM
@###### @Uwe Bonnes Thank you for the insights.
As you can see the code.
1.I switched to single sample mode.
2.I have enable the SCAN mode bit in the ADC1.
I expect that on each Start of conversion I read the ADC in the set sequence, however it is just sampling the samething. I am not clear,where am I getting it wrong.
Please guide me what can I check?
Thank you
2024-04-09 02:28 AM
I would check using a debugger that the ADC Peripheral registers are being written to as you expect. Sometimes peripherals need to be enabled before the register contents will accept changes.
Also I would ensure your sampling cycles are correct. This is the period to wait in clock cycles before a valid reading can be taken and is in the Sampling cycles in ADC->SMPRx registers.
Also, try reading AN3116 if you haven't already.
This gives a good description of the ADC modes and may help your understanding better.