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 support@ccsinfo.com

Help:Code gives different results on different hardware.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

Help:Code gives different results on different hardware.
PostPosted: Fri Jun 25, 2010 7:31 am     Reply with quote

The following code give different values on supposedly identical prototype boards.
Code:

//Calculation of execution time.

#include <16f877A.h>
#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("\r\n Ticks=%lu",time);   //Ticks to do a=b*c
}


The code gives a Timer1 tick value of approx 211, but may go as high as 231, for exactly the same hex files. The value differs randomly between boards, and on the same board for whatever else you can think of. We've talked to the instructior and he has no idea what the problem may be. The point is: because the same instructions are executed on each try, we should NOT get a difference. The xtal freq does NOT effect the result.

We are students in a course. We were all given the same proto boards (seen at http://www.ccsinfo.com/product_info.php?products_id=16F877Akit). The school has the CCS C Compiler V3.170b,and we use a PICKit 2 Programmer (seen here http://www.canakit.com/pic-programmer.html?gclid=CODLz8-nu6ICFSQ65QodAyHY6A). The two devices are connected via an RJ12 cable. The proto board has its own power. The Programmer is powered via the USB port. It is set NOT to power the proto board. The proto board uses a 20 MHz xtal.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 7:58 am     Reply with quote

I see 2 potential problems with your code although these do not explain the isuue you are having.

1. a = b * c;

As b and c are not assigned and a is not used after this the compiler *may* optimise this out. Check your .lst file to make sure it is doing the math.

2. I am amazed you are seeing the full output because as soon as the printf is executed the pic will go to sleep. this should prevent the last 2 chars being sent as the uart will be turned off. Put a while(true); at the end.

[*edit*]
Actually, isn't there a delay after writing to the timer before the timer is set with the correct value, that might be the 2 ticks you are subtracting and if the calculation is not being done you could be reading a random value from the timer before it has had a chance to be updated. [*edit*] I think I am talking rubish here Smile


Last edited by Wayne_ on Fri Jun 25, 2010 8:07 am; edited 1 time in total
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 8:06 am     Reply with quote

Wayne_ wrote:
I see 2 potential problems with your code although these do not explain the issue you are having.

1. a = b * c;

As b and c are not assigned and a is not used after this the compiler *may* optimise this out. Check your .lst file to make sure it is doing the math.

2. I am amazed you are seeing the full output because as soon as the printf is executed the pic will go to sleep. this should prevent the last 2 chars being sent as the uart will be turned off. Put a while(true); at the end.


Re (2): Now THAT was a really helpful comment. It probably explains why we get bad behavior from printf. I will pass it on to the rest of the bunch.

Re (1): Yes, it may optimize, but you are right, it should have no effect on the results because we use the same hex file.
Ttelmah



Joined: 11 Mar 2010
Posts: 19330

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 9:32 am     Reply with quote

It will....
You are not initialising 'b', or 'c' to values.
Though the maths takes _similar_ times for different values, the time will vary a little.
Try adding a line to initialise b, and c, like:
Code:

   a=0x0000;b=0x0000;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this

Now try with say:
Code:

   a=0xFFFF;b=0xFFFF;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this

Note that now the times are the same with different hardware, but differ in the first case, and second case.

Best Wishes
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 12:00 pm     Reply with quote

Sorry, fellows, I didn't think those ideas make any difference. I tried the code below
Code:
 //Lab13B V3 Calculation of execution time.
#include <16f877A.h>
#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   b=0;
   c=0;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu \n\r",time);   //Ticks to do a=b*c
   while(1);
}

