ADC from a PIC 16f877a

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

ADC from a PIC 16f877a

Post by Henk »

Hi there,

I would like to use the 10 bits function of FlowCode 3.0.

I have a program in mind in which I have to divide 0,521V over 27 bits. This limits my calculation options.

To solve this, I want to make use of the VREF+ with 4,830V on it and I’ll put 4,309V on the VREF-

That way I have 0,521V to divide over 1024 bits which gives me more calculation options.

How can I activate and use the 10 bits ADC functions in FlowCode 3.0 for this.



Kind regards,

Henk Middendorp

The Netherlands

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Henk

To do this you will have to create your own ADC routine which enables these registers on the PIC. the easiest way todo this is to create a flowcode program with an ADC sample routine and then compile it to C and copy / change the parts that need editing (refer to the PICmicro datasheet for this). You can then include this C code into your flowcode program by placing #include"somename.c" in the supplementary code and calling the C functions using the C code icons.

User avatar
Steve
Matrix Staff
Posts: 3418
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Post by Steve »

The ADC component's GetValue function returns the whole 10-bit value.

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Supplementary code

Post by Henk »

Benj wrote:Hello Henk

To do this you will have to create your own ADC routine which enables these registers on the PIC. the easiest way todo this is to create a flowcode program with an ADC sample routine and then compile it to C and copy / change the parts that need editing (refer to the PICmicro datasheet for this). You can then include this C code into your flowcode program by placing #include"somename.c" in the supplementary code and calling the C functions using the C code icons.

Hello Ben,
I have ceated a flowcode programm and I use 3 ADC components.
The first is ADC0 that is the variable value,
and than I have ADC2 VREF-
And I have ADC3 VREF+.
And than I compiled to C like you says
void FCD_ADC0_SampleADC()
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (0 << 3);
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;
What must 1 chance in this programm?

And then you says>>in the supplementary code and calling the C functions using the C code icons<<.
How must Iuse the supplementary code?

Regards Henk.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Henk

To use the supplementary code you do the following.

Insert your function into the function implementations box.

void FCD_ADC0_SampleADC()
{
char ta, te, cnt;
...
}

Then in the definitions box enter the function prototype.

void FCD_ADC0_SampleADC();

You can now call the function from flowcode using a c code icon.

FCD_ADC0_SampleADC();

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Benj wrote:Hello Henk

To use the supplementary code you do the following.

Insert your function into the function implementations box.

void FCD_ADC0_SampleADC()
{
char ta, te, cnt;
...
}

Then in the definitions box enter the function prototype.

void FCD_ADC0_SampleADC();

You can now call the function from flowcode using a c code icon.

FCD_ADC0_SampleADC();
Hi ben
Must I also use the clock conversion in Flowcode with a C-Code icon
If its so witchs line must I use.
ADCS1:ADCS0: A/D Conversion Clock Select bits (ADCON0 bits in bold)
ADCON1
<ADCS2>
ADCON0
<ADCS1:ADCS0> Clock Conversion
0 00 FOSC/2
0 01 FOSC/8
0 10 FOSC/32
0 11 FRC (clock derived from the internal A/D RC oscillator)
1 00 FOSC/4
1 01 FOSC/16
1 10 FOSC/64
1 11 FRC (clock derived from the internal A/D RC oscillator)

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello

The conversion clock is alread set to Fosc / 64. you could change this for example to the internal RC clock by changing the line

Code: Select all

adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64
to

Code: Select all

adcon0 = 0xC1 | (Channel << 3);      //Set Internal RC
The Channel variable will let you sample from more then one Analog input.

Code: Select all

//Function Prototype
void FCD_ADC0_SampleADC(char Channel);

//Function Implementation
void FCD_ADC0_SampleADC(char Channel)
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64 and AN channel
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80; 
}

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Benj wrote:Hello

The conversion clock is alread set to Fosc / 64. you could change this for example to the internal RC clock by changing the line

Code: Select all

adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64
to

Code: Select all

adcon0 = 0xC1 | (Channel << 3);      //Set Internal RC
The Channel variable will let you sample from more then one Analog input.

Code: Select all

//Function Prototype
void FCD_ADC0_SampleADC(char Channel);

//Function Implementation
void FCD_ADC0_SampleADC(char Channel)
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64 and AN channel
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80; 
}
Hello Ben,

I have done all the things you have told me but it don't works. What is wrong?
Maybe you have one example so that I can sie what I must write in to the defenitie en fucntiedeclaraties box en what must Iwrite in to the Functie implementatiebox?
And where must I write the variabele?

Kind regards
Henk.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello

Sorry I only gave the code for the sample routine.

Definitions and declarations

Code: Select all

//Function Prototypes
void FCD_ADC0_SampleADC(char Channel); 
int FCD_ADC0_GetVal(void);
Function Implementations

Code: Select all

void FCD_ADC0_SampleADC(char Channel)
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64 and AN channel
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;
}

int FCD_ADC0_GetVal(void)
{
	short iRetVal;
	iRetVal = (adresh << 2);
	iRetVal += (adresl >> 6);
	return (iRetVal);
}
Setup two Flowcode variables and assign values.
One of the variables takes the address of the ADC channel eg 0 - 7
The other variable must be of type int and stores the return value.

The two variables names are Chan and RetVal

C code Icon calls

Code: Select all

FCD_ADC0_SampleADC(FCV_CHAN); 
FCV_RETVAL = FCD_ADC0_GetVal();

User avatar
Steve
Matrix Staff
Posts: 3418
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Post by Steve »

