2008-04-02 12:50 AM
2008-03-28 08:52 PM
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 ?2008-03-31 01:18 AM
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, EtaPhi2008-04-01 12:01 AM
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 andto 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
2008-04-01 12:59 AM
Woro, your answer is very interesting...
In a previous post () 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? EtaPhi2008-04-01 09:42 PM
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, WoRo2008-04-01 11:15 PM
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 :)2008-04-02 12:50 AM
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