cancel
Showing results for 
Search instead for 
Did you mean: 

multichannel ADC

danielfischer9
Associate II
Posted on July 01, 2010 at 01:39

Hello all,

The analog to digital example provided, ADC, uses 1 analog channel (channel 9) only.  I am working on an application and need to convert 2 voltage channels.

1) is there a way to set up the A/D to cause an interrupt when 2 channels have been converted.  If yes, could someone provide the setup C sequence and the interrupt service routine C sequency (ADC example has the setup in main.c and interrupt service routine in stm8s_it.c).  I have found a SCAN bit in ADC_CR2 (Ref. Manual), presumably channel can be scanned; no info on which/the order of the scanned analog channels; how do I select say, ch 8 and ch 9 for scanning?

2) if the above cannot be done automatically, do I have to select the next channel in the interrupt service routine of the timer, and read the A/D in its interrupt handler; if you could provide the C sequence, that would be great.

3) There are a number of data buffer registers located in the memory range 53E0 to 53F3 (according to the Reference manual 14587.pdf).  I looked with the debugger and all these registers seem to be stuck on 0 (zero).  According to the ADC example, the value to be read for the conversion is in the data register high and low ADC_DRH and DRL.  I found a bit DBUF, in conf register 3 of the AD1, which presubably would enable the buffers.  My question is, why would one NOT want the buffer registers ALWAYS enabled; I would like to get the result of channel conversion in the appropriate buffer registers (0-9), rather than in one single register, and having to figure out which channel value is in this register; just wondering...

Daniel

#eoc #adc #no-interrupt
3 REPLIES 3
spiovan9
Associate II
Posted on July 01, 2010 at 09:58

Hi Daniel,

I realized a tiny datalogger with 2 ADC channels (8 and 9), 4 DIN and 4DOUT (see the forum thread I posted up yesterday). It runs at the same samplig time of about 2 mseconds as the provided Discovery ADC application.

The commutation between the two channel is done by simply switching on the fly from a channel (i.e. 8)  to the other channel (i.e. 9) as soon the previous sample is acquired.

Stefano

brazov22
Associate II
Posted on July 02, 2010 at 19:48

Hi,

1) Yes, when you use scan conversion you can configure the ADC in order to get an interrupt at the end of the SCAN conversion. The info on how scan channels are converted is in the Application Note of STM8S ADC; ADC converts from channel 0 to channel X where channel X can be selected trough configurations bits. So if you want to use SCAN it's better you use Channel 0 and Channel 1 where X is 1.

2) Yes, see Daniel's answer.

3) I think old ST7 ADC didn't have buffered registers (you can enable it by configuration register bit), so conversion using only one ADC data registers has been left for compatibility.

brazov

spiovan9
Associate II
Posted on April 12, 2011 at 22:22

Hi,

In the followings an example (tested) on how to ADC scan 8 channels [0..7] without interrupt.

Hope it helps

Bye

// ADC1 Initialization

// ===================

// Port C[0..7]=floating input no interr

GPIO_Init(GPIOB, GPIO_PIN_ALL, GPIO_MODE_IN_FL_NO_IT);

// Deinit ADC

ADC1_DeInit();

// Single conversion mode, up to channel 7 (see scan mode below)

 ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, 

ADC1_CHANNEL_7, ADC1_PRESSEL_FCPU_D2, 

ADC1_EXTTRIG_TIM, DISABLE, 

ADC1_ALIGN_RIGHT, 

ADC1_SCHMITTTRIG_ALL, DISABLE);

// Scan mode from channel 0 to 7 (as defined in ADC1_Init)

ADC1_ScanModeCmd(ENABLE);

// Enable the ADC: 1 -> ADON for the first time it just wakes the ADC up

ADC1_Cmd(ENABLE);

...

In the code part which calls for conversion...

// ADON = 1 for the 2nd time => starts the ADC conversion of all channels in sequence 

ADC1_StartConversion();

// Wait until the conversion is done (no timeout => ... to be done)

while ( ADC1_GetFlagStatus(ADC1_FLAG_EOC) == RESET );

// EOC <- 1 then retrieves data from ADC buffers

for (i=0; i<8; i++)

    

ProcImage[8+i] = (unsigned int)ADC1_GetBufferValue(i); // 10 bit

// SW Clear the EOC flag to get the ADC ready for the next start conversion command

ADC1_ClearFlag(ADC1_FLAG_EOC);