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

A little help on C!

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



Joined: 14 Jun 2006
Posts: 31

View user's profile Send private message

A little help on C!
PostPosted: Thu Jun 15, 2006 2:25 pm     Reply with quote

Hi,

I am doing the CCS exercise book and I am doing the example on interupts....

Please consider the following code:

//=====================================
#include <prototype.h>
#define PUSH_BUTTON PIN_A4

int16 overflow_count;

#int_timer1 //declaring a timer interupt function
timer1_isr()
{
overflow_count++;
}

void main()
{
int32 time; //declaring a 32 bit variable

setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //sets up an intrnl. timer
enable_interrupts(int_timer1); //enables interupts for timers

while(TRUE)
{
enable_interrupts(global); //enables official interupt scope

while(input(PUSH_BUTTON));
set_timer1(0); //resets timer
overflow_count = 0; //resets overflow count

while(!input(PUSH_BUTTON));
disable_interrupts(global); //disables official interrupt scope

time = get_timer1(); //get time value from timer1
time = time + ((int32) overflow_count<<16); //??????
time -= 15; //???????
printf("Time is %lu.%06lu seconds.\r\n",
time/5000000, (time/5)%1000000);
}
}

//============================================

I don't really understand the following lines:

time = time + ((int32) overflow_count<<16); //??????
time -= 15; //???????

Q1:
When I consider the first line:

time = time + ((int32) overflow_count<<16); //??????

I guess that we are shifting the "overflow_count" variable 16 bits to the left and then type casting it to a 32 bit type, However, right after the "disable_interrupts(global)" line, isn't overflow_count equal to 0? so why shift it 16 bits to the left?

Q2:
Why are we removing 15 from time?

All sincere feedback is appreciated!

Thanks

Regards
Roberto
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Jun 15, 2006 4:43 pm     Reply with quote

Quote:
Q1:
When I consider the first line:

time = time + ((int32) overflow_count<<16); //??????

I guess that we are shifting the "overflow_count" variable 16 bits to the left and then type casting it to a 32 bit type,
True.

Quote:
However, right after the "disable_interrupts(global)" line, isn't overflow_count equal to 0? so why shift it 16 bits to the left?
Look at the line right before disabling the interrupts
Code:
 while(!input(PUSH_BUTTON));
I don't like this notation, it is confusing. Normally I note it as the equal but easier to understand
Code:
 while(!input(PUSH_BUTTON))
    ;  // Do nothing
Here your program waits in a loop until you press a button. Because the interrupt for timer1 is enabled the function timer1_isr() will be called on every timer1 overflow and overflow_count is incremented. So when you press the button, the loop is exited and overflow_count contains the number of timer1 overflows.
Timer1 is only a 16 -bit timer, but by shifting left the overflow_count by 16 and storing it in a 32 bit integer you get the total number of Timer1 counts again (shift left 16 is an efficient way for multiplying by 2^16, or 65536).


Quote:
Q2:
Why are we removing 15 from time?
I'm not sure either why this was put in. That's why you always have to comment your code. Reading the code people can see what you are doing, but not why you are doing it.
My guess is that this is some smart [spam] correction for the small time error introduced by reading the timer values and shift instruction. The only way the original programmer could have deduced this magical number of 15 was by studying the generated assembly code. Depending on your compiler version and settings this will change, so don't consider this as good example code.
rougie



Joined: 14 Jun 2006
Posts: 31

View user's profile Send private message

Thanks Ckielstra
PostPosted: Thu Jun 15, 2006 5:11 pm     Reply with quote

I most thankyou for your reply, you are very kind!

Yes I agree with you also, that the 15 ticks x 2microseconds would compensate for the few lines before the prinf statement.

Allthough in all due respect, I was wondering if the program waits in a loop until you press a button? I actually thought that the program measured the time *while* the button was pressed. Hence:

while(!input(PUSH_BUTTON));

And once we let go the button, then we calculate the time! I don't know about you, but I am 4 days old in this CCSMicro PICS stuff, so I could be wrong!

All I know is that it took all afternoon to make sence of this code fragment!

Anyways, again I thankyou for your generous help!

Kind regards
Roberto
Ttelmah
Guest







PostPosted: Fri Jun 16, 2006 2:38 am     Reply with quote

Which way round the 'button' is, depends completely on the hardware. Assuming you have 'pull up' resistors, and the button to ground (the commonest configuration, given that the PIC has the possibility of internal 'pull up' resistors), then the button is pushed, when '!PUSH_BUTTON' is true, rather than when 'PUSH_BUTTON' is true. However the button can equally well be wired the other way round....
I must admit, this is the sort of thing where a bit of 'forethought' by the programmer, can make things a lot clearer. This is particularly important, where logic levels 'change' between parts of the circuit. For instance, a lot of my output drives, will be 'fail safe', and set to turn drivers off, and alarms on, if the power fails. Given that these will then probably drive through inverting logic to the actual signal, keeping track of all this is hard, whereas if this is all 'pre-done' in the defines, it makes things much easier to 'keep right'. Sofor example, my defines for a motor control system, moving a platform under processor control, are:
Code:

#define OVERRIDEON (input(OVERRIDE)==0)
#define OVERRIDEOFF (input(OVERRIDE)==1)
#define LOWSTOPON (input(LOWSTOP)==1)
#define LOWSTOPOFF (input(LOWSTOP)==0)
#define HIGHSTOPON (input(HIGHSTOP)==1)
#define HIGHSTOPOFF (input(HIGHSTOP)==0)

Now, notice that the high/low 'stop' inputs, use the opposite logic to the 'override' input. These all use inputs with pull up resistors, and if a cable fails on the limit switches (HIGHSTOP,and LOWSTOP), these signals will go 'on', and stop the platform. However a broken cale, will _stop_ the manual override from working. So the main code, instead of having to worry about whether the input requires positive, or negative logic can just test as:

//Moing upwards and upper limit reached
if (HIGHSTOPON && MOVINGUP) BRAKEON;

Here 'MOVINGUP' is a logic value, reflecting which way the motor is being driver, and 'BRAKEON', is a simlar define, outputting the values to stop the motor.
Now combined with the comment, a programmer can come back to this code, months latter, and know what the function is meant to do, and see exactly what is tested, making future support _much_ easier.

Best Wishes
rougie



Joined: 14 Jun 2006
Posts: 31

View user's profile Send private message

Thanking you!
PostPosted: Fri Jun 16, 2006 9:14 am     Reply with quote

Thankyou Ttelmal,

I will make note of this!

I appreciate the effort in your reply and the fact that you shared some methology of programming, I will keep your advice in mind!

Kind Regards
Roberto
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