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

#int_ad Help?

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



Joined: 07 Sep 2003
Posts: 51

View user's profile Send private message Yahoo Messenger

#int_ad Help?
PostPosted: Wed Feb 11, 2004 5:11 am     Reply with quote

Mabuhay!

I am using the #int-AD service routine of a PIC18F452 at 20MHz. I am using a variable power supply as my analog voltage input to replicate the changes in the analog input to the PIC ADC AN0 channel

Unfortunately, I read zero result even if I vary the power supply output voltage from 5V to 0V or vice versa. Is there something wrong with my code listed below? Or maybe I miss something?

BTW, I use two 5V power supply here: one for the PIC18F452 and the other for my analog voltage.

Any help will do? Please comment on this?

Thank you.


The code:

Code:

#include <18F452.H>           // Target PIC Microcontroller IC
#device  *=16 ADC=10          // use a 16-bit pointer & 10bit A/D

#fuses HS,NOPROTECT,NOWDT     // PIC MCU Configuration
#use delay(clock=20000000)    // 20MHz Crystal clock speed

#use rs232(baud=115200,parity=N,xmit=PIN_B3,rcv=PIN_B2,bits=8)

/////////////////////////////////////
//  Include Files                  //
/////////////////////////////////////
#include <LCD.C>

/////////////////////////////////////

/////////////////////////////////////
//  PIC18F452 Config Register      //
/////////////////////////////////////
unsigned char ADRESL;
#locate ADRESL=0x0FC3

unsigned char ADRESH;
#locate ADRESH=0x0FC4

unsigned char PIR1;
#locate PIR1=0x0F9E

struct {
    unsigned char TMR1IF:1;
    unsigned char TMR2IF:1;
    unsigned char CCP1IF:1;
    unsigned char SSPIF :1;
    unsigned char TXIF  :1;
    unsigned char RCIF  :1;
    unsigned char ADIF  :1;
    unsigned char PSPIF :1;
} PIR1bits;
#locate PIR1bits=0x0F9E

unsigned char ADCON0;
#locate ADCON0=0x0FC2

struct {
    unsigned char ADON  :1;
    unsigned char ADNONE:1;
    unsigned char GODONE:1;
    unsigned char CHS0  :1;
    unsigned char CHS1  :1;
    unsigned char CHS2  :1;
    unsigned char ADCSO :1;
    unsigned char ADCS1 :1;
} ADCON0bits;
#locate ADCON0bits=0x0FC2

unsigned char ADCON1;
#locate ADCON1=0x0FC1

struct {
    unsigned char PCFG0 :1;
    unsigned char PCFG1 :1;
    unsigned char PCFG2 :1;
    unsigned char PCFG3 :1;
    unsigned char ANONE1:1;
    unsigned char ANONE2:1;
    unsigned char ADCS2 :1;
    unsigned char ADFM  :1;
} ADCON1bits;
#locate ADCON1bits=0x0FC1

/////////////////////////////////////

/////////////////////////////////////
//  Defines and Macros             //
/////////////////////////////////////

// Six (6) Most Significant bits of ADRESH are read as �0�
#define ADC_RIGHT_JUSTIFY 1
// Six (6) Least Significant bits of ADRESL are read as �0�
#define ADC_LEFT_JUSTIFY  0

/////////////////////////////////////

/////////////////////////////////////
//  Global Flag Variables          //
/////////////////////////////////////
int1 glADCdone = 0;  // A/D done conversion flag bit

/////////////////////////////////////

/////////////////////////////////////
//  Global Variables               //
/////////////////////////////////////
unsigned int16 gi16ADCresult;    // A/D result value after conversion

/////////////////////////////////////

