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

PIC16f819 Analog to Digital conversion

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



Joined: 24 Nov 2008
Posts: 9

View user's profile Send private message

PIC16f819 Analog to Digital conversion
PostPosted: Tue Mar 03, 2009 6:47 am     Reply with quote

Hello,

I generated a code which suppose to read a signal using pins PIN_A0, PIN_A1 and PIN_A2. These are my 3 inputs. The main task is to read the signal and turn on or off a LED. Because the A/D resolution is 10bit, I said that if the input signal on PIN_A0 is greater than 511 (somewhere in the middle cos 1023 max) then make output PIN_B0 high, and if less than 511 make the same pin_B0 low. The same applies to the other 2 inputs.
The problem is that if any of those inputs become high then all outputs become high!
But I wanted for example if PIN_A1 is high, only PIN_B1 to be high and so on !

The code is given below:
Code:
#include <16F819.h>    //header file for device
#device ADC=10         //resolution of ADC
#use delay (clock=8000000)

//fuse settings to configure device
//i.e. NO WDT - NO Watchdog Timer, INTRC_IO Internal clock used, pins available for I/O
#fuses NOWDT,INTRC_IO, NOPUT, NOMCLR,NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG,NOPROTECT


//Interrupt Service Routine
// the compiler will gerenate code to jump to the function when the interrupt is detected.
//It will generate code to save and restore the machine state, and will clear the interrupt flag.
#INT_TIMER0
void isr()
{
   long AC_CAP = 0;
   long DC_CAP = 0;
   long CURRENT = 0;
   
   
// code for isr

set_ADC_channel( PIN_A0 );  //enable AC Capacitor ADC
delay_us(100);
AC_CAP = read_adc();        //read ADC

if (AC_CAP > 511)           //if value > 2.5V LED ON
   output_high(PIN_B0);
delay_ms (0);

if (AC_CAP < 511)           //if value > 2.5 LED OFF
   output_low(PIN_B0);
delay_ms (0);


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

set_ADC_channel( PIN_A1 );  //enable DC Capacitor ADC
delay_us(100);
DC_CAP = read_adc();        //read ADC

if (DC_CAP > 511)           //if value > 2.5V LED ON
   output_high(PIN_B1);
delay_ms (0);

if (DC_CAP < 511)          //if value < 2.5V LED OFF
   output_low(PIN_B1);
delay_ms (0);

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

set_ADC_channel( PIN_A2 );  //enable current ADC
delay_us(100);
CURRENT = read_adc();       //read ADC

if (CURRENT > 511)          //if value > 2.5V LED ON
   output_high(PIN_B2);
delay_ms (0);

if (CURRENT < 511)          //if value < 2.5V LED OFF
   output_low(PIN_B2);
delay_ms (0);

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


}
void main() {
   setup_oscillator(OSC_8MHZ);     //use internal 8MHz clock

   SETUP_TIMER_0(RTCC_DIV_2);     
   setup_timer_1(T1_DISABLED);     //TIMER 1 NOT USED
   setup_timer_2(T2_DISABLED,0,1); //timer 2 not used, period, postcale

   setup_ADC_ports( NO_ANALOGS );  //ALL PORTS DIGITAL
   setup_ADC( ADC_CLOCK_DIV_16 );  //SET adc CLOCK, SHOULD BE BETWEEN 1.6us AND 6.4us (1/8MHz X 16 = 2us)
   
   enable_interrupts(INT_TIMER0);  //TIMER 0 TO CAUSE INTERRUPT
   enable_interrupts(GLOBAL);      //Enable interrupts

do
   {
   //dummy code executed while waiting for interrupt
   } while (TRUE);
}

Regards
Mitsaras
Ttelmah
Guest







PostPosted: Tue Mar 03, 2009 9:22 am     Reply with quote

Lots of faults.....
Start with your use of the timer interrupt.
You have this set to run off the master clock/8. It'll interrupt every 512 machine instructions. You are then sitting in the interrupt using long delays (a total of 300uSec at least), which is more time than the interrupt will take....
You to interrupt at a _much_ lower frequency, and also shorten the delays as much as possible. Even better, get rid of them entirely. Use a state machine, and perform just one job at a time in the interrupt (first time, select the channel, second time, start the ADC, third time, read the ADC, then perform the first test etc.). A search here will find example code for this approach.
Then, look at the manual for the value that the set_adc_channel function expects. Does it expect pin numbers?.
Fnally, look at how to use an 'else' statement.

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