Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

i unable to read two adc channels(vref and external voltage) simultaneously please help

smeraj580

Newbie
Joined
Nov 23, 2023
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
63
Code:
int main(void)
{   
  Init_Prcs();
   while(1) 
 {       
        ADC_StartOfConversion(ADC1);
        while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_OVR));
   }
}

void Init_Prcs(void)
{ 
 SystemInit();
    SystemCoreClockUpdate();
    Hal_AdcInit();
}


void Hal_AdcInit(void)
{   
GPIO_InitTypeDef GPIO_InitStruct;
 ADC_InitTypeDef ADC_InitStruct;   
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); 
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;   
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA,&GPIO_InitStruct); 

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
   ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
  ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 
 ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward; 
 ADC_Init(ADC1,&ADC_InitStruct);
 
for(i=0;i<adc_max;i++) 
 {     
ADC_ChannelConfig(ADC1,CHANNELS,ADC_SampleTime_239_5Cycles); 
  } 

  ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);   
 ADC_VrefintCmd(ENABLE);   
ADC_Cmd(ADC1,ENABLE);   

while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
 
  NVIC_InitTypeDef NVIC_InitStructure;   
NVIC_InitStructure.NVIC_IRQChannel = ADC1_COMP_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPriority=0;   
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   
NVIC_Init(&NVIC_InitStructure);
}

void ADC1_COMP_IRQHandler(void)
{   
 while(ADC_GetITStatus(ADC1,ADC_IT_EOC)==RESET);   
 if(adc_ctr<=adc_max) 
  {        ADC_VAL[adc_ctr++]=ADC_GetConversionValue(ADC1);   
 }   
else       
 {           
 adc_ctr=0;     
  }

ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}



help me out what am i doing wrong here ?? please

[Code tags added by moderator]
 
Last edited by a moderator:
Some clues about the type of processor and the compiler might be useful. It is difficult to assess code when we don't even know what the device is and what you do with the code. I added code tags to reformat your code as originally sent, please wrap sections of code between < / > using the icon in the menu above the message window to preserve the indentation or the forum will strip it all out.

Brian.
 
yes its stm32f072 ide i am coo cox ide . okay i'll be careful next time onwards
please sir help me out with this i am stucked here since 5 days
 
Hi,

if you don´t want to waste time .. then please provide all informations at once.

It´s not clear
* how you connected the hardware
* what you try to do
* what you expect
* what information you need. Need help with wiring, with writing code, with compiler errors, with interpreting conversion results...??

I don´t understand at all what you mean by "simultaneously sampling two channels ARef and external voltage"
Usually an ADC has one or more analog input channels.
So I guess (and guessing is not a good thing here) that the "external voltage" is connected to an analog input to the ADC.
But ARef usually is the reference voltage for the ADC. It usually is not an analog input channel you can select to be converted into digital.
ARef is essential for every conversion.

And for "simultaneous" conversions you usually need two ADCs ... or at least two "sample and hold" channels. Is your microcontroller able to do simultaneous sampling on two analog input channels?

Klaus
 
hello there, my requirement is the code
Hardware is stm32f072c8t6 ide is coo cox coide USING Standard peripheral library
First of all i am trying to read two channels ADC_channel_0 and Vref_Channel , the provided code may not be understandable because i am beginner..
the adc_channel_0 is connected to port A pin 0 with an dc regulator and i am trying to read voltage reading from it and the other channel is vref_channel which is internal channel there is no dedicated gpio to it and in this i am trying to read the referance voltage okay....
individualy i was easily able to read both the channels ....but the further task is to create a buffer and store the values to the buffer according to the index like for index 0 it should store the reading of dc supply which i am providing on PA0 pin and for index 1 it should store reading of vref which is internal value of 1522 something in digital form... now the thing is the adc_startofconversation happens it generates an interrupt and in the handler i am trying to the store the value in a variable adc_val[adc_ctr] now what am i getting is continous Adc_channel_0 reading only which means i am not able to configure adc channel.....


now i need the logic for switching channels 1 by 1 and storing the channels reading in a buffer
tell whats wrong i am doing

code
:
static uint32_t CHANNELS[MAX]={ADC_Channel_0,ADC_Channel_Vrefint};
static uint32_t adc_max=2;

uint16_t ADC_VAL[2];
uint16_t static adc_ctr;
volatile uint16_t i;



/*********Main*********/

int main(void)
{
SystemInit();
SystemCoreClockUpdate();
Hal_AdcInit();

while(1)
{
ADC_StartOfConversion(ADC1);
}

}


this is the initialization of adc

void Hal_AdcInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitStruct);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1,&ADC_InitStruct);

for(i=0;i<MAX;i++)
{
ADC_ChannelConfig(ADC1,CHANNELS,ADC_SampleTime_239_5Cycles);
}

ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
ADC_VrefintCmd(ENABLE);
ADC_Cmd(ADC1,ENABLE);

while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ADC1_COMP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}



this is the handler
void ADC1_COMP_IRQHandler(void)
{
while(ADC_GetITStatus(ADC1,ADC_IT_EOC)==RESET);
if(adc_ctr<adc_max)
{
ADC_VAL[adc_ctr++]=ADC_GetConversionValue(ADC1);
}
Hal_AdcDeInit();
i++;
if(adc_ctr>=adc_max)
{
adc_ctr=0;
i=0;
}
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}
 
Just for future reference, there are parts out there that have dual SARs on them
that facilitate simultaneous sampling in HW, example (single chip) :

1700742151872.png


This only used a fraction of onchip resources, below is typical for this family of other
resources onchip, multiples in many cases :


1700742343165.png



Regards, Dana.
 
Hi,

again: please use the CODE button. symbol: [</>] ... (on mouse_over it says "CODE")

I´m still confused and don´t know what to recommend.

1) I don´t know why you want to read "VRefInt"
... and if you really want to convert VRefInt, then the ADC needs any other Reference to compare it with.
If you know what this means: Tell us wich other_reference you use to convert VRefInt.
If you don´t fully understand: Then read generl informations how an ADC works AND read your microcontroller´s datsheet ADC section.
In any case give links to the documents you use, tell us the sections/pages and use identical terminology. (just to avoid misunderstanding)

2)
i am trying to read the referance voltage
An ADC never reads the voltage (in the meaning that the result has the uint "Volt"). In most cases it tells the ratio (V_IN / VRef) * RESOLUTION. The unit is "LSB".
(dettails are given in the datasheet)

3) simultaneous.
.. means two channles at the same time. I just had a quick view on the datsheet ... I guess the microcontroller is not able to do simultaneous conversions.
--> If you think it is able to, then please tell us the document and section where this is mentioned.

4) your requirement is code.
.. but you posted a lot of code. What is wrong with it? Where is it from? Are there comiler errors? Are there other problems?

I´ll be back where there are clear informations, so I don´t need to guess.

Klaus
 
I see in your ISR you have variables that have not been declared as volatile,
which is proper practice for ISR handlers :



You also execute a while loop inside ISR, "normally" one wants to get in and out of
an ISR as fast as possible. And you call a f() inside ISR, which creates a lot of stack push,
eg. latency, delay, also not advised.


There is more on the web on this topic of ISR handlers....


Regards, Dana.
 
For clarification, the reason you usually can't measure Vref is because it is the voltage that sets the maximum reading of the ADC. For example if Vref is 2V you can only measure voltages up to 2V and 1V would be half reading. However, if Vref comes from an external source there are ways it can sometimes be read if you can switch the ADC's Vref to a different and higher voltage. I'm not sure how useful that would be when there is only one ADC though. It's a bit like using a ruler to measure its own length.

Brian.
 

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top