|
|
View previous topic :: View next topic |
Author |
Message |
nailuy
Joined: 21 Sep 2010 Posts: 159
|
VREF not working on 16F1936 |
Posted: Sat Jul 19, 2014 4:38 am |
|
|
Hy team I have problem by setting vref.
I try many sources of vref but not working.
I set value at input pin AN12/ B0: 0,339V and on display show 26 for 8bit, and 106 for 10bit ADC.
I try to change VREF to have better amplifier at this value but I can't.
Can someone help me? to understand why not working, or where is my mistake?
Voltage of VDD to VSS is 4.98V
Version of CCS 4.140.
Best regards.
Code: | void main()
{
port_E_pullups(0xFF);
setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12);
// setup_adc(ADC_CLOCK_DIV_4); //2,4,8,16,32,64
setup_adc(ADC_CLOCK_INTERNAL );
setup_vref(VREF_ADC_1v024); //1v024, 2v048, 4v096
// setup_vref(VREF_VDD);
setup_lcd(LCD_DISABLED);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_1MHZ|OSC_TIMER1|OSC_PLL_OFF,0);
LCD_INIT_1();
//LCD_SEND_C(%u,asd);
//LCD_SEND ("" %,asd);
//printf(LCD_SEND_C,"=%uV",123);
static unsigned int16 TIMER_LED, VAL;
while(TRUE)
{
TIMER_LED++;
//LCD_SEND_C
output_bit(ONBK,1);
//output_bit(LED,0);
set_adc_channel( 12 );
delay_us(30);
VAL = read_adc();
set_adc_channel( 10 );
switch (TIMER_LED) {
case 100: output_bit(LED,0);
break;
case 300: output_bit(LED,1);
TIMER_LED=0;
printf(LCD_SEND_C,"%4Lu",VAL);
LCD_DATA_3=0;
break;
default: ;
break; }
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Jul 19, 2014 7:53 am |
|
|
A lot of things....
First what is the minimum Vref the ADC is rated to use?. Parameter AD06 in the data sheet.
Then, though yours is one of the (few) chips which does not say _not_ to use ADC_CLOCK_INTERNAL, unless the CPU is put to sleep during the reading, you do still get better accuracy using the divided CPU clock. Fosc/2 at your clock rate. You have FOSC/4 selected in a remark, but not used.
Then get out of the habit of declaring variables mid code. This is 'borderline'. CCS accept it, but it is not legal in traditional C, and unfortunately has the habit of leading to 'sneaky' errors.
Then you enable channels 1,2,3,4 & 12 to the multiplexer, but later select adc_channel 10.....
Then the killers with the FVR....
Code: |
setup_adc(ADC_CLOCK_DIV_2|VSS_FVR); //Reference needs to be used..
setup_vref(VREF_ADC_2v024|VREF_ON); //needs to be turned on....
|
|
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Sat Jul 19, 2014 1:07 pm |
|
|
Thank you Ttelmah.
First what is the minimum Vref the ADC is rated to use?. Parameter AD06 in the data sheet.
Let say is 4,096V
Code: | setup_vref(VREF_ADC_4v096|VREF_ON); //1v024, 2v048, 4v096 |
Then, though yours is one of the (few) chips which does not say _not_ to use ADC_CLOCK_INTERNAL, unless the CPU is put to sleep during the reading, you do still get better accuracy using the divided CPU clock. Fosc/2 at your clock rate. You have FOSC/4 selected in a remark, but not used.
Now I use
Code: | setup_adc(ADC_CLOCK_DIV_4|VSS_FVR); |
Then you enable channels 1,2,3,4 & 12 to the multiplexer, but later select adc_channel 10.....
I know this I want to use to be sure that conversion exist because if I select this channel 10 result are 0 or 1, this model not support this.
At the final this solution is not working :(
Vref is at VDD, at 255 I have 4,98V on input CH1, or 100 at 1,831V :(
Code: |
setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12);
setup_adc(ADC_CLOCK_DIV_4|VSS_FVR); //2,4,8,16,32,64
setup_vref(VREF_ADC_4v096|VREF_ON); //1v024, 2v048, 4v096
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Sat Jul 19, 2014 1:56 pm |
|
|
Actually it is working, though without seeing your complete program makes it hard for us to see where you think there is a problem.
1) you've selected a Vref of 4.096 volts,so FSD will be 4.096 volts
2) you supply 5.00 to the ADC and get back 255 bits = 4.98 volts. That's actually a good result as FSD is 4.096, so 5.00 is 'overrange' of the ADC.
3) 100 bits with Vref of 4.096 is about 1.6 volts and you display 1.8. We don't know how you're converting ADC bits to display as 'real volts'.
Please show us your current program that gave those results.
Also you should read the raw Vin say 8 times and average it to reduce any 'glitch' or 'erroneous' readings.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Jul 19, 2014 2:13 pm |
|
|
and as one more comment, you risk destroying the chip.
The analog input must not go more than 0.3v above Vref.
Also the accuracy of the internal ref, is only +/-6%, and the ADC, +/-2.5 counts, so for an input of (say) 2.048 volts, you could get readings from different chips/temperatures etc., between 117 counts, and 138 counts. It is also very unlikely that the voltage you measure really 'is' 1.831v, unless you have a better than 0.1% DVM, that has been calibrated in the last few days.... |
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Sat Jul 19, 2014 3:08 pm |
|
|
I don't upset anybody but is my code made for LCD and problem is not from there so I can't post.
I copy from LST file.
Code: | .................... setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12);
022A: BCF 1E.0
022B: BCF 1E.1
022C: BCF 1E.2
022D: MOVLW 2E
022E: MOVLB 03
022F: MOVWF 0C
0230: MOVLW 01
0231: MOVWF 0D
.................... setup_adc(ADC_CLOCK_DIV_4|VSS_FVR); //2,4,8,16,32,64
0232: MOVLB 01
0233: BCF 1E.4
0234: BCF 1E.5
0235: BSF 1E.6
0236: BCF 1E.7
0237: BSF 1D.0
.................... setup_vref(VREF_ADC_2v048|VREF_ON); //1v024, 2v048, 4v096
0238: MOVLW 82
0239: MOVLB 02
023A: MOVWF 17
|
I look forward for solution also I search on web and in data sheet for this bug. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 20, 2014 1:45 am |
|
|
The parameter in bold is in the wrong place:
Quote: | setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12);
setup_adc(ADC_CLOCK_DIV_4 | VSS_FVR);
setup_vref(VREF_ADC_4v096|VREF_ON); |
According to the 16F1936.h file, it's supposed to go in setup_adc_ports(),
like this:
Code: | setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12|VSS_FVR); |
However, it doesn't produce the correct ASM code in the .LST file.
So I wrote a macro to replace the built-in setup_adc_ports() function.
See the code below:
Code: |
#include <16F1936.H>
#fuses INTRC_IO, BROWNOUT, PUT, NOLVP
#use delay(clock = 4M)
#use rs232(baud=9600, UART1, ERRORS)
//--------------------------------------
// This macro will replace the built-in setup_adc_ports()
// function which is not setting the ADPREF and ADNREF
// bits correctly. The macro fixes that problem.
#byte ANSELA = getenv("SFR:ANSELA")
#byte ANSELB = getenv("SFR:ANSELB")
#byte ADCON1 = getenv("SFR:ADCON1")
#bit ADPREF0 = ADCON1.0
#bit ADPREF1 = ADCON1.1
#bit ADNREF = ADCON1.2
#define setup_adc_ports(x) \
ANSELA = make8(x, 3); \
ANSELB = make8(x, 1); \
(make8(x, 0) & 1) ? (ADPREF0 = 1) : (ADPREF0 = 0); \
(make8(x, 0) & 2) ? (ADPREF1 = 1) : (ADPREF1 = 0); \
(make8(x, 0) & 4) ? (ADNREF = 1) : (ADNREF = 0);
//--------------------------------------
//==================================
void main()
{
setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12|VSS_FVR);
setup_adc(ADC_CLOCK_DIV_4);
setup_vref(VREF_ADC_2v048|VREF_ON);
while(1);
} |
Try that code and see if it fixes the problem. I don't have time tonight
to test it in hardware. If it doesn't work, I can do that tomorrow. |
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Sun Jul 20, 2014 4:54 am |
|
|
Thank you PCM programmer
I tried today and is working, your asm code is okay, now I try to learn how you do that to understand where is problem with data sheet.
Code: | setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12|VSS_FVR); |
This is correct syntax like you posted is written in header file.
Thanks again.
Now let's study this asm code.
If I have future question I will post in this thread.
Best regards.
Nailuy. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 05, 2014 10:53 am |
|
|
CCS tech support says it's not actually a bug. Instead, the Vref parameter
should be separated from the sANx parameters by a comma. Example:
Code: | setup_adc_ports(sAN1|sAN2|sAN3|sAN4|sAN12, VSS_FVR); |
This is in fact documented in the manual.
So, forget my work-around. It's not necessary. Do it as shown above. |
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Tue Sep 02, 2014 1:28 pm |
|
|
Yes is working until now. |
|
|
|
|
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
|