CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

ADC VREF

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

ADC VREF
PostPosted: Thu Jan 18, 2007 7:56 am     Reply with quote

I'm attempting to get my ADC port working, on the 16F914, 8Mhz oscillator. This PIC has a 10 bit ADC.

The 16F914.h file specifies:
Code:
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
//                SET_ADC_CHANNEL(), READ_ADC()
// Constants used for SETUP_ADC() are:
#define ADC_OFF                0              // ADC Off
#define ADC_CLOCK_DIV_2    0x100
#define ADC_CLOCK_DIV_4     0x40
#define ADC_CLOCK_DIV_8     0x10
#define ADC_CLOCK_DIV_32    0x20
#define ADC_CLOCK_DIV_16    0x50
#define ADC_CLOCK_DIV_64    0x6
#define ADC_CLOCK_INTERNAL  0x30              // Internal 2-6us

// Constants used in SETUP_ADC_PORTS() are:
#define sAN0            1       //| A0
#define sAN1            2       //| A1
#define sAN2            4       //| A2
#define sAN3            8       //| A3
#define sAN4            16      //| A5
#define sAN5            32      //| E0     
#define sAN6            64      //| E1     
#define sAN7            128     //| E2     
#define NO_ANALOGS      0       // None
#define ALL_ANALOG      255     // A0 A1 A2 A3 A5 E0 E1 E2

// One of the following may be OR'ed in with the above using |
#define VSS_VDD               0x0000          // Range 0-Vdd
#define VREF_VREF             0x6000          // Range VrefL-VrefH
#define VSS_VREF              0x2000          // Range 0-VrefH
#define VREF_VDD              0x4000          // Range VrefL-Vdd


// Constants used in READ_ADC() are:
#define ADC_START_AND_READ     7   // This is the default if nothing is specified
#define ADC_START_ONLY         1
#define ADC_READ_ONLY          6

So, would i be correct in specifying:
Code:
setup_adc_ports(ALL_ANALOG | VREF_VREF); // Using the VREF+/- to limit the input voltage
setup_adc(ADC_CLOCK_DIV_16); // Slowing down the sampling time
set_adc_channel(16); // AN4 / PIN 7
delay_us(20); // Sampling delay
probe = read_adc();

Leaving the ADC value in the variable probe?


Last edited by aodj on Tue Jan 23, 2007 8:19 am; edited 1 time in total
libor



Joined: 14 Dec 2004
Posts: 288
Location: Hungary

View user's profile Send private message

PostPosted: Thu Jan 18, 2007 8:25 am     Reply with quote

set_adc_channel(4);

in set_adc_channel() the channel parameter is numbered sequentially from 0-to-x, the parameter is not bitmask.
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

View user's profile Send private message Send e-mail

PostPosted: Thu Jan 18, 2007 8:27 am     Reply with quote

I believe the argument for set_adc_chanel() should be 4, not 16. You want the 4th channel. I think you took the 16 from the #define list for use with setup_adc_ports. check the manual and also look at the LST code generated from your C code, comparing the results to what the chip's data sheet says for configuring the ADCON register(s).

Next, calling set_adc_channel doesn't initiate a conversion. So the comment you have immediately after that line for your delay isn't right. The delay is a good idea, especially if you plan to move from one channel to another. The call to read_adc is where the read is initialized and your code will wait for the "done" bit. Again, look at the LST file and compare that to what the datasheet says the bits in the ADC registers mean.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Mon Jan 22, 2007 6:03 am     Reply with quote

Further to my previous post, I've got the ADC giving me outputs that I can work with, but to calibrate my ADC, I've got some variable resistor networks connected to Vref- and Vref+.

The hardware itself is fine, and varies the voltages, and when I alter the Vref- I get a corresponding change in the displayed reading from the ADC. However, if I attempt to change the Vref+, nothing happens.

I've used:
Code:
setup_adc_ports(sAN4|VREF_VREF);

