|
|
View previous topic :: View next topic |
Author |
Message |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Jan 23, 2013 2:59 pm |
|
|
This can be so much simpler than the code you have created.
How good does the accuracy of your timing have to be ??
If using the internal oscillator, at nominal temperature, the precision could already be "off" by +/- 2% -
&&
with a crystal perhaps .02% or BETTER.
Yet with a sloppy enough spec for precision, this can be done with a lot less code, and no interrupts at all, provided ALL you have to do is watch the clock and light leds.
I'd like to comment, that there is no better way to complicate a project than to chase an enhanced set of specs in pursuit of a non-existent level of accuracy and performance. |
|
|
ccslearner
Joined: 12 Jan 2013 Posts: 10
|
|
Posted: Wed Jan 23, 2013 9:09 pm |
|
|
Mike Walne wrote: | You've (or your tutor's) changed the rules.
So, you either extend the present scheme or change to something more general purpose.
Mike |
May i know what rule i changed ? Please cite me |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jan 24, 2013 7:59 am |
|
|
I don't know if the rules were changed, but it wasn't clear from the beginning that you had a list of assignments to do with different timing subjects.
As a remark on your first program: from your assignment it was not specified you were to use interrupts. Interrupts are great, but are a difficult subject as you've found out the hard way.
Here is another possible solution for the same assignment, not using timers or interrupts: Code: | #define LED1 PIN_B1
#define LED2 PIN_B2
void update_led1()
{
if (time_1 > 0)
{
time_1--;
}
else
{
output_toggle(LED1);
time_1 = 5;
}
}
void update_led2()
{
if (time_2 > 0)
{
time_2--;
}
else
{
output_toggle(LED2);
time_2 = 2;
}
}
void main()
{
//infinite loop
while(1)
{
update_led1();
update_led2();
delay_ms(1000);
}
} |
Note how I've used the output_toggle() function to switch on/off the LEDs. You could also have used the output_low() and output_high() functions, these are easier to read and much more efficient than your construction. Compare: Code: | if ( last_5sec == TRUE)
{
output_b( (input_b() | 0x02)); // ON LED 2 alone
}
else
{
output_b( (input_b() & 0xFD)); // OFF LED 2 alone
} | and Code: | if ( last_5sec == TRUE)
{
output_high(LED2);
}
else
{
output_low(LED2);
} | The last version is so easy to read that you don't need documentation, i.e. this is called 'self documenting code'. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Jan 24, 2013 3:50 pm |
|
|
ccslearner wrote: | Mike Walne wrote: | You've (or your tutor's) changed the rules.
So, you either extend the present scheme or change to something more general purpose.
Mike |
May i know what rule i changed ? Please cite me |
There has been a change from symmetric operation of each LED to asymmetric.
Each time you post you're presenting a different task.
You either design a solution for each task or create something which is more general purpose.
As others have pointed out you're not presenting us with a complete specification for your task.
What is your ultimate goal?
Mike |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Jan 25, 2013 2:45 am |
|
|
So, you have been set a learning assignment: you have to use interrupts to get this flashing to work.
This is an exercise in learning about interrupts: the flashing is just a way of showing the results.
I'd approach this simple exercise simply. I'd look at it as I would if I was designing hardware to implement the same function. As its an exercise about interrupts I'd make sure I got that bit right.
I'd set a timer - timer 2 for simplicity as it resets itself, which is best for timekeeping - to give me an interrupt at or a sub-multiple of the shortest timing interval I need. In this case what I'd like, for simplicity, would be a one second tick, but that's difficult on many PICs due to timer limitations, so I'd go for something like 10ms or 100ms. I'd update a tick count variable in my ISR which I made wrap round at the lowest common multiple of the flash rates I need, say 10s for a five sencond flash and a two second flash. This is simply a low frequency counter. That's my ISR and timer sorted.
That's the real meat of the exercise done: the ISR and timer. The rest is simply showing the results. I'd use a simple main loop that just tests the result of my tick counter (which is updated in the ISR) and decode the values as I needed with simple if statements. So, in the first five seconds of the ten I'd light my first LED. In the first two, fith and sixth, nineth and tenth seconds I'd light my second LED. To alter the pattern is simply a matter of altering the constants in the if statements. Its also simple to add more LEDS. I'd ensure my counter wrapped around at a suitably long time: the lowest common multiple of the required flash rates.
This solution is simple, flexible, easy to understand and show command of the concept of interrupts. It is a clearly defined two part solution: a timing counter and a decoder that decodes and acts on the "time". The ISR is simple: just a counter. There are no delays. The timing is reliable and predictable. There *is* lag between the ISR and the mainloop, but it is acceptably small provided the mainloop doesn't do much more.
I'm not going to provide code as it's your assignment. Indeed I really only show this becuase I suspect all of the solutions so far presented have been too closely focussed on the specifics of the timing, rather than on the principles of ISRs and timing, which I think is what the exercise is probably about.
RF Developer |
|
|
|
|
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
|