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

16F1503 Internal Temperature Indicator

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



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

16F1503 Internal Temperature Indicator
PostPosted: Sat May 19, 2012 8:59 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat May 19, 2012 8:13 pm     Reply with quote

What's the Vdd voltage for the PIC on your board ?
Sam_63



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

PostPosted: Sun May 20, 2012 7:46 am     Reply with quote

A regulated 2.5Vdc source
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 20, 2012 3:28 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun May 20, 2012 6:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun May 20, 2012 11:00 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun May 20, 2012 11:26 pm     Reply with quote

Post your latest test program.
Sam_63



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

PostPosted: Sun May 20, 2012 11:58 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 21, 2012 12:44 am     Reply with quote

BTW, I use

http://www.bb-elec.com/bb-elec/literature/232LPTTL-3406ds.pdf
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon May 21, 2012 1:47 am     Reply with 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();

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

View user's profile Send private message

PostPosted: Mon May 21, 2012 8:21 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Mon May 21, 2012 8:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 21, 2012 11:54 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Mon May 21, 2012 12:41 pm     Reply with quote

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
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