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 CCS Technical Support

18F26K22 A/D example Please
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

18F26K22 A/D example Please
PostPosted: Sat Feb 12, 2011 10:44 am     Reply with quote

I am having trouble setting up the a/d on a 18f26k22. I need to read a 10bit value from an0 only using vss/vdd as references. I have successfully configured other pics for a/d. The application is not critical. I am only wanting to use a pot to select options of a menu based on the a/d range input.

Would some one Please show me an example?

Thanks Much
Brian
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 12:55 pm     Reply with quote

The header file for the device would be where I'd start to see what valid combinations are allowed.
Then see what peripherals need to be disabled, if required.
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 2:33 pm     Reply with quote

Thanks for the reply. I tried looking at the header file and I'm able to get the program to compile. The trouble is I'm not getting the results I would expect. I select the an0 port only as follows: setup_adc_ports(sAN0|VSS_VDD);
But when I view the ANSELA register I find it is set to 0010111b
Should it not be 00000001b? And the value = Read_ADC(); is always 00h

Thanks
Brian
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 2:39 pm     Reply with quote

Sorry but I don't have that chip or the compiler for it. Perhaps there is an example in the examples folder that will help. Several of them have ifdef.... for various PIC series.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 4:03 pm     Reply with quote

Post your compiler version. If it's a compiler bug, maybe I can look at
the problem later today or tomorrow.

(Always post your version. We don't remember it from your previous threads).
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 7:43 pm     Reply with quote

It looks like the 18F26k22 is very similar to the one I'm using, the 18F14K22. In that case, I wanted to use the internal reference (at 1.024 volts since the 2**10 = 1024 and the temp sensor gives 10mv/deg C it worked out very nice). I'm using the internal precision oscillator at 8mhz using the compiler directive:
#use delay(clock=8000000) // configure for 8mhz clock
With compiler version 4.114, the header did not have the correct (or any actually) info configured for the internal reference - here is the code segment I used to set it up to use the internal reference:

Code:
     // setup AD converter
     // AN2 (RA2) = ambient temp, AN10 (RA10)=htr temp
     // NOTE: the setup_adc_ports clears my selection of the Vref source
     //       so it needs to be done before I write to ADCON1.
     // => If we define VSS_VFVR using the same format as the rest of the ref
     //    config info in the .h file (0x800) then setup_adc_ports() does select
     //    the internal reference correctly and we only have to write to the
     //    VREFCON0 register to enable the FVR and select the 1x multiplier.
setup_adc_ports(AIR_PORT | HTR_PORT,VSS_VFVR); 
setup_adc(ADC_CLOCK_DIV_16);
         
     // Have to enable the internal FVR and set to 1x
VREFCON0 = 0x90; // FVR enabled, 1x (1.024v)  (pg 245)
         
     //  VREFCON1 = 0x00; // DAC is disabled  (pg 246)
     //  VREFCON2 = 0x00; // DAC output disabled (pg 246)
     //  ADCON1   = 0x08; // pos vref from FVR, neg vref from Vss (pg 214,207)
     //  ADCON2   = 0x95; // Rt. justify, TAD4,Fosc/16   (pg 215)
 
     // setup_adc_ports(AIR_PORT | HTR_PORT); 
     // AN2 (RA2) = ambient temp, AN10 (RA10)=htr temp

     // check for current settings in eeprom - if first byte of eeprom is not
     // CHK_BYTE then copy defaults to eeprom else read settings from eeprom
     // into the settings structure (over write defaults).


To read the ADC, I use the following code:

Code:
// read the heater ADC channel - return raw value + cal factor for sensor
// also saves corrected reading in HTR_raw (mv)
signed int16 rd_HTR_raw()     
    {
    set_adc_channel(HTR_CHAN); // select the HTR temp channel
    delay_us(20);              // let stabilize
    HTR_raw = read_adc(ADC_START_AND_READ)+ settings.sens_cal_htr ;
    return(HTR_raw);          // return corrected raw value (mv)
    }


Don't forget to specify the 10 bit mode with a device line near the top of your code:

Code:
#device adc=10         // 10 bit AD mode



Hope this helps - this code runs fine in my little application (2 sensors).
Note that the page number references are for the 18F14K22 chip.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sat Feb 12, 2011 9:09 pm     Reply with quote

Thanks Guys for the replies!
I'll check out the code early tomorrow.

P.S.
My version is 4.110

Thanks again
Brian
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 9:47 am     Reply with quote

Still no luck getting the adc to work. The ANSELA value never changes from the default POR setting (00101111b) even after the following lines execute:

setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0|VSS_VDD);