and by repeated use of the Reset button (not to trustworthy, it seems - I got...
Code:
 Ticks=                                                                             
 Ticks=211                                                                         
 Ticks=                                                                             
 Ticks=211                                                                         
 Ticks=                                                                             
 Ticks=211                                                                         
 Ticks=703                                                                         
 Ticks=/9573                                                                       
 Ticks=51                                                                           
 Ticks=211                                                                         
 Ticks=213                                                                         
 Ticks=211                                                                         
 Ticks=211                                                                         
 Ticks=211                                                                         
 Ticks=                                                                             
 Ticks=211                                                                         
 Ticks=218                                                                         
 Ticks=211                                                                         
 Ticks=211                                                                         
 Ticks= 0211                                                                       
 Ticks=211                                                                         
 Ticks=5i=8e                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i                                                                           
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82                                                                       
 Ticks=5i=82 Ticks=6dv3j                                                           
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j                                                                         
Ticks=6dv3j  Ticks=6dv3j                                                           
                                                                                   

The timing is more consistent now. But the output is still erratic.

Lou.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 12:40 pm     Reply with quote

1. Add BROWNOUT to the #fuses statement.

2. Add the ERRORS parameter to the #use rs232() statement.

3. Don't run the program in Debug mode. Comment out the Device
ICD=TRUE statement. Re-compile and use the Programmer menu.
Run it as a stand-alone program.

See if this helps.
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Fri Jun 25, 2010 8:19 pm     Reply with quote

-Have you got a noisy supply?
-Have you got a pull up on MCLR?

Could you please post results for this code:
Code:
while(1)
{   
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu \n\r",time);   //Ticks to do a=b*c
   delay_ms(10);    //or any appropriate value
}
Put this code after setting up the timer.

Rohit
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 26, 2010 9:28 am     Reply with quote

PCM programmer wrote:
1. Add BROWNOUT to the #fuses statement.

2. Add the ERRORS parameter to the #use rs232() statement.

3. Don't run the program in Debug mode. Comment out the Device
ICD=TRUE statement. Re-compile and use the Programmer menu.
Run it as a stand-alone program.

See if this helps.

Big difference; see the code and output below. I do not know what to do with the ERRORS result.
The reset button was used for each occurrence of the printf. The same results were obtained with and without the PICkit 2 Programmer connected.

What is the significance of these changes - especially the BROWNOUT? I would have thought it should be NOBROWNOUT.
And the NODEBUG?

The output without the while(1){} is significant; the ending LFCR is missing on EACH reset.
Code:

//Lab13B V Calculation of execution time.
#include <16f877A.h>
#fuses HS, NOLVP, NOWDT, PUT, NODEBUG, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   b=0;
   c=0;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu\n\r",time);   //Ticks to do a=b*c
   while(1){};
}

Without while(1){};
Code:

Ticks=211Ticks=211 Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211
Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211Ticks=211T
icks=211Ticks=211Ticks=211Ticks=211Ticks=211

With while(1){};
Code:

Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               

I will try the next suggestions form Rohit de Sa, but pls explain these.
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 26, 2010 9:56 am     Reply with quote

Rohit de Sa wrote:
-Have you got a noisy supply?
-Have you got a pull up on MCLR?

Could you please post results for this code:
Code:
while(1)
{   
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu \n\r",time);   //Ticks to do a=b*c
   delay_ms(10);    //or any appropriate value
}
Put this code after setting up the timer.

Rohit

The board has a pull-up resistor on !MCLR.
Your code works. I assume it was simply an experiment, but I'm not sure what it proves.
I had to replace the 10 ms with 1000 ms after several tries because the serial port monitor (C compiler tool) could not keep up. Its output is constant, and 211 is, I assume the correct answer. Later I added
#device ICD=TRUE and it did not output anything until it was reprogrammed several times.

I will let you all know if that value changes tomorrow <grin>

Re: power supply: We thought of this and we traded both boards and power supplies (9v adapters) independently, with the same erratic results and behavior.
Code:

//Lab13B X5 Calculation of execution time.
#include <16f877A.h>
#fuses HS, NOLVP, NOWDT, PUT//, NODEBUG, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main ()
{
    long time;
    long a,b,c;    b=0;
    c=0;
  //Set Timer1 as Timer mode from instruction clock.
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
    while (1)
   {
      set_timer1(0);         //Start the timer at value 0
      a=b*c;      //Calculate time to execute this
      time=get_timer1();    //Get the # of clock ticks.
      time-=2;         //Subtract overhead
      printf("Ticks=%lu\n\r",time);   //Ticks to do a=b*c
      delay_ms(1000);
    }
}
//Output on serial port monitor
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
Ticks=211                                                               
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 26, 2010 10:15 am     Reply with quote

Wayne_ wrote:

[*edit*]
Actually, isn't there a delay after writing to the timer before the timer is set with the correct value, that might be the 2 ticks you are subtracting and if the calculation is not being done you could be reading a random value from the timer before it has had a chance to be updated. [*edit*] I think I am talking rubbish here Smile

Well, if you go execute the new code (below), the result is 2 ticks. That is the overhead of the setup_timer and the set_timer1(0) code. The 211 ticks are the "computer-time" of the instruction a=b*c.

What is unclear to many is that the ticks values do not change with crystal speed. There be will the same number of ticks for every 16F877A for 20Mhz xtal as for 4Mhz xtal. But start another thread if you want to talk about this.
Code:

//Lab13B V4 Calculation of execution time.
#include <16f877A.h>
#fuses HS, NOLVP, NOWDT, PUT, NODEBUG, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   b=0;
   c=0;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
//   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
//   time-=2;         //Subtract overhead
   printf("Ticks=%lu\n\r",time);   //Ticks to do a=b*c
   while(1){};
}
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 26, 2010 10:25 am     Reply with quote

A sample problem with the new code. Note the ICD=TRUE. Why is the output in a sequence and why does it repeat??
Code:

//Lab13B V6 Calculation of execution time.
#include <16f877A.h>
#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT//, NODEBUG, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   b=0;
   c=0;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu\n\r",time);   //Ticks to do a=b*c
   while(1){};
}

For each reset button depression
Ticks=222
Ticks=223
Ticks=224
Ticks=226
Ticks=227
Ticks=228
Ticks=229
Ticks=218
Ticks=219
Ticks=221
Ticks=222
Ticks=223
Ticks=224
Ticks=226
Ticks=227


Last edited by louarnold on Sat Jun 26, 2010 11:34 am; edited 1 time in total
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 26, 2010 11:08 am     Reply with quote

Here is some more analysis. It would be helpful if someone could explain the reason for the results.
Code:

//Lab13B V7 Calculation of execution time.
#include <16f877A.h>
//#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT
//#fuses NODEBUG
//#fuses BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main ()
{
   long time;
   long a,b,c;   //was int a,b,c;
   b=0;
   c=0;
   //Set Timer1 as Timer mode from instruction clock.
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);         //Start the timer at value 0
   a=b*c;      //Calculate time to execute this
   time=get_timer1();    //Get the # of clock ticks.
   time-=2;         //Subtract overhead
   printf("Ticks=%lu\n\r",time);   //Ticks to do a=b*c
   while(1){};
}

PIC 16F877A Fuses and ICD=TRUE - Calculation of ticks for a=b*c
#device ICD=TRUE ("added" means not commented out)
#fuse NODEUG ("omitted" means line is commented out)
#fuse BROWNOUT

Conclusion: You should have ICD=TRUE with NODEBUG for proper results, otherwise do not use ICD=TRUE.
BROWNOUT makes no difference.
Code:

ICD=TRUE    BROWNOUT    NODEBUG    Result(Reset button)
added       added       omitted    repeated 218 to 227
added       omitted     omitted    repeated 218 to 227
added       omitted     added      ticks=211
added       added       added      repeated 218 to 227
omitted     omitted     omitted    ticks=211
omitted     added       omitted    ticks=211
omitted     omitted     added      ticks=211
omitted     added       added      ticks=211


Last edited by louarnold on Mon Jun 28, 2010 7:52 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 27, 2010 5:09 pm     Reply with quote

I can't duplicate your problem. I don't have your test setup. I have an
ICD2. I believe you have a PicKit2. I tested it with vs. 4.109. I used
"Programmer" mode in MPLAB (not Debugger mode). I used your latest
program with this configuration:
Code:

#include <16f877A.h>
#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

This is one of the configurations that fails for you, but it works for me:
Quote:

Ticks=213
Ticks=213
Ticks=213
Ticks=213
Ticks=213
Ticks=213

I assume it's a peculiarity of the PicKit2 and/or your test setup.
I recommend that you don't do software timings in Debug mode.
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Mon Jun 28, 2010 6:19 am     Reply with quote

PCM programmer wrote:
I can't duplicate your problem. I don't have your test setup. I have an
ICD2. I believe you have a PicKit2. I tested it with vs. 4.109. I used
"Programmer" mode in MPLAB (not Debugger mode).
--snip--
I assume it's a peculiarity of the PicKit2 and/or your test setup.
I recommend that you don't do software timings in Debug mode.

I agree; its likely the test set-up.
As for the code, it was given to us, left over from a previous course when an ICD was used. We no longer have an ICD, and we debug by printf. The compiler menu option Debug, shows the debugger disabled, but I assume that when ICD=TRUE, then Debug is in effect.

You recommended these changes; can you explain what ICD=TRUE does?
I know what BROWNOUT does, but how would it have helped here?

I assume DEBUG would leave hooks somewhere for the debugger, but as we set no breakpoints, I am at a loss to understand why it makes a difference. Can you explain?


Last edited by louarnold on Mon Jun 28, 2010 8:10 am; edited 2 times in total
louarnold



Joined: 13 May 2010
Posts: 42
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Mon Jun 28, 2010 8:02 am     Reply with quote

PCM programmer wrote:
I can't duplicate your problem. I don't have your test setup. I have an
ICD2. I believe you have a PicKit2. I tested it with vs. 4.109. I used
"Programmer" mode in MPLAB (not Debugger mode). I used your latest
program with this configuration:
Code:

#include <16f877A.h>
#device ICD=TRUE
#fuses HS, NOLVP, NOWDT, PUT, BROWNOUT
#use delay (clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

This is one of the configurations that fails for you, but it works for me:
Quote:

Ticks=213
Ticks=213
Ticks=213
Ticks=213
Ticks=213
Ticks=213

I assume it's a peculiarity of the PicKit2 and/or your test setup.
I recommend that you don't do software timings in Debug mode.

I tried it again with my set-up. The output was intermittent with the reset button - sometimes nothing, and other times "ticks=211", but then it went into the sequence again - 218,218...229,218,219, etc.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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