View previous topic :: View next topic |
Author |
Message |
mahmudur.rahman
Joined: 08 Nov 2010 Posts: 3
|
need to know the simple way for timer calculations... |
Posted: Mon Dec 13, 2010 2:12 am |
|
|
hi there...
I am bit new in programming PIC. At present I am playing with the timers. I got some useful informations from here...
http://www.microcontrollerboard.com/pic-timer1-tutorial.html
http://www.ccsinfo.com/forum/viewtopic.php?t=22467
They were very helpful but as I am a novice I think I need to know it more clearly.
I am trying to toggle a pin at 1 sec time period. I know it could be possible using PWM. I will do it when I am done with the timers. But now I want learn about the timers.
My controller is 16F873A and I have a 16Mhz crystal. I wrote a code based on the equation given here http://www.microcontrollerboard.com/pic-timer1-tutorial.html my code is
Code: |
#include <16F873A.h>
#fuses HS, NOLVP, NOWDT, PUT, BROWNOUT, NOPROTECT
#use delay(clock=16M, crystal=16M)
#use fast_io(b)
#define overflow 50000 // overflows in every 0.1 sec
volatile unsigned int1 tmr1_flag;
volatile unsigned int16 tmr1_count;
// Timer1 interrupt
#INT_TIMER1
void isr_timer1(void){
if(tmr1_flag == 0)
{
tmr1_flag = 1;
output_bit(PIN_B1,1);
}
else
{
tmr1_flag = 0;
output_bit(PIN_B1,0);
}
set_timer1(overflow);
tmr1_count++;
if(tmr1_count == 32)
{
tmr1_count = 0;
}
}
int main(void)
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_tris_b(0x00);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(overflow);
tmr1_count = 0;
tmr1_flag = 0;
output_bit(PIN_B1, 0);
while(TRUE);
return 0;
}
|
I know I am doing something wrong . But I can't point it out. As I said it before I am very new in programming PIC. I am just learning. Please forgive me if I made any mistakes here .
I am just using the timer1 interrupt. There is nothing else in the code. If I can figure out the proper timing I think I could do it while operating with other instruction. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 13, 2010 2:05 pm |
|
|
Quote: | #define overflow 50000 // overflows in every 0.1 sec |
Timer1 is an Up-counter. You are thinking it's a down counter. But it's
not. You are preloading Timer1 with 50,000. It will count up to 65535
and then roll over to 0, and cause an interrupt. So you have set Timer1
to interrupt every 15,536 counts (instead of 50,000 as you thought).
Also, a few more comments:
Quote: |
#define overflow 50000
set_timer1(overflow);
|
In the C language, it's the standard to put constants in upper case.
Your code should be:
Code: |
#define OVERFLOW 50000
set_timer1(OVERFLOW);
|
This helps programmers to easily see that a value is a #define'd constant.
Quote: |
int main(void)
{
.
.
.
while(TRUE);
return 0;
}
|
The main() function doesn't return to any Operating System. Get rid of
the return statement and change the return data type on main() to void.
Example:
Code: |
void main(void)
{
.
.
.
while(TRUE);
}
|
Your setup code in main() is all done in the wrong order, in my opinion.
You should setup your Timer1 parameters and load Timer1 before you
start the timer by calling setup_timer_1(). Also, everything should be
completely setup before you enable interrupts. Example:
Code: |
set_tris_b(0x00);
set_timer1(overflow);
tmr1_count = 0;
tmr1_flag = 0;
output_bit(PIN_B1, 0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
|
|
|
|
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Mon Dec 13, 2010 2:10 pm |
|
|
I think you might want to verify you can toggle an actual LED on and off
to verify your hardware is configured correctly before playing with the
timer function.
When dealing with timers it can be sometimes difficult to calculate when
the timer overflows. There is a handy windows program that works out the
math and its available here.
http://pictimer.picbingo.com/
There is also a book called "C what happens" that covers many of the basics on using the pic. There is a very good section that explains the use
of timers. It also includes code to blink your led on and off.
Thanks Scott |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Tue Dec 14, 2010 9:38 am |
|
|
You can let the compiler do the math and just say
Code: | set_timer1(0xFFFF - 50000); |
or better yet, just back the timer up from wherever it happens to be when you get to it:
Code: | set_timer1(get_timer1()-50000); |
|
|
|
|