/////////////////////////////////////
//  Interrupt Service Routines     //
/////////////////////////////////////
/*
 The data sheet says there must be a delay of 2 x Tad
 after a conversion. Since we're using a Tad of 3.2 usec,
 this delay must be 2 x 3.2 = 6.4 usec. But we know that the
 CCS interrupt handler takes at least that long to go in
 and out of this interrupt routine (with our 20 MHz crystal),
 so we don't need to put in a line of code to do the delay.
*/
#int_ad  // ADC interrupt service routine
void adc_isr()
{
   // read the 10-bit ADC result
   // this requires reading the high and low bytes of the
   // ADC register, and putting them into a 16-bit variable
   gi16ADCresult = (ADRESH<<8);
   gi16ADCresult |= ADRESL;

   glADCdone = 1;          // ADC conversion complete
   while (PIR1bits.ADIF)   // check if ADIF is set
      PIR1bits.ADIF = 0;   // set ADIF to zero
}

/////////////////////////////////////
//  End Interrupt Service Routines //
/////////////////////////////////////

///////////////////////////////////
//  MCU Initialization Routines  //
///////////////////////////////////

//************************************************************************
void init_chip() {   // Initialize the MCU Chip

   lcd_init();       // LCD should be initialized first
   delay_ms(100);
   lcd_init();       // Init LCD again, coz sometimes can't initialize LCD
   delay_ms(100);
   lcd_init();       // Once more, to be sure LCD gets initialized

   setup_adc_ports(RA0_RA1_RA3_ANALOG);   // setup the ADC analog pins
   // with a 20MHz clock, we divide the oscillator by 64
   // to get an ADC clock of 312.5KHz, so Tad=3.2usec
   setup_adc(ADC_CLOCK_DIV_64);  // configure the ADC clock to 3.2usec
   set_adc_channel(0);  // specify ADC channel to use (PortA0)

   // Six (6) Most Significant bits of ADRESH are read as �0�
   ADCON1bits.ADFM = ADC_RIGHT_JUSTIFY;
   PIR1bits.ADIF = 0;   // clear ADC interrupt before enabling

   enable_interrupts(int_ad);     // enable ADC interrupt
   enable_interrupts(global);    // enable global interrupt
}

///////////////////////////////////
//End MCU Initialization Routines//
///////////////////////////////////


//************************************************************************
// Main Program
//************************************************************************
main()
{
   init_chip();      // Initialize the MCU Chip
   
   lcd_putc("\fADC Demo");

   gi16ADCresult = 0;   // initialize the ADC result variable to zero
   delay_us(20);        // wait for ADC aquisition time

   ADCON0bits.GODONE = 1;  // start an ADC conversion

   while (TRUE)
   {
      if (glADCdone) // ADC conversion completed
      {
         glADCdone = 0; // prevent multi-trigger of ADC conversion
         printf("ADC Result = %lx\n\r",gi16ADCresult);   // print the result
         // for demo purpose delay 1sec. for screen updating with
         // the new ADC result
         delay_ms(1000);
         ADCON0bits.GODONE = 1;  // start another ADC conversion
      }
   }
}

//************************************************************************
// End Program
//************************************************************************


[/img]
Ttelmah
Guest







PostPosted: Wed Feb 11, 2004 6:23 am     Reply with quote

To say that you seem to be working very hard to do something that the compiler allready does for you, is perhaps an understatement...

The READ_ADC function, has three variables. ADC_START_ONLY, and ADC_READ_ONLY, allow the standard functions to be used to cover what you are doing. ADC_START_AND_READ, gives the 'default' behaviour.

So, you only need in the interrupt code:
Code:

#int_ad  // ADC interrupt service routine
void adc_isr()
{
   // read the 10-bit ADC result
   gi16ADCresult = READ_ADC(ADC_READ_ONLY);

   glADCdone = 1;          // ADC conversion complete
}


The global handler routine automatically clears the interrupt flag.

In the main code, you can use:
[code]
void init_chip() { // Initialize the MCU Chip

lcd_init(); // LCD should be initialized first
delay_ms(100);
lcd_init(); // Init LCD again, coz sometimes can't initialize LCD
delay_ms(100);
lcd_init(); // Once more, to be sure LCD gets initialized

setup_adc_ports(RA0_RA1_RA3_ANALOG); // setup the ADC analog pins
// with a 20MHz clock, we divide the oscillator by 64
// to get an ADC clock of 312.5KHz, so Tad=3.2usec
setup_adc(ADC_CLOCK_DIV_64); // configure the ADC clock to 3.2usec
set_adc_channel(0); // specify ADC channel to use (PortA0)

//The default is to right justify
enable_interrupts(int_ad);
// enable ADC interrupt
enable_interrupts(global); // enable global interrupt
}

