|
|
View previous topic :: View next topic |
Author |
Message |
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
16F1503 Internal Temperature Indicator |
Posted: Sat May 19, 2012 8:59 am |
|
|
Has anyone successively used the Internal temperature indicator on the 16f1503?
Seems simple enough but the decimal level at 20C returning back for the ADC read appears to be exceeding the 10bit ADC (e.g.>1023).
Reference Application
Note AN1333, “Use and Calibration of the Internal
Temperature Indicator” (DS01333) for more details
regarding the calibration process.
BTW, eq. #3 and #4 should be read 0.00132 NOT "0.0132"
using PCM Ver. 4.132
Code: |
#include <16LF1503.h>
#device adc=10;
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT
#use delay(clock=8000000)
#include <STDLIB.h>
signed int16 adcQuery();
signed int16 eStopInt;
void main(void)
{
setup_vref(VREF_OFF | VREF_ADC_OFF | TEMPERATURE_INDICATOR_ENABLED | TEMPERATURE_RANGE_LOW);
setup_adc(adc_clock_internal);
while(1)
{
//reading external temp sensor here that is working, switch now to internal temp
set_adc_channel(TEMPERATURE_INDICATOR);
delay_us(200);
eStopInt = adcQuery();
if(eStoptInt >= 1000) //falls in here at 20C
{
while(1)//blink some lights
{
output_high(PIN_C1);//red on
delay_ms(500);
output_low(PIN_C1);//red off
output_high(PIN_C2);//green on
delay_ms(500);
output_low(PIN_C2);//green off
}
}
}
signed int16 adcQuery()
{
signed int16 errorValues;
read_adc(ADC_START_ONLY);
int1 done = adc_done();
while(!done)
{
done = adc_done();
}
errorValues = read_adc();
return errorValues;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 19, 2012 8:13 pm |
|
|
What's the Vdd voltage for the PIC on your board ? |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sun May 20, 2012 7:46 am |
|
|
A regulated 2.5Vdc source |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 20, 2012 3:28 pm |
|
|
I don't have a 16LF1503. I do have a 16F1507. It's not the LF version,
but it will run OK at a Vdd of 2.5v, according to the data sheet.
I ran it on a Microchip "Low Pin Count" board. I used a bench power
supply to power the board with +2.5v. I installed compiler vs. 4.132.
I used a Sparkfun RS232 Level Shifter to send the output to a TeraTerm
window on my PC. I used a software UART on pin B6 of the 16F1507
and connected it to the RX-I pin on the Sparkfun board. I also connected
the Vcc and Gnd pins on the Sparkfun board to Vdd and Vss on the Low
Pin Count board. http://www.sparkfun.com/products/449
I ran the test program shown below and I got these results. The results
are not very accurate (I think they calculate out to 13 degrees C, and
it's probably really about 24 deg. C in this room). But at least they
are within the gross expected range.
Quote: |
542
542
542
541
542
542
542
542
541
|
Test program:
Code: |
#include <16F1507.H>
#device adc=10
#fuses INTRC_IO, NOWDT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_B6)
//==========================================
void main()
{
int16 result;
printf("Start:\n\r");
setup_vref(TEMPERATURE_INDICATOR_ENABLED | TEMPERATURE_RANGE_LOW);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(TEMPERATURE_INDICATOR);
delay_us(200);
while(1)
{
result = read_adc();
printf("%lu \n\r", result);
delay_ms(500);
}
} |
I didn't look at the .LST file to see if all the registers are being setup
correctly. At this point, I just wanted to run this simple test. |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sun May 20, 2012 6:32 pm |
|
|
Well hell........that's what I wanted!!.......hmmm, mine should have ran fine as is.
I'll follow your lead and shut off the analog inputs and reduce the sample speed. I'll get back to ya, thx |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sun May 20, 2012 11:00 pm |
|
|
Start:
1023
1023
1023
1023
1023
1023
1023
1023
1023
1023
1023
1023
hmmmmm, perhaps my chip is broke. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 20, 2012 11:26 pm |
|
|
Post your latest test program. |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sun May 20, 2012 11:58 pm |
|
|
Code: |
#include <16LF1503.h>
#device adc=10;
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C4)
#include <STDLIB.h>
signed int16 adcQuery();
int16 eStopInt;
void main(void)
{
setup_vref(TEMPERATURE_INDICATOR_ENABLED | TEMPERATURE_RANGE_LOW);
//setup_adc_ports(sAN0 | sAN7 | VSS_VDD);
setup_adc_ports(NO_ANALOGS);
//setup_adc(adc_clock_internal);
setup_adc(ADC_CLOCK_DIV_8);
printf("Start:\n\r");
while(1)
{
set_adc_channel(TEMPERATURE_INDICATOR);
delay_us(200);
eStopInt = 0;
eStopInt = adcQuery();
if(eStopInt >= 1000)
{
while(1)
{
printf("%lu \n\r", eStopInt);
output_high(PIN_C1);//red on
delay_ms(500);
output_low(PIN_C1);//red off
output_high(PIN_C2);//green on
delay_ms(500);
output_low(PIN_C2);//green off
}
}
}
signed int16 adcQuery()
{
signed int16 errorValues;
read_adc(ADC_START_ONLY);
int1 done = adc_done();
while(!done)
{
done = adc_done();
}
errorValues = read_adc();
return errorValues;
}
|
|
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19447
|
|
Posted: Mon May 21, 2012 1:47 am |
|
|
First thing, use C.....
C, _does not allow variables to be declared mid function. The 'technical' wording, is that variables _must_ be declared at the start of the function, or at the start of a code block. Now, CCS does not complain if you declare variables mid function, but the results are code that works erratically.
Second thing is that CCS, _does not allow variables to be declared and assigned values from functions in one line_. Constant allocations only.
So, in one line, you have two errors:
int1 done = adc_done();
Illegal both in C in general, and in CCS specifically.
It doesn't actually matter, since having started the ADC, you then start it again, with:
errorValues = read_adc();
What does 'read_adc, without any values in the brackets do?.
Your entire 'adcQuery function, does nothing more than read_adc on it's own, except waste some time, and potentially have problems because of incorrect coding....
Then as a comment, is an integer from the ADC signed?. You return the value as signed, and then convert it to unsigned in the main code. Pointless, messy, and a sign of not actually thinking about the implications of what you are doing. Compare PCM programmers code, to your's.
Best Wishes |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Mon May 21, 2012 8:21 am |
|
|
Quote: |
First thing, use C.....
C, _does not allow variables to be declared mid function. The 'technical' wording, is that variables _must_ be declared at the start of the function, or at the start of a code block. Now, CCS does not complain if you declare variables mid function, but the results are code that works erratically.
Second thing is that CCS, _does not allow variables to be declared and assigned values from functions in one line_. Constant allocations only.
So, in one line, you have two errors:
int1 done = adc_done();
|
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf (page 156)
Quote: | Illegal both in C in general, and in CCS specifically.
It doesn't actually matter, since having started the ADC, you then start it again, with:
errorValues = read_adc();
What does 'read_adc, without any values in the brackets do?.
|
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf (page 220)
Quote: | Your entire 'adcQuery function, does nothing more than read_adc on it's own, except waste some time, and potentially have problems because of incorrect coding....
|
This is true.........I have several calls to this function (not shown), very clean and quite standard practice unless one would want to re-write same code for each call to a adc read? Noooo....bad practice!!
Quote: | Then as a comment, is an integer from the ADC signed?. You return the value as signed, and then convert it to unsigned in the main code. Pointless, messy, and a sign of not actually thinking about the implications of what you are doing. Compare PCM programmers code, to your's.
|
Yes, there was a type change that should have required a typecast, I saw it but, this was just merely a quick test PCM and I were running, the print statements we added were actually having a problem with the signed types.
Best wishes to you as well my friend...... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19447
|
|
Posted: Mon May 21, 2012 8:39 am |
|
|
The 'example' in the CCS manual page you show, is faulty....
It explains why a lot of people recently have been using this type of construct.....
Simple thing though, it doesn't work.
Declaring 'in code', is a C++ feature, not C, but sometimes works. Allocating a value with the declaration, is legal in most C's, but not in CCS. I'd suspect the manual author 'borrowed' this bit from another C, and that possibly CCS are trying to switch to allowing this. However in common with most 'new' features with CCS, you can reckon on at least 50 compiler versions being needed before it actually works OK.
One thing 'critical' with CCS, is to keep to the 'lowest subset', of original K&R features, and CCS features. Trying anything beyond this is likely to lead to failure.
In fact their example here is not just wrong, but will cause invalid readings.
The ADC has to _wait_ for Tacq after a reading has been performed, before the capacitor can re-acquire the incoming voltage, and another reading can be taken. The fact that 'done' won't be initialised properly doesn't matter, since they load the value inside the do loop before they test. However they wait for the conversion to finish, and then instead of reading the result (read_adc(ADC_READ_ONLY)), call 'read_adc' again, which if called with no value in the brackets _immediately_ triggers a new conversion (which is what I was pointing out), and waits for this to complete. It is the result of this second conversion which is then read. At this point you have an invalid result because of the lack of Tacq.....
A really c&*p piece of coding. Worth about -9 on a scale of 0 to 10 as an 'example'...
Best Wishes |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Mon May 21, 2012 11:54 am |
|
|
Quote: | One thing 'critical' with CCS, is to keep to the 'lowest subset', of original K&R features, and CCS features. Trying anything beyond this is likely to lead to failure. |
int1 done = adc_done(); this type goes back to C89? if not C90 does it not? I'll have to look at my K&R books. Regardless.....I haven't had any CCS issues with this though.
Quote: | In fact their example here is not just wrong, but will cause invalid readings.
The ADC has to _wait_ for Tacq after a reading has been performed, before the capacitor can re-acquire the incoming voltage, and another reading can be taken. The fact that 'done' won't be initialised properly doesn't matter, since they load the value inside the do loop before they test. However they wait for the conversion to finish, and then instead of reading the result (read_adc(ADC_READ_ONLY)), call 'read_adc' again, which if called with no value in the brackets _immediately_ triggers a new conversion (which is what I was pointing out), and waits for this to complete. It is the result of this second conversion which is then read. At this point you have an invalid result because of the lack of Tacq.....
A really c&*p piece of coding. Worth about -9 on a scale of 0 to 10 as an 'example'... |
I see your point here on this one and agree that if errorValues = read_adc(); is in fact restarting the entire acquisition process over, the code "start_only" and "wait_till_done" is pointless then....agreed. Looking further into it, CCS isn't/wasn't too clear on the process/es of the function without a optional "mode". I'll use errorValues = read_adc(ADC_READ_ONLY) and see what it returns. I haven't ran into any bugs with this code though reading in the other analog values.....all has been spot on BUT, this perhaps is a bit different beast beings it is ported differently. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19447
|
|
Posted: Mon May 21, 2012 12:41 pm |
|
|
Quote: |
"int1 done = adc_done(); this type goes back to C89? if not C90 does it not? I'll have to look at my K&R books. Regardless.....I haven't had any CCS issues with this though."
|
Yes, as I said originally. This one is legal in most C's, but _not_ in CCS. Values can only be initialised in a declaration, with a constant, not from a function.
Best Wishes |
|
|
|
|
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
|