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

Analog to digital conversion from scratch

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



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

Analog to digital conversion from scratch
PostPosted: Wed Nov 13, 2013 12:08 pm     Reply with quote

Hello All,

I am having trouble getting the A2D to work on PIC16f1939. I am using CCS compiler 5.007.
The built in A2D function works fine but when I follow the manual method( more control) I couldn't get it work.
Can anyone point out what I am doing wrong? your help is appreciated it.
Thank you!
Code:

#include <16F1939.h>
#fuses   INTRC_IO, NOWDT, NOPROTECT, NOMCLR
#use     delay(clock = 32000000)
#include "flex_lcd.c"
#use     i2c(master, sda=PIN_C4, scl=PIN_C3)
#include <stdlib.h>
#use     fast_io (B)
 
#byte GPIOB = 0xd
#bit  GPIOB_1 = GPIOB.1
 
#byte TRISIOB  = 0x08D
#bit  TRISIOB_1=  TRISIOB.1
 
#byte ANSELB = 0x18D
#bit  ANSELB_1= ANSELB.1
 
#byte ADCON0=0x9d
#bit  ADCON0_0=ADCON0.0
#bit  ADCON0_1=ADCON0.1
#bit  ADCON0_2=ADCON0.2
#bit  ADCON0_3=ADCON0.3
#bit  ADCON0_4=ADCON0.4
#bit  ADCON0_5=ADCON0.5
#bit  ADCON0_6=ADCON0.6
 
#byte ADCON1=0x9e
#bit  ADCON1_7=ADCON0.7
#bit  ADCON1_6=ADCON0.6
#bit  ADCON1_5=ADCON0.5
#bit  ADCON1_4=ADCON0.4
 
//PERIPHERAL INTERRUPT ENABLE REGISTER 1
#byte PIE1= 0x91
#bit  PIE1_6=PIE1.6
 
#byte ADRESH=0x9c
#byte ADRESL=0x9B
 
//FUNCTION PROTOTYPE
void  adc_init(void);
int16 sample(void);
 
void  main()

   int16 adc=0;
 
   lcd_init();
   adc_init();
 
   While(1)
   {
    adc=sample();
    delay_ms(10);
    printf(lcd_putc,"\f%s%5lu","ADC:",adc);
   }
}
 
void adc_init(void)
{
 
   //CONFIGURE PORT RB1/AN10 AS DIGITAL:
     TRISIOB_1=1; //CONFIGURE PIN RB1 AS INPUT.
 
   //CONFIGURE PIN AS ANALOG
      ANSELB_1=1;  // SET UP PIN RB1 AS ANALOG.
 
   //Select ADC conversion clock Fosc/64
      ADCON1_6=1;
      ADCON1_5=1;
      ADCON1_4=0;
 
   //Select Analog Channel 10 (AN10)
   //ADCON0 |=01010000;   
      ADCON0_6=0;
      ADCON0_5=1;
      ADCON0_4=0;
      ADCON0_3=1;
      ADCON0_2=0;
 
   //10 bit results should be right justified
    ADCON1_7=1;
}
 
int16 sample(void)
{
   // variable declaration
   int high;
   int low;
   int16 adc;
 
   //Disables the ADC interrupt
   PIE1_6=0;
   //Turn on the A2D converter
   ADCON0_0=1;
   delay_us(60);
   //start the conversion (Go)
   ADCON0_1=1;
   //wait for the acquisition time
   delay_us(60);

   //when ADCON0_1=1 the A2D conversion is not done
   while(ADCON0_1==1)

   //wait till the conversion is finished
   //Read the value of ADRESH and ADRESL
   high= ADRESH;
   low=  ADRESL;
 
   //store the resulting A2D conversion
   //high and low byte into one 16 bit variable
   adc=make16(high,low);
 
   return(adc);
}
temtronic



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

View user's profile Send private message

PostPosted: Wed Nov 13, 2013 12:26 pm     Reply with quote

general comments.
without trying your code( I don't have tht PIC here...)...

1) dump the listing of the program that does work as well as your program that doesn't.

2) see what /how CCS does their code and compare the steps/code you've used

3)providing you follow what CCS has done, yours should work.

4) pay special attention to setting the TRISx registers as you're using fastio()! One wrong bit will spoil your day.

