|
|
View previous topic :: View next topic |
Author |
Message |
rougie
Joined: 14 Jun 2006 Posts: 31
|
A little help on C! |
Posted: Thu Jun 15, 2006 2:25 pm |
|
|
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
|
|
Posted: Thu Jun 15, 2006 4:43 pm |
|
|
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
|
Thanks Ckielstra |
Posted: Thu Jun 15, 2006 5:11 pm |
|
|
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
|
|
Posted: Fri Jun 16, 2006 2:38 am |
|
|
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
|
Thanking you! |
Posted: Fri Jun 16, 2006 9:14 am |
|
|
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 |
|
|
|
|
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
|