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

ADC on Pic16F88 not working
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
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

ADC on Pic16F88 not working
PostPosted: Fri Jul 28, 2017 3:26 am     Reply with quote

Dear Friends, I am working on PIC16F88 with crystal of 20MHz and for some reason the code is not working. I connected the potentiometer on 5V on one end and 0V on the other. The wiper is connected on AN2. I am using the below code:

Code:
#include <main.h>
int8 read_delay_analogue = 0;


void main()
{
   setup_adc_ports(sAN2);
   setup_adc(ADC_CLOCK_DIV_4);
   set_adc_channel(2);



   //Example blinking LED program
   while(true)
   {
   delay_ms(100);
   read_delay_analogue = read_adc();
   }

}


The pic is still reading 0!

Looking forward for your help
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 3:45 am     Reply with quote

First thing is you are clocking the ADC much too fast.

Table 12-1. ADC_CLOCK_DIV_4 is rated for 2.5MHz maximum CPU speed....

For 20Mhz, you need /32.

You don't show whether you have an ADC= line. You want #device ADC=8 for the int8 output you are using.
What is the impedance of the pot?.

The comparator should also be turned off, since it shares pins with the ADC here.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 3:49 am     Reply with quote

Dear Ttelmah,

Thanks for your reply. The code is below:

Code:
#include <16F88.h>
#device ADC=16


It was in the main.h file.

The resistance of the pot is 1Kohm.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 3:55 am     Reply with quote

You need ADC=8. Currently the ADC value is being left justified to an int16, and you are then taking the low 8bits of this (since you read into an int8....).

You show no fuses or clock?....

Code:

#include <16F88.h>
#device ADC=8
#fuses HS, NOWDT, PUT, NOLVP, NOPROTECT, NOMCLR
#use delay(clock=20MHz)


Then change to ADC_CLOCK_DIV_32, and you have a chance of it working.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 3:57 am     Reply with quote

Dear Ttelmah,

This is the information:

Code:
#include <16F88.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal=20000000)

#define LED PIN_B3
#define DELAY 1000


Sorry but my whole program had already reached the 150 lines and I do not want to confuse someone. Just tell me what information you want and I will send you.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 4:04 am     Reply with quote

Dear Ttelmah,

It worked perfectly. The problem was the ADC definition. it was 16 and I put it to 8 as you suggested.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Jul 28, 2017 7:22 am     Reply with quote

You need the ADC clock change as well, or accuracy will be foul.

Have a suspicion you may be testing with Proteus....
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun Aug 20, 2017 2:55 pm     Reply with quote

Dear Friends,

I continue to working on this project and for some reason, the ADC is not working fine. I made the 10K pot on 5V and GND and the wiper to AN0 of the PIC16F88. I am using the pot to create delay according to user request. I inserted the following lines in my code:
Code:

setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_2);

int switch_delay = 0;

#device ADC=8

I used the ADC 8 because I want 0-256 range from 5V to GND and the center is 128. But still I am getting 0 in the middle of the wiper. I am seeing the value on RS232 terminal. What could be the problem please? If you need any more information please let me know. My fuses are:
Code:

#include <16F88.h>
#device ADC=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                   

#use delay(crystal=20000000)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 20, 2017 3:22 pm     Reply with quote

aaronik19 wrote:

#use delay(crystal=20000000)

setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_2);

Look at this table, on page 118 of the 16F88 data sheet. It shows a
table of ADC clock divisors for several different PIC frequencies:
Quote:
TABLE 12-1: TAD vs. MAXIMUM DEVICE OPERATING FREQUENCIES – STANDARD DEVICES (C)

http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf
What is the correct divisor for a 20 MHz PIC clock ?
Hint: It's not 2, as in your code above.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun Aug 20, 2017 3:28 pm     Reply with quote

I also compiled the program with divide 32 and 64 but still got the same result. Am i right that the variable is int since the maximum is 256?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Aug 21, 2017 1:14 am     Reply with quote