No compile errors so I assume the values I'm using are valid.

How do I set the registers manually?

Thanks
Brian
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 11:09 am     Reply with quote

Here are the definitions I use for the 18F14k22 - you will need to verify they are the same for your chip, but this is how I reference the registers I need to access the ADC config stuff. Note the line in my example code above to set the VREFCON0 register as an example ...

Code:
   // Processor specific ADC config info
   // Define some SFR registers we need access to ...
#BYTE VREFCON0 = 0xFBA  // Vref configuration registers
#BYTE VREFCON1 = 0xFBB
#BYTE VREFCON2 = 0xFBC

#BYTE ADCON0 = 0xFC2    // A/D converter config registers
#BYTE ADCON1 = 0xFC1
#BYTE ADCON2 = 0xFC0
#define VSS_VFVR  0x800 // new definition to use internal vref not listed in .h

#BYTE ANSEL  = 0xF7E    // Analog Select Registers
#BYTE ANSELH = 0xF7F

#BYTE OSCCON = 0xFD3    // Oscillator control register
#BYTE OSCCON2= 0xFD2



mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 11:19 am     Reply with quote

Thanks! Can I also define CONFIG3H in the same way? It's address is huge (300005h). I would like to clear bit #1 (PBADEN) in this register so the portB a/d's are disabled upon POR.

Thanks
Brian
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 11:58 am     Reply with quote

I'm not sure on that one - seems to me there is something funny about the config registers up there that have to be accessed via a table command or something - I have seen other posts here about that. I think that is one of the fuses - take a look in the install directory for the compiler (usually C:\Program Files\PICC ) for the file "fuses.txt" One of the entries I find in there is:
NOPBADEN PORTB pins are configured as digital I/O on RESET

which sounds like what you are looking for.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 3:07 pm     Reply with quote

This program should work with vs. 4.110:
Code:

#include <18F26K22.h>
#device adc=10
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

//======================================
void main(void)
{
int16 result;

setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_4);
set_adc_channel(0);
delay_us(10);

while(1)
  {
   result = read_adc();
   printf("%lx \n\r", result);
   delay_ms(500);
  }

}


I tested it with an 18F45K22 in hardware, with vs. 4.110, and it worked.
It displayed these values in the terminal window as I turned a trimpot
from one end to the other:
Quote:

0001
0001
0034
014a
01a7
023d
032d
03ae
03ff
03ff
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 3:14 pm     Reply with quote

Thanks for the reply I'll test it out. In the mean time I have the program working using manual setting of registers and testing / toggling the GO/DONE bit.

#byte ANSELA = 0xf38
#byte ANSELB = 0xf39
#byte ANSELC = 0xf3a
#byte ANSELD = 0xf3b
#byte ANSELE = 0xf3c
#byte ADCON0 = 0xfc2
#byte ADCON1 = 0xfc1
#byte ADCON2 = 0xfc0

#byte CM1CON0 = 0xf78
#byte CM2CON0 = 0xf77



//setup_adc(ADC_CLOCK_INTERNAL);
//setup_adc_ports(sAN0|VSS_VDD);
ANSELA = 1;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;

ADCON0 = 1; //AN0 (only) selected and a/d enabled
ADCON1 = 0; //Vss & Vdd are reference
ADCON2 = 0x81; //Rigth justify,

CM1CON0 = 0;
CM2CON0 = 0;


Thanks Again
Brian
bdrmachine



Joined: 24 Jan 2010
Posts: 14

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 7:47 pm     Reply with quote

PCM programmer

I tested the code with my hardware and I get the same results as before (ANSELA remains at POR value).

The manual register select code work as expected.

Thanks
Brian
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 13, 2011 8:53 pm     Reply with quote

The POR (power-on-reset) value of ANSEL is "all 1's" for the analog bits.
This means they are all configured as analog pins on power-up. I looked
at the .LST file for vs. 4.110 and it doesn't write to ANSELA (0xF38).
It leaves it in the power-on-reset state.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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