5) does the CCS one have the same code? like usingI2C() ? same fuses, etc.

6) also check that the addresses are correct,again a slip here is a bummer !!

7) might be a compiler version problem but I doubt it as CCS code works...

8) when configuring ports/ registers be sure to clear bits as well as set the correct ones.If you don't , you might get 'random' configurations( ie: wrong).

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 13, 2013 12:27 pm     Reply with quote

Quote:
The built in A2D function works fine

Compile your program using CCS functions, then look at the .LST file and
see what CCS is doing. Compare your manual code to the CCS ASM
code in the .LST file. Try find what you are doing wrong. Put the .LST
file in Symbolic format in the Project options menu, so it will show register
names.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Nov 13, 2013 2:26 pm     Reply with quote

what IS IT that are you trying to DO with the ADC that is not bundled already into the very simple , but elegant CCS intrinsics for ADC operation?

you are exerting immense effort in reinventing a wheel that is already highly polished and very efficient code wise,
as reading the ADC section of the CCS user manual will quickly reveal.
Ttelmah



Joined: 11 Mar 2010
Posts: 19563

View user's profile Send private message

PostPosted: Wed Nov 13, 2013 3:05 pm     Reply with quote

Agree totally with Asmboy here.
However some comments:

1) You are assuming values on the bits you don't set in the registers - may well not be what you expect.
2) Use register names, and bit names. It is too easy to get an address/bit wrong. The compiler allows you to access registers and bits by name.
So:
Code:

#byte ADCON0=getenv("SFR:ADCON0")

Makes it much more portable, and less likely to have errors.
3) Your comments disagree with your actions. So:
Code:

   //Select Analog Channel 10 (AN10)
   //ADCON0 |=01010000;   
      ADCON0_6=0;
      ADCON0_5=1;
      ADCON0_4=0;
      ADCON0_3=1;
      ADCON0_2=0;

generates x01010xx

one bit out of alignment with your commented mask....

Best Wishes
kbruin79



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

PostPosted: Wed Nov 13, 2013 6:43 pm     Reply with quote

I got it working now. It turns out that even though the Vref- and Vref+ in ADCON1 are setup by default to '0' once I explicitly made them '0' I started getting the right result.

I never thought this step was necessary, why would it be? I didn't modify the default register bit for the Vref- and + in ADCON1.


Thanks again for the help.
kbruin79



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

PostPosted: Wed Nov 13, 2013 6:47 pm     Reply with quote

asmboy wrote:
what IS IT that are you trying to DO with the ADC that is not bundled already into the very simple , but elegant CCS intrinsics for ADC operation?

you are exerting immense effort in reinventing a wheel that is already highly polished and very efficient code wise,
as reading the ADC section of the CCS user manual will quickly reveal.


Agreed, however this will help me better understand the sequence of the analog to digital conversion and how it works.
Ttelmah



Joined: 11 Mar 2010
Posts: 19563

View user's profile Send private message

PostPosted: Thu Nov 14, 2013 1:26 am     Reply with quote

kbruin79 wrote:
I got it working now. It turns out that even though the Vref- and Vref+ in ADCON1 are setup by default to '0' once I explicitly made them '0' I started getting the right result.

I never thought this step was necessary, why would it be? I didn't modify the default register bit for the Vref- and + in ADCON1.


Thanks again for the help.


As I said:
"You are assuming values on the bits you don't set in the registers - may well not be what you expect."

You may even find values change from chip to chip. Also the compiler will default (on some versions) to setting all ports to digital unless told to do otherwise, so may well set bit values in the configuration registers.

Generally, _never_ assume a bit has a value, unless you have set it.

Best Wishes
kbruin79



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

PostPosted: Thu Nov 14, 2013 8:03 am     Reply with quote

Ttelmah wrote:
kbruin79 wrote:
I got it working now. It turns out that even though the Vref- and Vref+ in ADCON1 are setup by default to '0' once I explicitly made them '0' I started getting the right result.

I never thought this step was necessary, why would it be? I didn't modify the default register bit for the Vref- and + in ADCON1.


Thanks again for the help.


As I said:
"You are assuming values on the bits you don't set in the registers - may well not be what you expect."

Generally, _never_ assume a bit has a value, unless you have set it.

Best Wishes


Thanks again, great advice
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