View previous topic :: View next topic |
Author |
Message |
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
pic16f1939 timer problem |
Posted: Mon Jul 09, 2012 10:28 am |
|
|
Hello Everybody!!!
please help me
I have a program...I wrote in CCS.
The program contains a timer.
This timer works if I use pic16f877A, if I use pic16f1939 then no.
What's wrong? I don't understand :(
Thank you!!
Code: |
#include <16F1939.h>
#include "hardver.h"
#DEVICE ADC=10
#fuses HS,NOWDT,PROTECT,NOPUT,CPD
#use delay(clock=XTAL_FREQUENCY)
#zero_ram
#INT_TIMER1
void Timer1_isr()
{
output_high(LED2);
}
void main()
{
set_timer1(0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
enable_interrupts(INT_TIMER1);
for(;;)
{
output_toggle(LED0);
delay_ms(1000);
}
}
|
|
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Mon Jul 09, 2012 10:39 am |
|
|
"Does not work" is really vague... What does not work?
compiler version?.... some chips are not supported by all compilers..
where is XTAL_FREQUENCY defined?
Where is LED2 and LED0 defined?
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
|
Posted: Mon Jul 09, 2012 10:59 am |
|
|
Gabriel wrote: | "Does not work" is really vague... What does not work?
compiler version?.... some chips are not supported by all compilers..
where is XTAL_FREQUENCY defined?
Where is LED2 and LED0 defined?
G. |
hello,
version is 4.093
LED2 and LED0 are defined in the hardver.h
FREQ = 10Mhz
This program works with 16f877A, but with 16f1939 no :(
interrupt is not working... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 09, 2012 12:01 pm |
|
|
You don't ever enable GLOBAL interrupts. It won't work until you do that. |
|
|
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
|
Posted: Mon Jul 09, 2012 12:14 pm |
|
|
PCM programmer wrote: | You don't ever enable GLOBAL interrupts. It won't work until you do that. |
if i enable global interrupts the program will stop...I don't no why |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 09, 2012 12:57 pm |
|
|
It doesn't stop. It just does a Timer1 interrupt several times per second,
and so the program is constantly setting the LED2 pin to a high level.
So as soon as your main code sets it low, just a short moment later, it's
set high again. So it appears to be constantly high. |
|
|
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
|
Posted: Tue Jul 10, 2012 1:25 am |
|
|
PCM programmer wrote: | It doesn't stop. It just does a Timer1 interrupt several times per second,
and so the program is constantly setting the LED2 pin to a high level.
So as soon as your main code sets it low, just a short moment later, it's
set high again. So it appears to be constantly high. |
I talk about some similar problem
http://www.ccsinfo.com/forum/viewtopic.php?p=153693
I just don't understand what's this :( |
|
|
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
|
Posted: Tue Jul 10, 2012 1:27 am |
|
|
PCM programmer wrote: | It doesn't stop. It just does a Timer1 interrupt several times per second,
and so the program is constantly setting the LED2 pin to a high level.
So as soon as your main code sets it low, just a short moment later, it's
set high again. So it appears to be constantly high. |
I change two different LED
LED0 and LED2 |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Tue Jul 10, 2012 7:33 am |
|
|
this is simple to understand:
you have this:
Code: | #INT_TIMER1
void Timer1_isr()
{
output_high(LED2);
}
void main()
{
set_timer1(0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
enable_interrupts(INT_TIMER1);
for(;;)
{
output_toggle(LED0);
delay_ms(1000);
}
} |
you timer counts from 0 to FFFF (assuming timer1 is 16 bit) .... when it overflows (in other words, when it reaches its max value of FFFF) it causes an interrupt... the interrupt make your code go here:
Code: | #INT_TIMER1
void Timer1_isr()
{
output_high(LED2);
} |
as you can see, you set your LED2 high... you turn it ON.
now.. your timer is set to:
Code: | setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); |
you are using the smallest prescaler available "T1_DIV_BY_2" so your timer will overflow (reach FFFF) _very_often_and_very_fast.....
REMEMBER: interrupts do precisly that, _INTERRUPT_ normal code, exectute the ISR and continue executing the code where it was when the interrupt occured
that means that the following code executes _many_times per second:
Code: | #INT_TIMER1
void Timer1_isr()
{
output_high(LED2);
} |
.... so when you get here:
Code: | for(;;)
{
output_toggle(LED0);
delay_ms(1000);
} |
and you turn your LED _OFF_ you will turn it right back ON in the timer ISR, remember it gets called several times per second... so
assume your timer interrupts every 50ms... your LED gets turned ON every 50ms ...
when you finally get to turn it OFF, 50ms later, you will turn it back ON because the timer will overflow.... thus your LED will have a MAXIMUM OFF TIME of 50ms.... which means...
you will NOT see it turn OFF because the OFF period is less than your EYE can detect.
you cant try this better: (havent tested it)
Code: | #include <16F1939.h>
#include "hardver.h"
#DEVICE ADC=10
#fuses HS,NOWDT,PROTECT,NOPUT,CPD
#use delay(clock=XTAL_FREQUENCY)
#zero_ram
#INT_TIMER1
void Timer1_isr()
{
output_toggle(LED1); //<------This LED will toggle based on the TIMER
}
void main()
{
set_timer1(0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_256); //<---largest prescaler for longer periods between overflows
enable_interrupts(INT_TIMER1);
for(;;)
{
output_toggle(LED2); //<---]This LED will toggle every second as per the delay
delay_ms(1000);
}
} |
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
barnal
Joined: 27 Jun 2012 Posts: 8 Location: Hungary
|
|
Posted: Tue Jul 10, 2012 7:47 am |
|
|
Thank you for your big answer ;)
I will try it soon and i will answer for you
Have a nice day! |
|
|
|