The function names may also cause a problem with compilation if you have an ADC component added to Flowcode.

You might want to rename these functions (the declarations and the function calls) to something like "ADC_Sample" and "ADC_GetVal" instead to be on the safe side.

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Benj wrote:Hello

Sorry I only gave the code for the sample routine.

Definitions and declarations

Code: Select all

//Function Prototypes
void FCD_ADC0_SampleADC(char Channel); 
int FCD_ADC0_GetVal(void);
Function Implementations

Code: Select all

void FCD_ADC0_SampleADC(char Channel)
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64 and AN channel
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;
}

int FCD_ADC0_GetVal(void)
{
	short iRetVal;
	iRetVal = (adresh << 2);
	iRetVal += (adresl >> 6);
	return (iRetVal);
}
Setup two Flowcode variables and assign values.
One of the variables takes the address of the ADC channel eg 0 - 7
The other variable must be of type int and stores the return value.

The two variables names are Chan and RetVal

C code Icon calls

Code: Select all

FCD_ADC0_SampleADC(FCV_CHAN); 
FCV_RETVAL = FCD_ADC0_GetVal();
Hello Ben,

I don't no of it works, first i going on a holiday sunday for 2 weeks.
Then I try the program and I let you no of it works.

Regards,
Henk.

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Henk wrote:
Benj wrote:Hello

Sorry I only gave the code for the sample routine.

Definitions and declarations

Code: Select all

//Function Prototypes
void FCD_ADC0_SampleADC(char Channel); 
int FCD_ADC0_GetVal(void);
Function Implementations

Code: Select all

void FCD_ADC0_SampleADC(char Channel)
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (Channel << 3);      //Set Fosc/64 and AN channel
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;
}

int FCD_ADC0_GetVal(void)
{
	short iRetVal;
	iRetVal = (adresh << 2);
	iRetVal += (adresl >> 6);
	return (iRetVal);
}
Setup two Flowcode variables and assign values.
One of the variables takes the address of the ADC channel eg 0 - 7
The other variable must be of type int and stores the return value.

The two variables names are Chan and RetVal

C code Icon calls

Code: Select all

FCD_ADC0_SampleADC(FCV_CHAN); 
FCV_RETVAL = FCD_ADC0_GetVal();
Hello Ben,

I don't no of it works, first i going on a holiday sunday for 2 weeks.
Then I try the program and I let you no of it works.

Regards,
Henk.
Hello Ben,

Now I have a program with 3 adc and i want to use an0 and vref- and vref+.
This is in the Supplementary code box>
void SampleADCMetVref()
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (0 << 3);
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;


}
void SampleADCMetVrefmin()
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (2 << 3);
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;


}

void SampleADCMetVrefplus()
{
char ta, te, cnt;
adcon1 = 0x00;
ta = trisa;
trisa = trisa | 0x2F;
te = trise;
trise = trise | 0x07;
adcon0 = 0x81 | (3 << 3);
cnt =0;
while (cnt <220) cnt++;
adcon0 = adcon0 | 0x04;
while (adcon0 & 0x04) ;
trisa = ta;
trise = te;
adcon1 = 0x0F;
adcon0 = 0x80;


}


And this in the Defenities and functiedeclaraties box<
void SampleADCMetVref();
void SampleADCMetVrefmin();
void SampleADCMetVrefpus();

My variable are
an0 and vref_min and_vref+
And I used 3xC-Code like SampleADCMetVref(); in my flowchart.

If I compile the programm to the pic I see three value's on my lcd.
If I turn the button an0, the value change.
If I turn the button vrefmin, the value change.
If I turn the button vref+, the value change.
Now the problem is that the value from an0 not change if I put the button vrefmin or vrefplus.

Can you tell me what wrong with this program?

Regards Henk.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello

All three of your sample functions contain exactly the same code.

You need to assign a different adcon1 value for the VRef+ and VRef-.

Code: Select all

//VREF+
char ta, te, cnt;
adcon1 = 0x01;
ta = trisa; 
...........

Code: Select all

//VREF-
char ta, te, cnt;
adcon1 = 0x08;
ta = trisa; 
...........

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Benj wrote:Hello

All three of your sample functions contain exactly the same code.

You need to assign a different adcon1 value for the VRef+ and VRef-.

Code: Select all

//VREF+
char ta, te, cnt;
adcon1 = 0x01;
ta = trisa; 
...........

Code: Select all

//VREF-
char ta, te, cnt;
adcon1 = 0x08;
ta = trisa; 
...........
Hello Ben,
I Idid what you says but now I put the button vref- than the value =1023,
and the vref+ value are 0 , and then I put on the vref+button then the value on the vref+ are 1023 and the vref- are 0.

Can I do sam more options to let it works.

Regards,
Henk.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Which ADC channel are you sampling.

If you refer to the device datasheet under ADC then you will see that the values that I picked convert one or two of the AN channels into the VREF channels.

Henk
Posts: 40
Joined: Sun May 20, 2007 11:03 am
Location: Nederland
Contact:

Post by Henk »

Benj wrote:Which ADC channel are you sampling.

If you refer to the device datasheet under ADC then you will see that the values that I picked convert one or two of the AN channels into the VREF channels.
In my programm I sampling the an0 and I use the variable an0 and read it as INT.( I see this on my LCD).Now the vref- and the vref+ is in the supplementary code, then I call with a C-Code block.
In my program I use only the sampling vref-(an2) and the vref+(an3).
The two variabel's are vref_min and vref_plus because I want to see this on my LCD.

Sorry my engels language is not so good but I try it.

Regards,
Henk

Post Reply