Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

ATTiny44 ADC reference selection

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive
View previous topic :: View next topic  
Author Message
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Fri Oct 05, 2007 2:05 pm    Post subject: ATTiny44 ADC reference selection Reply with quote

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 Wink
Back to top
View user's profile
Luciano
member
member


Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri Oct 05, 2007 4:41 pm    Post subject: Reply with quote

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
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Fri Oct 05, 2007 8:57 pm    Post subject: Reply with quote

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 Crying or Very sad 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 Rolling Eyes

any advice gratefully received Wink
Back to top
View user's profile
Luciano
member
member


Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri Oct 05, 2007 9:33 pm    Post subject: Reply with quote

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
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Fri Oct 05, 2007 10:34 pm    Post subject: Reply with quote

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 Crying or Very sad

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

Rolling Eyes

thanks for the help so far...
Back to top
View user's profile
Luciano
member
member


Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Fri Oct 05, 2007 10:51 pm    Post subject: Reply with quote

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
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Fri Oct 05, 2007 11:27 pm    Post subject: Reply with quote

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) Rolling Eyes

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
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Fri Oct 05, 2007 11:34 pm    Post subject: Reply with quote

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

   Vadc = Getadc(34)                                        'temperature sensor input select &Bxx10 0010

   Admux = &B10100010                                       'to turn on bit 7 of ADMUX for 1.1V ref
   Vadc = Getadc(34 , 128)                                  'to turn on bit 7 of ADMUX for 1.1V ref


   Loop


End


In the simulator this seems to work OK, but the chip behaves differently in real life. The extra Admux line changes the measured values significantly Crying or Very sad
Back to top
View user's profile
Luciano
member
member


Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Sat Oct 06, 2007 1:15 pm    Post subject: Reply with quote

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
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Sat Oct 06, 2007 10:12 pm    Post subject: Reply with quote

thank you luciano I will try that and report back Smile
Back to top
View user's profile
jasreb
member
member


Joined: 03 Dec 2004
Posts: 41

uk.gif
PostPosted: Sun Oct 14, 2007 12:44 am    Post subject: Reply with quote

Thanks Luciano, doing it manually seems to do the trick. Not only that, but I can now read the temperature sensor as well Very Happy

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
View user's profile
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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