View previous topic :: View next topic |
Author |
Message |
srikrishna
Joined: 06 Sep 2017 Posts: 82
|
Timer problem |
Posted: Thu Jul 12, 2018 5:40 am |
|
|
Quote: | Before we load this count in the timer, we first need to subtract it from 65536. The reason we need to subtract it is because the timer is 16-bit. Therefore,
65536 – count = 65536 – 2000 = 63536
Converting this count into hex we get 0xF830. Load this hex value in the Timer1 i.e. TMR1 register. TMR1 is a 16-bit register which is used to load the count for Timer1. |
I can't understand why the counter value is subtracted from 65536 and then loaded to the timer??
Why not counter value is directly loaded in to timer(TIMER1) register??
Here is the link
http://www.electronicwings.com/pic/pic18f4550-timer |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Thu Jul 12, 2018 6:44 am |
|
|
The reason is because of how the timers count.
They don't count 'down', they count 'up'.
They give an interrupt when they reach 65535, and reset to zero (what would be the count of 65536).
So if you put 2000 into the timer, it'd count 2001, 2002, 2003,.... to 65535, and then on the next count would go back to 0 and interrupt. A total of 63536 counts.
To get 2000 counts between the interrupts, you need to load it with 65536 - 2000.
It then counts 63536, 63537, 63538.... to 63535, then on the next count resets. Giving 2000 counts. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Thu Jul 12, 2018 6:52 am |
|
|
In your post it looks like the programmer wants the timer to set an interrupt once every 2000 counts.
Since the timer is an 'up' counter, you need to preset the timer with the value that is 2000 'counts' BEFORE it goes from 0xFFFF to 0x0000. Though some may say 1999 is proper.
To do this you take 65536 subtract 2000 and get 63536, thus 63536 is then loaded into the timer to 'preset' the timer counter.
Have a good read of the datasheet in the timer section for that PIC.
Your post is incomplete as timers generally will have prescalers and /or postscalers as well as clock source options. All these(and more) will affect the actual operation of when the timer issues the interrupt.
Jay |
|
|
Eto
Joined: 31 Jul 2018 Posts: 4
|
|
Posted: Tue Jul 31, 2018 10:44 am |
|
|
I write one prog, I want to check one pin during run my program, how I can define that pin,
if that pin active, my program run else return to main.
I use "while" but my program is many lines with many delays, and after finishing while, it return to main. I want to return immediately.
Pls help me. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Tue Jul 31, 2018 11:22 am |
|
|
You have the question of what you mean by 'active'. Pulled low?. Pulled high?.
Something like:
Code: |
if (input(the_pin_you_want==1))
break;
|
If that is done inside a 'while', the while will exit immediately. |
|
|
Eto
Joined: 31 Jul 2018 Posts: 4
|
|
Posted: Tue Jul 31, 2018 11:34 am |
|
|
Ttelmah wrote: | You have the question of what you mean by 'active'. Pulled low?. Pulled high?.
Something like:
Code: |
if (input(the_pin_you_want==1))
break;
|
If that is done inside a 'while', the while will exit immediately. |
But for example
Code: |
Delay_ms(10000);
If( input pin==1)
Break;
|
If pin==1 at first second of delay the code run 9 s after that go for break, I want to leave in between of delay also |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Tue Jul 31, 2018 12:12 pm |
|
|
You can't easily.
Break your delay up. So have say 10*0.1 second delays and test after each. |
|
|
Eto
Joined: 31 Jul 2018 Posts: 4
|
|
Posted: Tue Jul 31, 2018 12:37 pm |
|
|
Ttelmah wrote: | You can't easily.
Break your delay up. So have say 10*0.1 second delays and test after each. |
My prog is same as below
Code: |
Void test1 (){
Code
Delay
Code
Delay
}
Void test2(){
Code
Delay
Code
}
Void main(){
While(true){
Delay;
Test1()
Code
Delay
Test2()
Code
Delay
}
} |
Now how I can immediately leave from While to main, I have so many delay 10s, 40s ....
My prog is for one washing machine. I want to start my prog when the door is locked and due to open the machine door in between of prog, the prog should be stop and leave, that is safety of system.
Pls help me |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Tue Jul 31, 2018 1:41 pm |
|
|
As I said just break up the delays.
If you have a lot, then write a simple macro that automatically generates a split delay, and use this.
Honestly 'long term', don't code like this. Have a master loop using a timer to generate a loop every 1/10th second (say). Have you code use a state machine and a tick counter to handle delays, so you can have exit tests every time round the loop. |
|
|
Eto
Joined: 31 Jul 2018 Posts: 4
|
|
Posted: Tue Jul 31, 2018 1:48 pm |
|
|
Ttelmah wrote: | As I said just break up the delays.
If you have a lot, then write a simple macro that automatically generates a split delay, and use this.
Honestly 'long term', don't code like this. Have a master loop using a timer to generate a loop every 1/10th second (say). Have you code use a state machine and a tick counter to handle delays, so you can have exit tests every time round the loop. |
Can u write one simple sample for me?
With tnx |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Tue Jul 31, 2018 2:49 pm |
|
|
Pretty sure there's an example in the examples folder or in the FAQ section of the manual... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Tue Jul 31, 2018 11:27 pm |
|
|
and, on the split delay, something like:
Code: |
#define DELAY(x) int16 count; for(count=0;count<8*x;count++) \
{ delay_ms(125); if (input(pin_xx)) return; }
|
Since each of your routines is a separate routine, you can just use 'return' to come out. Instead of (say) delay_ms(10000); for a 10 second delay, use DELAY(10). When 'pin_xx' goes high, the code will return within 125mSec. |
|
|
|