|
|
View previous topic :: View next topic |
Author |
Message |
milkman41
Joined: 16 Jun 2008 Posts: 30
|
Timer question |
Posted: Thu Jul 31, 2008 11:34 am |
|
|
I am currently trying to use one of the internal timers for an application in my program, and I'm not entirely sure how to do it, I've searched through some of the topics but haven't found quite what I'm looking for. I'm trying to write some code such that I can run a function for a certain duration, so essentially have a while loop running for a certain amount of time. I would do something simple like...
Code: | while(x < limit) {
//function
delay_ms(1000);
x++;
} |
...but the 'function' part of my code takes a non-negligible amount of time to run (it sends X10 commands, which take time), so I can't exactly do that. Though I could figure out how long it takes to execute the function and take that into consideration, I was hoping there was a nice simple way to do what I want. If anybody has some suggested/code or a thread that would be useful, I'd be very grateful if they could share.
Thanks,
Nick
PS I'm using a PIC16F877A and compiler version 4.058s |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
milkman41
Joined: 16 Jun 2008 Posts: 30
|
|
Posted: Thu Jul 31, 2008 12:39 pm |
|
|
Thanks for the reply PCM, I looked at the thread and it seemed pretty good, the thing is, I don't really want to multi-task, my thinking is that a command is given to the PIC, and then it runs this function (which for my project is basically a thermostat) for an amount of time entered by the user, and then once it is done running the program, it sits back in wait for more commands to come (this is the same project I've been asking for AT help with, just a different part of it). I found some code on another recent topic http://www.ccsinfo.com/forum/viewtopic.php?t=35540 that sort of does what I would want, but I can't get it to work.
My adapted code:
Code: |
#include <protoalone.h> //16f877A, clock = 20MHz, fuses: HS, NOLVP, NOWDT, PUT, NOPROTECT
long int seconds;
#INT_TIMER2
void tick(void) {
static int counts = 39;
if(counts) --counts;
else {
counts = 39;
//1-second job here
seconds++;
printf("%lu\r\n", seconds);
}
}
void main() {
seconds = 0;
setup_timer_2(50,249,10); //the example has setup_timer_2(10,249,10), but it has 4MHz clock, so this should be the same, right?
set_timer2(0);
enable_interrupts(int_timer2);
enable_interrupts(global);
output_high(RED_LED);
while(seconds < 8)
output_low(RED_LED);
}
|
So basically what Im trying to do here is increment the seconds count by 1 each second, and then it lights the red led for 8 seconds (arbitrary number).
Any help on this or more suggestions on the initial post would be very helpful.
Thanks,
-Nick |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 31, 2008 1:24 pm |
|
|
You should try to make it work instead of me writing the code for you. |
|
|
milkman41
Joined: 16 Jun 2008 Posts: 30
|
|
Posted: Thu Jul 31, 2008 1:45 pm |
|
|
I'm not asking you to write any code for me, I've been trying to get my code to work for a couple days now, but I dont really know programming as well as the people on this board, so I thought I would come here where people have been very helpful previously, show the code that isn't working, and ask for some advice or suggestions on how to make the code work - but not asking anybody to write any code for me. If I was, I'd have stated it explicitly, and not asked for suggestions or advice like I did. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Thu Jul 31, 2008 2:23 pm |
|
|
The principle of your code is good. You have an interrupt routine that adds +1 to seconds every second (or at least that is what it should do). Then you can poll for seconds as you are doing in your main loop. But please take that printf() out of your interrupt code. You should never put anything like that in an interrupt routine. It takes too much time and it uses compiler resources that are shared with your main program. If you need to debug something, put your printf statements in the main loop. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jul 31, 2008 6:02 pm |
|
|
Take care when copying code examples. The thread you refer to mentions the code is not working... Garbage In = Garbage Out.
Apart from some other issues:
Code: | setup_timer_2(50,249,10); //the example has setup_timer_2(10,249,10), but it has 4MHz clock, so this should be the same, right? | Nope.
The first value (50) represents the hardware prescaler. Check the datasheet of your chip for valid values.
Code: | output_high(RED_LED);
<<-- The RED LED will be on for about 0.4us. Your eyesight is perfect!
while(seconds < 8)
output_low(RED_LED);
} <<-- What happens when the code gets here ? |
|
|
|
milkman41
Joined: 16 Jun 2008 Posts: 30
|
|
Posted: Fri Aug 01, 2008 8:10 am |
|
|
ckielstra wrote: | Take care when copying code examples. The thread you refer to mentions the code is not working... Garbage In = Garbage Out.
|
Yeah but it was the latest post, which noone had responded to, so I thought it could possibly work, but I was wrong eh :p.
So I've altered the code, here is the new code, but it still doesnt work :(.
Code: |
#include <protoalone.h> //20MHz clock
long int seconds;
#INT_TIMER2
void tick(void) {
static int counts = 124;
if (counts) --counts;
else {
counts = 124;
seconds++;
}
}
void main() {
seconds = 0;
setup_timer_2(16,249,10);
set_timer2(0);
enable_interrupts(int_timer2);
enable_interrupts(global);
output_high(RED_LED);
while(seconds < 2) {
output_low(RED_LED);
}
output_high(RED_LED);
output_low(GREEN_LED);
}
|
I want the red led to light up for 2 seconds, shut off, and the green led turns. I changed the setup_timer_2 line, since the accepted prescalers are 1, 4, 16 (according to the other thread), and 16 * (249+1) * 10 * 125 = 5MHz, and 5MHz * 4 = 20MHz. The problem is that the red led never shuts off, its just on the whole time, so this means the program stays in the while loop the whole time, so the seconds aren't incrementing for some reason :\. Anybody have any suggestions?
Thanks,
-Nick |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Mon Aug 04, 2008 10:40 am |
|
|
1)You don't have a forever while(1) loop.
2)You don't turn on green led
try this for a little spoon feeding. ((pcm 3.249 picdem 2 plus, 10Mhz))
Code: | #include <16f877.h>
#device *=16
#use delay(clock=10000000,restart_wdt)
#fuses hs,nowdt,noprotect,nolvp //we have a wdt now
#use rs232(baud=19200,xmit=PIN_E2,invert,restart_wdt,stream=DEBUG)
#case
#zero_ram
#define INTS_TENTHSEC_TMR2 5;//or 32
#define RED_LED PIN_B0
#define GREEN_LED PIN_B1
#define toggle_them_both(x,y) output_toggle(x);output_toggle(y)
int16 seconds=0;
int16 old_seconds=0;
int16 int_count_tmr2;
//"I want the red led to light up for 2 seconds, shut off, and the green led turns ?ON?"
//========= Prototypes =========//
void init(void);
void main() {
output_high(RED_LED);
fprintf(DEBUG,"STARTING... Red ON\r\n");
init();
while(1)//main while loop
{
if(seconds != old_seconds)
{
old_seconds=seconds;
fprintf(DEBUG,"Sec=%lu\r\n",seconds);
}
if(seconds == 2)
{
seconds=0;
toggle_them_both(RED_LED,GREEN_LED);
}
}
}
void init()
{
seconds = 0;
setup_timer_2(T2_DIV_BY_16,255,16);
int_count_tmr2 = INTS_TENTHSEC_TMR2;
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
}
#INT_TIMER2
void tick(void) {
output_toggle(PIN_B3);
if (int_count_tmr2) --int_count_tmr2;
else
{
output_toggle(PIN_B2);
int_count_tmr2 = INTS_TENTHSEC_TMR2;
seconds++;
}
}
|
|
|
|
|
|
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
|