You say:
"I inserted the following lines in my code", but give us no indication of 'where'.

You need to post a small _complete_ program. Emphasis on the 'complete'. It must be something that will compile.
Also what your compiler version number is?.

Then we have a chance of telling you what is wrong.
temtronic



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

View user's profile Send private message

PostPosted: Mon Aug 21, 2017 5:02 am     Reply with quote

re:
But still I am getting 0 in the middle of the wiper.
...

Is the pot a LINEAR version and NOT a Logarithmic( audio) one ?

simple test is to confirm with a DMM that the pot is linear.

once you know, post a small program, (setup,read adc, send to PC)

Jay
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Aug 21, 2017 5:05 am     Reply with quote

Dear All,

This is the whole program.
Code:

#include <main2.h>
#define CCP_OFF

int count_highlevel_delay = 0, count_lowlevel_delay = 0, stop_sifter_delay = 0;
byte high_level_ack = 0, low_level_ack = 0, stop_sifter_ack = 0;
unsigned int16 switch_delay;


#INT_RB
void  RB_isr(void)
{
   
   switch_delay = read_adc();
   if (input(PIN_B6))
   {
      count_highlevel_delay = 0;
      high_level_ack = 1;
      stop_sifter_ack = 0;
   }
   else   {
      count_highlevel_delay = 0;
      high_level_ack = 0;
      stop_sifter_ack = 1;
      stop_sifter_delay = 0;
   }
   
   if (input(PIN_B4))
   {
      count_lowlevel_delay = 0;
      low_level_ack = 1;
   }
   else   {
      count_lowlevel_delay = 0;
      low_level_ack = 0;
      output_low(PIN_A2);
      }
}

#INT_TIMER1
void  TIMER1_isr(void)
{
++count_highlevel_delay;
++count_lowlevel_delay;
++stop_sifter_delay;

if (count_highlevel_delay == switch_delay & high_level_ack)
   {
    output_high(PIN_A1);
   }

if (stop_sifter_delay == switch_delay & (!high_level_ack) & stop_sifter_ack)
   {
    output_low(PIN_A1);
   }

if (count_lowlevel_delay == switch_delay & low_level_ack)
   {
    output_high(PIN_A2);
   }

}

void main()
{
   setup_adc_ports(sAN0);
   set_adc_channel(0);
   setup_adc(ADC_CLOCK_DIV_64);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //104 ms overflow
   set_tris_a(00000001);
   output_a(00000000);
   delay_ms(500);
   output_b(00000000);
   
   
   enable_interrupts(INT_RB);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   delay_ms(100);
   //switch_delay = read_adc();
   //switch_delay = 20;
   
   //Example blinking LED program
   while(true)
   {
      output_low(LED);
      delay_ms(DELAY);
      output_high(LED);
      delay_ms(DELAY);

   }

}


In this code there are other functions, so please ignore them. I submitted all the program just for your interest.

The H File:
Code:

#include <16F88.h>
#device ADC=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal=20000000)

#define LED PIN_B0
#define DELAY 1000
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Aug 21, 2017 6:11 am     Reply with quote

Yes the POT is linear. That is the first I checked
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Aug 21, 2017 6:27 am     Reply with quote

Your INT_RB is never going to be called.
Code:

   set_tris_a(00000001);
   output_a(00000000); //This sets the whole of portA to output
   delay_ms(500);
   output_b(00000000);//This does the same for portB....

Both port A and portB are programmed as outputs. So the ADC can't work, nor can the portB inputs...

You need:
Code:

   output_a(0b0000000); //This sets the whole of portA to output
   set_tris_a(0b0000001); //switches A0 to be an input
   delay_ms(500);
   output_b(0b0000000);//This does the same for portB....
   set_tris_b(0b0101000); //set B4 & B6 as inputs.
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