to setup the pin and hopefully, the 2 Vref's as the references.

Any ideas?
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 5:45 am     Reply with quote

Has anyone else had any problems with setting the Vrefs?
Ttelmah
Guest







PostPosted: Wed Jan 24, 2007 6:00 am     Reply with quote

Add 'setup_lcd(LCD_DISABLED);' to your initialisation. It _shouldn't_ be necessary, but whenever you have a problem with a pin, it is worth making sure that everything else that may be attached to that pin is 'off'.
Using adjustable Vref settings, is common (though normally buffered, rather than through just a resistor tree - remember the load changes quite significantly during different parts of the ADC operation...).

Best Wishes
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 8:19 am     Reply with quote

I already had that line in my code. The problem in this instance is that whilst I vary the voltage at VRef+, and it is measured at the pin, the ADC scale doesn't change at all.
Code:
void init()
{
   setup_lcd(LCD_DISABLED);
   setup_comparator(NC_NC);
   set_timer0(0);
   setup_timer_0(RTCC_DIV_8);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   setup_adc_ports(sAN4|VREF_VREF);
   setup_adc(ADC_CLOCK_DIV_16);
   set_adc_channel(4); // 4 == AN4 / PIN 7
   delay_us(20);
}

Above is an init() routine I call at the beginning of my main. Further to this there is a problem with the pullup resistors for Port B, but thats for another thread Sad
Ttelmah
Guest







PostPosted: Wed Jan 24, 2007 9:31 am     Reply with quote

So what voltage is on pin 5, when you test with a DVM?.
Just stepped through the code, and the compiler does seem to be setting the right bit (bit 5 of ADCON0), to enable the Vref+ input.

Best Wishes
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 9:39 am     Reply with quote

Pin 5 can be varied between 2.36V and 4.69V. The data sheet specifies that VRef+ - VRef- must be greater than 2.5V to ensure an accurate ADC conversion, so at preset, I'm simply trying to get a scale change on the ADC.
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 10:09 am     Reply with quote

I just tested this with the VSS_VREF command instead of VREF_VREF, and tried altering the VRef+ voltage. Whilst the voltage does vary, the ADC value stays static, and will not change, even though, in theory, the upper limit of the conversion range is being changed.
Ttelmah
Guest







PostPosted: Wed Jan 24, 2007 10:18 am     Reply with quote

So, _is_ pin 5 actually changing.
You are telling us what voltage you 'think' is getting there, but is this voltage _really_ changing on the actual pin, if you test with a DVM?.
Also, what compiler version?. i tested with 3.249, and the register bit to change to use the external pin, does get set, but it is perfectly possible that this is not the case with another compiler version. If you have MPLAB, run the simulator up to the read command, and check whether bit 5 of ADCON0, is being set.

Best Wishes
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 10:30 am     Reply with quote

Yes, I'm reading the voltage changes as close to the package of the chip as possible.

As for compiler version, I believe it is 4.016.

I'll see what the simulation has to say about it. Thankyou for your continued assistance Smile
aodj



Joined: 20 Dec 2006
Posts: 40
Location: Reading, UK

View user's profile Send private message

PostPosted: Wed Jan 24, 2007 10:52 am     Reply with quote

Wewt, got it.

You were right to tell me to use the MPLAB Sim, so after a bit of blundering, I worked out how to set it up.

The set_adc_channel(4); command was resetting bit 5 in the ADCON0 register, turning off the VRef+.

So I moved it above the VREF_VREF and it now doesn't get overwritten.

Thankyou so much for your invaluable help!
Ttelmah
Guest







PostPosted: Wed Jan 24, 2007 11:13 am     Reply with quote

You might also look at the comments about V4 compilers. Though (gradually), they are starting to work,I sill say if you want to test with something 'near stable', use 3.249...
Glad you have it sorted for now.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
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


Powered by phpBB © 2001, 2005 phpBB Group