|
|
View previous topic :: View next topic |
Author |
Message |
wa1384 Guest
|
How to use timer |
Posted: Wed Feb 04, 2009 1:00 am |
|
|
I would like to ask about how to use the timer too...
how to use set_timer0, get_timer0,
what is the meaning of the value of set_timer0(0)...
because I am doing a program that will have a digital waveform, which have high and low voltage...I would like to use timer to make the waveform low for a certain time..anybody can help me on this?
thanks in advance... |
|
|
wa1384 Guest
|
|
Posted: Wed Feb 04, 2009 1:03 am |
|
|
sorry,forgot to put some info, I am using PIC16f877A |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
wa1384 Guest
|
|
Posted: Wed Feb 04, 2009 8:56 pm |
|
|
If I have this kind of program,
Code: |
int s1;
int s2;
int s3;
int s4;
void main()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
// setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while(TRUE)
{
while (read_ADC()>50);
while (read_ADC()<50);
delay_ms(125);
s1=read_ADC();
printf("\rADC=%u,s1",s1);
delay_ms(250);
s2=read_ADC();
printf("\rADC=%u,s2",s2);
delay_ms(250);
s3=read_ADC();
printf("\rADC=%u,s3",s3);
delay_ms(250);
s4=read_ADC();
printf("\rADC=%u,s4",s4);
set_timer0(4);
while ( get_timer0() ) ;
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
if ((s1>50 && s1<126) && s2<50 && s3<50 && s4<50) //case1
{
output_high(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
}
else if ((s1>50 && s1<126) && (s2>50 && s2<126) && s3<50 && s4<50 ) //case2
{
output_low(PIN_D0);
output_high(PIN_D1);
output_low(PIN_D2);
}
else if ((s1>50 && s1<126) && (s2>50 && s2<126) && (s3>50 && s3<126) && s4<50) //case4
{
output_low(PIN_D0);
output_low(PIN_D1);
output_high(PIN_D2);
}
else if ((s1>126 && s1<176) && (s2>50 && s2<126) && s3<50 && s4<50) //case3
{
output_high(PIN_D0);
output_high(PIN_D1);
output_low(PIN_D2);
}
else if ((s1>126 && s1<176) && (s2>50 && s2<126) && (s3>50 && s3<126) && s4<50) //case5
{
output_high(PIN_D0);
output_low(PIN_D1);
output_high(PIN_D2);
}
else if ((s1>126 && s1<176) && (s2>126 && s2<176) && (s3>50 && s3<126) && s4<50) //case6
{
output_low(PIN_D0);
output_high(PIN_D1);
output_high(PIN_D2);
}
else if (s1>176 && (s2>126 && s2<176) && (s3>50 && s3<126) && s4<50) // case7
{
output_high(PIN_D0);
output_high(PIN_D1);
output_high(PIN_D2);
}
else //case0
{
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
}
}
}
|
I want the output of pin_D0 to pin_D2 to be low after running 7ms, but it is not working. Is it because of my wrong calculation?
My crystal frequency was 4 MHz, 8 bit counter. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 04, 2009 11:25 pm |
|
|
Quote: |
I want the output of pin_D0 to pin_D2 to be low after running 7ms
|
Why don't you just do this:
Code: |
delay_ms(7);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2); |
Make everything as simple as possible. |
|
|
wa1384 Guest
|
|
Posted: Thu Feb 05, 2009 1:37 am |
|
|
thanks for the reply, but my mean is, I want to make the output low after all the if else things happen...but I did try the suggestion given, did not work out...
anyway, if I want to use interrupt
timer0_isr(void)
{
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
}
how to call it? I enabled the interrupt already but it says function not void and doesn't return value timer0_isr...
thanks again in advance |
|
|
Ttelmah Guest
|
|
Posted: Thu Feb 05, 2009 5:07 am |
|
|
You don't call it.
That is the whole point of interrupts. The _event_ calls it.
You need to declare an interrupt handler like:
Code: |
#int_timer0
void timer0_isr(void) {
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
disable_interrupts(INT_TIMER0); //explain this later...
}
|
The interrupt handler, can never return a value, or receive a value. If you want to pass things to/from a handler, you do this through global variables. The compiler will complain if you try to return a value.
The handler _must not_ be 'called' by any of your code.
Then if the interrupts are enabled, the handler will _automatically_ be called when the event occurs.
Now, you have not posted your clock statement, so we can't tell how fast your timer would 'tick'. However it counts from the master oscillator/4, divided by the selected prescaler (/256 as you show). So if your master clock was 10MHz, it'd count one every (10000000/(4*256)) = 102.4uSec.
So 68 counts, would give 6.96mSec. The closest you could get with this prescaler.
Then to make the event 'happen', you would want:
Code: |
void fire_in_seven(void) {
set_timer0(256-68);
clear_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
}
|
If you call this, the output pattern you want, will occur automatically 6.96mSec latter, while your other code can be carrying on doing whatever you want. I have disabled the interrupt in the handler, since otherwise the pattern will trigger again 26msec later, when the interrupt fires again. You will need to adjust the counts to suit your clock.
Now, the 'clear' is necessary, since otherwise the interrupt will trigger immediately, if it has triggered since the last time the routine was used, or since the chip started.
Best Wishes |
|
|
wa1384 Guest
|
|
Posted: Mon Feb 23, 2009 2:40 am |
|
|
So, If I use 20Mhz for the master clock, and I if I want all pin low in 1ms delay, I must use a 4 of prescaler right? and for the timer what should I set it? |
|
|
|
|
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
|