View previous topic :: View next topic |
Author |
Message |
Mill
Joined: 16 Jul 2006 Posts: 5 Location: Vancouver
|
Repost of Set_Timer1() Problem |
Posted: Sun Jul 16, 2006 12:18 pm |
|
|
According to the following code, I think PIN A1 should be HIGH for 262msecs and LOW for 102msecs. This is not what is happening. I tried changing the SET_TIMER1(X) number but it doesn't seem to change anything.
What is it that I am doing wrong? I am using PIC16F627A and internal oscillator(4MHz).
void main()
{
int16 delay = 0x4E20;
SET_TIMER1(delay);
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);
while(TRUE)
{
if(GET_TIMER1() <32768)
OUTPUT_LOW(PIN_A1);
if(GET_TIMER1() >32768)
OUTPUT_HIGH(PIN_A1);
}
}
Sorry for any mistakes as I am new to the forum + PICs/CCS.
Last edited by Mill on Sun Jul 16, 2006 1:05 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 16, 2006 12:30 pm |
|
|
Actually, I meant re-post it in the same thread, not a new thread.
Also, it doesn't look like you disabled HTML in the posting window.
Look at the line for GET_TIMER1(). Is that really your code ?
I looked at it in two different web browsers, and it looks like:
if(GET_TIMER1() "less than" 32768 "greater than" 32768)
Can you verify that when you posted it, you disabled HTML by selecting
the checkbox for it ? Example:
Code: | x Disable HTML in this post |
The whole reason this problem is happening is because the forum
software got re-configured or re-loaded, or something, about a week
ago. As a result, HTML was enabled by default for all posts. You have
to manually turn it off. If you don't, any code inside angle brackets
gets mangled.
The forum moderator must be on vacation or is out sick -- I don't know
which. But until we get a moderator to fix this problem it's going to
continue to be a mess. |
|
|
Mill
Joined: 16 Jul 2006 Posts: 5 Location: Vancouver
|
|
Posted: Sun Jul 16, 2006 1:08 pm |
|
|
I looked into what PCM programmer said and it does'nt do anything.
My code was changed for some reason and I have fixed it now.
Can you please look at it again. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jul 16, 2006 1:59 pm |
|
|
The program as posted has a bug in setting the timer1 delay. You set the required delay only once, but on reaching 0xFFFF the timer will overflow and start counting at 0 again, i.e. the delay value is not remembered and you will have to set it at every timer overflow again.
Even without this bug the program should work and change output state every 262msecs. Are you sure youre hardware is working correctly?
When posting a program please include all souce lines. Very often the problem is in the #fuse settings containing an error.
Please try the following simplified program. Take extra note of the #fuses settings, this is the minimum required set.
Code: | #include <16F627A>
#fuses INTRC, NOWDT, NOLVP
#use delay(clock=4000000)
//===============================
void main ()
{
while (TRUE)
{
output_low(PIN_A1);
delay_ms(102);
output_high(PIN_A1);
delay_ms(262);
}
} | [/code] |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 16, 2006 2:10 pm |
|
|
I don't have a 16F627A, but I do have a 16F628A and I was able
to make the following program flash an LED on a PicDem2-Plus board.
The LED goes on for about 1/2 second and off for 1/2 second.
Code: | #include <16F628A.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
//======================
void main()
{
int16 delay = 0;
SET_TIMER1(delay);
SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
while(TRUE)
{
if(GET_TIMER1() <32768)
OUTPUT_LOW(PIN_A1);
if(GET_TIMER1() >32768)
OUTPUT_HIGH(PIN_A1);
}
} |
|
|
|
Mill
Joined: 16 Jul 2006 Posts: 5 Location: Vancouver
|
|
Posted: Sun Jul 16, 2006 5:18 pm |
|
|
Thanks Ckielstra
Its working fine now after your suggestions.
You saved a lot of my time.
Just one more quick question though. What if I want HI for 100ms and LOW for 400ms. With the code below if 50% duty cycle ie 500ms.
Thanks again.
#include <16F627A.h>
#use delay(clock=4000000)
//Main Function
void main()
{
int16 delay = 3036;
SET_TIMER1(delay);
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);
while(TRUE)
{
if(GET_TIMER1() > 65530)
{
OUTPUT_TOGGLE(PIN_A1);
SET_TIMER1(delay);
}
}
}
This works fine now.
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Sun Jul 16, 2006 8:22 pm |
|
|
There is a "safer" way to code this. The code takes a finite amount of time to execute. It is possible and very likley that the timer will roll over and you will miss the rollover event.
Instead of testing if the counter is creater than a specifc value you should test if the Timer IF flag has been set. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 17, 2006 2:05 am |
|
|
Mill,
I'm glad to hear your program is working now.
A remark on posting program code in this forum: When posting your text there is a 'code' button you can use before and after pasting your code. This will help in preserve the indenting of your program and makes reading the code a lot easier to us.
Then, in your posted program I'm missing the #fuses line. If your program is working now it is because of some lucky default values being right for your setup, but you are taking a big risk. Save yourself a lot of troubles and add this line.
I don't know why you want to continue on using the timer functions instead of my example using the delay_ms functions. Using the timers is more versatile but more difficult. I like the KISS priniciple. |
|
|
|