View previous topic :: View next topic |
Author |
Message |
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Fri Oct 05, 2007 2:05 pm Post subject: ATTiny44 ADC reference selection |
|
|
Hi there (again!)
I am trying to change the ADC reference in Bascom for an ATTiny44.
If I use
Config Adc = Single , Prescaler = 16 , Reference = 0
or simply
Config Adc = Single , Prescaler = 16
then I can measure fine against the default VCC reference.
If I want to use the internal 1.1V reference, however, I can not get it to work. I have tried using
Config Adc = Single , Prescaler = 16 , Reference = internal_1.1
which will not compile
and also
Config Adc = Single , Prescaler = 16 , Reference = 2
which compiles fine, but does not give meaningful ADC results.
Does anyone have any ideas?
Also, assuming I can get the 1.1V reference to work in Bascom, can I change between the two references (VCC, and 1.1V) during my program using two sets of Config, Start, Stop statements? I am measuring external volts with reference to VCC and I would like to use the internal temperature sensor which according to the Atmel data sheet needs to use the internal 1.1V reference.
thanks in advance for any advice |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Fri Oct 05, 2007 4:41 pm Post subject: |
|
|
Hi,
This does select the internal 1.1V voltage reference.
Code: | Config Adc = Single , Prescaler = 16 , Reference = 2 |
(Click to enlarge)
To change the reference at run time see the ATtiny44 datasheet:
18.6 Changing Channel or Reference Selection
Just write the correct value into the ADMUX register.
Code: | ADMUX = &B00000000 'Set the bits where needed |
* * * *
Some CONFIG directives are intended to be used once. Config ADC is one of these.
See help file "CONFIG" to see which one can be changed at run time. (Reusable).
Best regards,
Luciano |
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Fri Oct 05, 2007 8:57 pm Post subject: |
|
|
Luciano wrote: | Hi,
This does select the internal 1.1V voltage reference.
Code: | Config Adc = Single , Prescaler = 16 , Reference = 2 |
(Click to enlarge)
To change the reference at run time see the ATtiny44 datasheet:
18.6 Changing Channel or Reference Selection
Just write the correct value into the ADMUX register.
Code: | ADMUX = &B00000000 'Set the bits where needed |
* * * *
Some CONFIG directives are intended to be used once. Config ADC is one of these.
See help file "CONFIG" to see which one can be changed at run time. (Reusable).
Best regards,
Luciano |
thanks Luciano, I am learning fast as I go - that makes some sense, but...
Looking at the datasheet, it seems correct that ADMUX needs to be set to &B1000xxxx (&H8x) for 1.1V internal reference, and that using
Config adc = single, reference = 2
changes ADMUX to &B1000 xxxx (&H8x) in the simulator. This does not explain why I don't get meaningful results from the ADC... I will check my maths and see if I can see why...
More importantly, if I want to switch ADC references during program execution using a manual ADMUX = &Bxxxx xxxx command, this does not help because when you use GetADC then it seems to overwrite all 8 bits of the ADMUX register...?
For instance, I would like to use the internal 1.1V reference to measure the internal temperature sensor. The Atmel datasheet describes this is 'ADC input 8" but a closer look at the data sheet shows that this does not mean ADMUX = &Bxxxx1000, in fact this is a 'reserved' code for differential measurements. It seems that what you need to do to use the internal temp sensor is to have ADMUX = &B1010 0010 (table 18-4 p151).
This means that Getadc(8 ) does not work for the temperature sensor..
OK I thought, I can use ADMUX = &B1010 0010 but then what getadc(x) do I use? I tried using getadc(2) which matches the lower nibble (0010) of the admux but when it calls the getadc command then the compiler resets the upper nibble back from my 1010 to 0000 Assuming Bascom does not support the new ATTINY temperature sensors yet, what I would like to do is set the ADMUX register manually and then be able to use the getadc(x) command without it resetting all 8 bits of the admux register. Is there any way to do this? Perhaps I need to write a new getadc in the lib, but that's a bit scary for a newbie like me
any advice gratefully received |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Fri Oct 05, 2007 9:33 pm Post subject: |
|
|
Hi,
See help file GETADC. (offset)
Run this code in the simulator:
Code: | $regfile = "attiny44.dat" 'regfile must match the chip
$crystal = 8000000 'crystal must match too
Config Adc = Single , Prescaler = 16
Dim Vadc as word
Start ADC
Do
Vadc = Getadc(5)
Vadc = Getadc(5,128) 'This will set bit7 of the ADMUX register
Loop
End |
Best regards,
Luciano |
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Fri Oct 05, 2007 10:34 pm Post subject: |
|
|
Luciano wrote: | Hi,
See help file GETADC. (offset)
Run this code in the simulator:
Code: | $regfile = "attiny44.dat" 'regfile must match the chip
$crystal = 8000000 'crystal must match too
Config Adc = Single , Prescaler = 16
Dim Vadc as word
Start ADC
Do
Vadc = Getadc(5)
Vadc = Getadc(5,128) 'This will set bit7 of the ADMUX register
Loop
End |
Best regards,
Luciano |
Hi again. Which help file do you refer to? I'm not sure I have that
I will try that and see..
Actually I just tried using
Code: |
ADMUX = &B0000 0101 'sets to VCC ref, input 5 for ext V measure
getadc(5) 'this seems to overwrite bits 0-5 of ADMUX anyway
ADMUX = &B1010 0010 'sets to 1.1V ref, input "8" for temp
getadc(34) 'this is equiv of 100010 for ADMUX0-5,which is needed for temperature measurement
|
This seems to work, well, sort of, I get meaningful measurements for my VCCref measurement, but the 'temp' measurements seem to vary from one to the next, but they seem to be sort of in the right range (230-250/1024 at room temperature). I wonder whether the start ADC and Stop ADC commands are important here, I have tried various combinations so far..
The simulator seems to suggest that when you use a getadc command, the compiler overwrites ADMUX0-5 but leaves 6 and 7 intact, but I'm not convinced this is working in practice..
hmm
thanks for the help so far... |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Fri Oct 05, 2007 10:51 pm Post subject: |
|
|
The Bascom AVR help file GETADC.
If you run the code of my last post in the Bascom simulator
you will see that with the parameter "offset" you can change
the voltage reference in the ADMUX register when you call
GETADC.
Best regards,
Luciano |
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Fri Oct 05, 2007 11:27 pm Post subject: |
|
|
Luciano wrote: | The Bascom AVR help file GETADC.
If you run the code of my last post in the Bascom simulator
you will see that with the parameter "offset" you can change
the voltage reference in the ADMUX register when you call
GETADC.
Best regards,
Luciano |
Ah yes I just downloaded latest helpfile I see it now.
OK, so for me I need to use VCC ref for measuring ext volts and 1.1V for internal temperature measurement. Using the getadc offset, to achieve this I should need:
Code: |
Vadc = Getadc(2 , 160) 'to turn on bits 7 and 5 = 128+32 of ADMUX, and select input '2' = &B1010 0010
|
The only trouble is this gives a different result depending on whether I precede it with
Code: |
Admux = &B10100010 '&HA2 = 1.1V ref, ip 34
|
If the offset is working correctly, it should have no effect (it is the same)
I also tried
Code: |
Vadc = Getadc(34, 128)
|
which gives same ADC results as
Code: |
Vadc = Getadc(2 , 160)
|
In both case the ADC results are quite wrong (readings around 448 instead of the expected 280-290 at room temperature)... |
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Sat Oct 06, 2007 1:15 pm Post subject: |
|
|
Hi,
Try the code below with real hardware.
The ADC prescaler must be 128 or 64.
Best regards,
Luciano
Code: | $regfile = "attiny44.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 16
$framesize = 40
Dim LSB_ADC As Byte 'ADC least significant byte
Dim MSB_ADC As Byte 'ADC most significant byte
Dim ADC_value As Word AT LSB_ADC OVERLAY 'ADC 10-bit value
Open "comb.0:9600,8,n,1" For Output As #1 'to display results
SET DIDR0.ADC5D 'Digital input buffer disabled on ADC5 pin
' (Optional, but reduces power consumption when digital input buffer not needed).
'*******************************************************
' ADC configuration
ADCSRA = &B10000111 'ADC enabled, prescaler = 128
ADCSRB = &B00000000
'*******************************************************
' Use this voltage divider for the test
'
' 4.7k 1k
' +5V----/\/\/\---+----/\/\/\---GND
' ¦
' ADC-------------+ <--- The voltage will be 0.877 volt
'
Do
ADMUX = &B00000101 'Voltage Reference=VCC Input ch.= 5
Set ADCSRA.ADSC 'Start conversion
While ADCSRA.ADSC = 1
'Wait conversion to complete
Wend
LSB_ADC = ADCL 'Get least significant byte
MSB_ADC = ADCH 'Get most significant byte
Print #1 , "ADC Ref +5V = " ; ADC_value
ADMUX = &B10000101 'Voltage Reference=Internal 1.1V Input ch.= 5
Set ADCSRA.ADSC 'Start conversion
While ADCSRA.ADSC = 1
'Wait conversion to complete
Wend
LSB_ADC = ADCL 'Get least significant byte
MSB_ADC = ADCH 'Get most significant byte
Print #1 , "ADC Ref +1.1V = " ; ADC_value
Waitms 1000
Loop
End
|
|
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Sat Oct 06, 2007 10:12 pm Post subject: |
|
|
thank you luciano I will try that and report back |
|
Back to top |
|
|
jasreb
Joined: 03 Dec 2004 Posts: 41
|
Posted: Sun Oct 14, 2007 12:44 am Post subject: |
|
|
Thanks Luciano, doing it manually seems to do the trick. Not only that, but I can now read the temperature sensor as well
Hopefully these features will be supported directly in future versions of Bascom..
this is the code:
Code: | $regfile = "attiny44.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 16
$framesize = 40
' v2 working ADC volts @ 5V ref for vbatt, and working temp with 1.1V reference 13/10/07
Dim Lsb_adc As Byte 'ADC least significant byte
Dim Msb_adc As Byte 'ADC most significant byte
Dim Adc_value As Word At Lsb_adc Overlay 'ADC 10-bit value
Dim Setadc As Byte 'byte to put in ADMUX
Open "comb.0:9600,8,n,1" For Output As #1 'to display results
Set Didr0.adc5d 'Digital input buffer disabled on ADC5 pin
' (Optional, but reduces power consumption when digital input buffer not needed).
'*******************************************************
' ADC configuration
Adcsra = &B10000111 'ADC enabled, prescaler = 128
Adcsrb = &B00000000
'*******************************************************
Do
'*******************************************************
Setadc = &B00000101 'Voltage Reference=VCC Input ch.= 5
Gosub Adcread
Print #1 , "Ext V (ADC Ref +5V) = " ; Adc_value
Waitms 1000
'*******************************************************
Setadc = &B00100010 'Voltage Reference=VCC Input ch.= temp
Gosub Adcread
Print #1 , "Temp (ADC Ref +5V) = " ; Adc_value
Waitms 1000
'*******************************************************
Setadc = &B10100010 'Voltage Reference=1.1V Input ch.= temp
Gosub Adcread
Print #1 , "Temp (ADC Ref +1.1V) = " ; Adc_value
Waitms 5000
'*******************************************************
Loop
'*******************************************************
Adcread:
Admux = Setadc 'setup ADC ref and input
Set Adcsra.adsc 'Start conversion
While Adcsra.adsc = 1
'Wait conversion to complete
Wend
Lsb_adc = Adcl 'Get least significant byte
Msb_adc = Adch 'Get most significant byte
Waitms 50
Return
'*******************************************************
Close #1
End |
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|