cancel
Showing results for 
Search instead for 
Did you mean: 

10 bit ADC manipulation

jps
Associate II
Posted on April 02, 2008 at 09:50

10 bit ADC manipulation

7 REPLIES 7
jps
Associate II
Posted on March 29, 2008 at 04:52

Hi,

I'm using a ST7LITE15B and I have to compare, in assembly, some voltage level to references. Could someone help me by giving an example on how to manipule the ADCDRH and ADCDRL registers to make comparaison between the 10 bit for ADC and the 8 bit accumulator A ?

fggnrc
Associate II
Posted on March 31, 2008 at 10:18

whitebull,

this forum contains some code snippets that use the 10-bit output from ADC...

Anyway, here is another one:

Code:

CLR X

LD A,ADCDRH

SLL A

RLC X

SLL A

RLC X

OR A,ADCDRL

this code works if the SLOW bit of ADCDRL is 0.

After the last instruction is executed, the register pair {X,A} holds the 10-bit ADC reading. The comparison should be an easy task for you...

Regards,

EtaPhi

wolfgang2399
Associate II
Posted on April 01, 2008 at 09:01

Hi whitebull, hi EtaPhi,

a clue to delve into the subject:

If you are using the 10 bit convertion without any extra precaution, you can get a significant error.

As per datasheet:

Set the ADON bit to enable the A/D converter and

 

to start the conversion. From this time on, the ADC

 

performs a continuous conversion of the selected

 

channel.

Consider that there might be a new conversion after reading ADCDRL and before reading ADCDRH - with unpredictable effects.

Abstract:

------------------------

LD A,ADCDRL ; value of conversion: 0x0010 - X=0x04, A=0x00

...

;!!!! new conversion !!!!!

...

OR A,ADCDRH ; new ADC value: 0x000F - x=0x03, A=0x03

; now you have X=0x04, A=0x03 and as result of the conversion ...

; ... you'll get 0x0013 instead of 0x00F or 0x010 !!!!!

------------------------

As workaround, I prefere to insert two while loops and take the two registers at one go.

Example:

---------------

conv_0: ; while ((ADCCSR.EOC) == 0);

BTJF ADCCSR,#7,conv_0

conv_L: ; do {...} while ((ADCCSR.EOC) == 1);

ld X,ADCDRH ; clears EOC-flag

ld A,ADCDRL

BTJT ADCCSR,#7,conv_L ; ADCCSR.EOC = 1 means: new conversion in the meantime

and A,#0x03

push A

ld A,X ; ADCDRH

pop X ; ADCDRL & 0x03

srl X

rrc X

rlc A

rlc X

rlc A

rlc X

---------------------------

Best regards,

WoRo

fggnrc
Associate II
Posted on April 01, 2008 at 09:59

Woro, your answer is very interesting...

In a previous post (

http://www.st.com/mcu/forums-cat-5455-1.html

) laubey gave me a different info: the ADCDRL and ADCDRH are updated only at the end of a conversion, so there are 14 TAdc clock cycles to read ADCDRL after ADCDRH (event that starts a new conversion).

What was your experience with the ADC in 10 bit sampling mode?

EtaPhi

wolfgang2399
Associate II
Posted on April 02, 2008 at 06:42

Hi again,

two additional ideas:

- first: even at the conversion time of 14 Tadc clock cycles you don't know, how long ago your conversion was finnished. So without any precaution it may have been done at 1,5,9 or any other number of cycles ago. Therefore Laubey says 'It is recommended to check the EOC bit before reading the data registers (ADCDRH and ADCDRL)'. But he don't say, how to check it reliably???

- Second: there may appear an interrupt just after you took the first part of your conversion... or even after you did check the EOC...

Other µCs stop the conversion after reading the first part of the conversion register or only do one conversion, when the EOC-flag has been cleared - but not so the ST7FLite. :( Therefore we have to take precaution. If not, I think - depending on the application - the fault rarely happens, but it may happen.

Regards,

WoRo

jps
Associate II
Posted on April 02, 2008 at 08:15

Thank you EtaPhi, thank you woro !

I'm a ''old'' developper familiar with 8 bits manipulation and with hardware. Software is not really my cup of tea and I try to do my best to use what these new families of controlers offer!

To solve the problem with the end of conversion, I work with a time base interrupt and a macro that I call when I read the ADC :

.fct_mes_ana

bres ADCCSR, #5

ld a, var_voie_ana

ld ADCCSR, A

bset ADCCSR, #5

mac_wait4adc

clr X

ld X, ADCDRL

ld A, ADCCRH

ret

the macro is :

mac_wait4adc MACRO

LOCAL wait

wait

btjf ADCCSR, #7, wait

MEN

Regards

whitebull 🙂

fggnrc
Associate II
Posted on April 02, 2008 at 09:50

woro, your hints are always precious!

I'm trying to summarize the conditions that are needed to read safely the 10 bit result from the ADC.

1- the conversion result has to be read when interrupts are disabled;

2- (optional) some devices (as is stated in their errata) need a fake reading before the real one because the first acquisition after power-up does not meet the acquisition error specification;

3- before the reading, the EOC bit must be set. This means that a wait loop often precedes the reading;

4- some SLL/RLC instructions are needed to transform the result in a 16 bit quantity;

whitebull, your code should be ok (provided that it executes inside the time-base interrupt).

My advice is however to read carefully the datasheet.

Regards

EtaPhi