///////////////////////////////////
//End MCU Initialization Routines//
///////////////////////////////////


//************************************************************************
// Main Program
//************************************************************************
main()
{
init_chip(); // Initialize the MCU Chip

lcd_putc("\fADC Demo");

gi16ADCresult = 0; // initialize the ADC result variable to zero
delay_us(20); // wait for ADC aquisition time

READ_ADC(ADC_START_ONLY); // start an ADC conversion

while (TRUE)
{
if (glADCdone) // ADC conversion completed
{
glADCdone = 0; // prevent multi-trigger of ADC conversion
printf("ADC Result = %lx\n\r",gi16ADCresult); // print the result
// for demo purpose delay 1sec. for screen updating with
// the new ADC result
delay_ms(1000);
READ_ADC(ADC_START_ONLY); // start another ADC conversion
}
}
}


Best Wishes
rrb011270



Joined: 07 Sep 2003
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Feb 11, 2004 8:13 am     Reply with quote

Thanx u for the immediate response...

I'll try this code tommorrow... coz its 11:00pm here in the Philippines...

May the force be with you... Very Happy
Guest








Re: #int_ad Help?
PostPosted: Wed Apr 26, 2006 11:20 am     Reply with quote

rrb011270 wrote:
Mabuhay!

I am using the #int-AD service routine of a PIC18F452 at 20MHz. I am using a variable power supply as my analog voltage input to replicate the changes in the analog input to the PIC ADC AN0 channel

Unfortunately, I read zero result even if I vary the power supply output voltage from 5V to 0V or vice versa. Is there something wrong with my code listed below? Or maybe I miss something?

BTW, I use two 5V power supply here: one for the PIC18F452 and the other for my analog voltage.

Any help will do? Please comment on this?

Thank you.


The code:

Code:

#include <18F452.H>           // Target PIC Microcontroller IC
#device  *=16 ADC=10          // use a 16-bit pointer & 10bit A/D

#fuses HS,NOPROTECT,NOWDT     // PIC MCU Configuration
#use delay(clock=20000000)    // 20MHz Crystal clock speed

#use rs232(baud=115200,parity=N,xmit=PIN_B3,rcv=PIN_B2,bits=8)

/////////////////////////////////////
//  Include Files                  //
/////////////////////////////////////
#include <LCD.C>

/////////////////////////////////////

/////////////////////////////////////
//  PIC18F452 Config Register      //
/////////////////////////////////////
unsigned char ADRESL;
#locate ADRESL=0x0FC3

unsigned char ADRESH;
#locate ADRESH=0x0FC4

unsigned char PIR1;
#locate PIR1=0x0F9E

struct {
    unsigned char TMR1IF:1;
    unsigned char TMR2IF:1;
    unsigned char CCP1IF:1;
    unsigned char SSPIF :1;
    unsigned char TXIF  :1;
    unsigned char RCIF  :1;
    unsigned char ADIF  :1;
    unsigned char PSPIF :1;
} PIR1bits;
#locate PIR1bits=0x0F9E

unsigned char ADCON0;
#locate ADCON0=0x0FC2

struct {
    unsigned char ADON  :1;
    unsigned char ADNONE:1;
    unsigned char GODONE:1;
    unsigned char CHS0  :1;
    unsigned char CHS1  :1;
    unsigned char CHS2  :1;
    unsigned char ADCSO :1;
    unsigned char ADCS1 :1;
} ADCON0bits;
#locate ADCON0bits=0x0FC2

unsigned char ADCON1;
#locate ADCON1=0x0FC1

struct {
    unsigned char PCFG0 :1;
    unsigned char PCFG1 :1;
    unsigned char PCFG2 :1;
    unsigned char PCFG3 :1;
    unsigned char ANONE1:1;
    unsigned char ANONE2:1;
    unsigned char ADCS2 :1;
    unsigned char ADFM  :1;
} ADCON1bits;
#locate ADCON1bits=0x0FC1

