|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Is delay_ms() using timer1 interrupts? |
Posted: Sat Mar 04, 2006 1:10 am |
|
|
when I comment out #use delay(800000) and all wrote my own delay_ms(), program executs fine.
This is too much now . . . |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 04, 2006 1:28 am |
|
|
Quote: | Is delay_ms() using timer1 interrupts |
The delay_ms() function uses software loops only.
Quote: | when I comment out #use delay(800000) |
Your #use delay() statement above is set for 800 KHz.
Does that match your hardware ? |
|
|
Guest
|
|
Posted: Sat Mar 04, 2006 2:16 am |
|
|
PCM,
Sorry, I made a typo, I meant #use delay(8000000)
Well, it definitely uses timer interrupt if #INT_TIMER1 is spceified and delay_ms() is used within the ISR, it gives me a warning -- interrupt disabled to prevent re-entrance.
When using CCS delay_ms(), the application does not run accordingly, the timer1 interrupt keeps getting called for no reason, as if it was in an infinite loop.
Anyways, I gave up with all default functions, I will go back to all direct manipulations of ports, bits, and delays |
|
|
Ttelmah Guest
|
|
Posted: Sat Mar 04, 2006 4:48 am |
|
|
No, it does not use the timer interrupt. The reason for it being disabled, is that if you use a delay function inside an interrupt, _and_ a version outside, interrupts are disabled in the external version, to prevent the same code from being called inside itself.
You #use delay function, is _wrong_. The syntax of this function, is:
#use delay(clock=8000000)
Hence it is not working...
Best Wishes |
|
|
Guest
|
|
Posted: Sat Mar 04, 2006 9:06 am |
|
|
Ttelmah,
Here is the COMPILED TEST code, try it youself and see what you get. I got a interrupt disabled (Warning 216) in Build output window. When I run it, the interrupt does not seem to be disabled, however.
#include "16f684.h"
#define OSCLK 8000000
#use delay(clock=OSCLK)
char ch_x;
#INT_TIMER1
void isr_timer()
{
ch_x = input_a();
delay_ms(10);
}
void main()
{
set_tris_a(0xff);
set_tris_c(0xff);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
delay_ms(1);
set_timer1(0xffff - 10);
}
} |
|
|
Guest
|
|
Posted: Sat Mar 04, 2006 9:12 am |
|
|
Here is what is in Build Window after building the above code.
Clean: Deleting intermediary and output files.
Clean: Deleted file "TEST_684.ERR".
Clean Warning: File "C:\Projects\TEST\TEST_684.o" doesn't exist.
Clean: Deleted file "TEST_684.HEX".
Clean: Deleted file "TEST_684.SYM".
Clean: Deleted file "TEST_684.LST".
Clean: Deleted file "TEST_684.PJT".
Clean: Deleted file "TEST_684.TRE".
Clean: Deleted file "TEST_684.COF".
Clean: Done.
Executing: "C:\Program files\Picc\CCSC.exe" "TEST_684.c" +FM +DF +LN +T -A +M +Z +Y=9 +EA
>>> Warning 203 "C:\Projects\TEST\TEST_684.c" Line 25(1,1): Condition always TRUE
>>> Warning 216 "C:\Projects\TEST\TEST_684.c" Line 31(0,1): Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)
Memory usage: ROM=6% RAM=12% - 14%
0 Errors, 2 Warnings.
Loaded C:\Projects\TEST\TEST_684.cof.
BUILD SUCCEEDED: Sat Mar 04 07:11:40 2006 |
|
|
Ttelmah Guest
|
|
Posted: Sat Mar 04, 2006 10:15 am |
|
|
You have a delay, both inside and outside the interrupt routine, so the interrupts will be disabled.
You can avoid this, by generating two #use delay statements (one for the interrupt handler, and one for the main code), which will result in two sets of delay code being generated, and avoid this. The interrupt is disabled for the delay. This is the generated .lst
Code: |
.................... delay_ms(1);
0071: CLRF 2E
0072: BTFSC 0B.7
0073: BSF 2E.7
0074: BCF 0B.7
0075: MOVLW 01
0076: MOVWF 31
0077: CALL 03C
0078: BTFSC 2E.7
0079: BSF 0B.7
|
The global interrupt enable is register B.7. It copies this into a temporary register (2E), clears it if it is set, then calls the delay code. On the return, if it was set, it sets the bit again.
If you code like this instead:
Code: |
#include "16f684.h"
#define OSCLK 8000000
char ch_x;
#use delay(clock=OSCLK)
#INT_TIMER1
void isr_timer() {
ch_x = input_a();
delay_ms(10);
}
#use delay(clock=OSCLK)
void main() {
set_tris_a(0xff);
set_tris_c(0xff);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1) {
delay_ms(1);
set_timer1(0xffff - 10);
}
}
|
Not the _two_ #use delay statements, the call becomes:
Code: |
.................... delay_ms(1);
0084: MOVLW 01
0085: MOVWF 2F
0086: GOTO 05B
|
Because there are now two copies of the delay code.
Best Wishes |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat Mar 04, 2006 10:16 am |
|
|
Quote: | No, it does not use the timer interrupt. The reason for it being disabled, is that if you use a delay function inside an interrupt, _and_ a version outside, interrupts are disabled in the external version, to prevent the same code from being called inside itself.
You #use delay function, is _wrong_. The syntax of this function, is:
#use delay(clock=8000000)
Hence it is not working...
Best Wishes |
Read this again very carefully and you will see why Telmath is correct |
|
|
|
|
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
|