/////////////////////////////////////

/////////////////////////////////////
//  Defines and Macros             //
/////////////////////////////////////

// Six (6) Most Significant bits of ADRESH are read as �0�
#define ADC_RIGHT_JUSTIFY 1
// Six (6) Least Significant bits of ADRESL are read as �0�
#define ADC_LEFT_JUSTIFY  0

/////////////////////////////////////

/////////////////////////////////////
//  Global Flag Variables          //
/////////////////////////////////////
int1 glADCdone = 0;  // A/D done conversion flag bit

/////////////////////////////////////

/////////////////////////////////////
//  Global Variables               //
/////////////////////////////////////
unsigned int16 gi16ADCresult;    // A/D result value after conversion

/////////////////////////////////////

/////////////////////////////////////
//  Interrupt Service Routines     //
/////////////////////////////////////
/*
 The data sheet says there must be a delay of 2 x Tad
 after a conversion. Since we're using a Tad of 3.2 usec,
 this delay must be 2 x 3.2 = 6.4 usec. But we know that the
 CCS interrupt handler takes at least that long to go in
 and out of this interrupt routine (with our 20 MHz crystal),
 so we don't need to put in a line of code to do the delay.
*/
#int_ad  // ADC interrupt service routine
void adc_isr()
{
   // read the 10-bit ADC result
   // this requires reading the high and low bytes of the
   // ADC register, and putting them into a 16-bit variable
   gi16ADCresult = (ADRESH<<8);
   gi16ADCresult |= ADRESL;

   glADCdone = 1;          // ADC conversion complete
   while (PIR1bits.ADIF)   // check if ADIF is set
      PIR1bits.ADIF = 0;   // set ADIF to zero
}

/////////////////////////////////////
//  End Interrupt Service Routines //
/////////////////////////////////////

///////////////////////////////////
//  MCU Initialization Routines  //
///////////////////////////////////

//************************************************************************
void init_chip() {   // Initialize the MCU Chip

   lcd_init();       // LCD should be initialized first
   delay_ms(100);
   lcd_init();       // Init LCD again, coz sometimes can't initialize LCD
   delay_ms(100);
   lcd_init();       // Once more, to be sure LCD gets initialized

   setup_adc_ports(RA0_RA1_RA3_ANALOG);   // setup the ADC analog pins
   // with a 20MHz clock, we divide the oscillator by 64
   // to get an ADC clock of 312.5KHz, so Tad=3.2usec
   setup_adc(ADC_CLOCK_DIV_64);  // configure the ADC clock to 3.2usec
   set_adc_channel(0);  // specify ADC channel to use (PortA0)

   // Six (6) Most Significant bits of ADRESH are read as �0�
   ADCON1bits.ADFM = ADC_RIGHT_JUSTIFY;
   PIR1bits.ADIF = 0;   // clear ADC interrupt before enabling

   enable_interrupts(int_ad);     // enable ADC interrupt
   enable_interrupts(global);    // enable global interrupt
}

///////////////////////////////////
//End MCU Initialization Routines//
///////////////////////////////////


//************************************************************************
// Main Program
//************************************************************************
main()
{
   init_chip();      // Initialize the MCU Chip
   
   lcd_putc("\fADC Demo");

   gi16ADCresult = 0;   // initialize the ADC result variable to zero
   delay_us(20);        // wait for ADC aquisition time

   ADCON0bits.GODONE = 1;  // start an ADC conversion

   while (TRUE)
   {
      if (glADCdone) // ADC conversion completed
      {
         glADCdone = 0; // prevent multi-trigger of ADC conversion
         printf("ADC Result = %lx\n\r",gi16ADCresult);   // print the result
         // for demo purpose delay 1sec. for screen updating with
         // the new ADC result
         delay_ms(1000);
         ADCON0bits.GODONE = 1;  // start another ADC conversion
      }
   }
}

//************************************************************************
// End Program
//************************************************************************


[/img]


I have the same problem
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