|
|
View previous topic :: View next topic |
Author |
Message |
Shaheers
Joined: 23 Sep 2013 Posts: 14
|
Timer0 is not reconfig while external int |
Posted: Fri Oct 18, 2013 4:35 pm |
|
|
I am using to detect 50Hz power signal using two of external Interrupts and Timer0.
The main idea is that both of two interrupts reset the counting register of Timer0 and if either of external interrupt is not triggered in time, the Timer0 causes interrupts.
The problem is, Timer0 interrupt does not respond.
The error is generated while compiling:
"function not void and does not return a value clock_isr"
The code is as following
Code: |
#include <Static_Switch.h>
#int_EXT
void EXT_isr(void)
{
output_high(PIN_D1);
//set_rtcc(61716);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}
#int_EXT1
void EXT1_isr(void)
{
output_low(PIN_D1);
//set_rtcc(61716);
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
}
#INT_RTCC
clock_isr() {
output_high(PIN_C5);
set_rtcc(61716);
clear_interrupt(int_timer0);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}
void main()
{
enable_interrupts(INT_EXT_H2L); //Interrupt on High to Low Edge
enable_interrupts(INT_EXT1); //Interrupt on Low to High Edge
set_rtcc(61716); // At 8mhz, the timer will interrupt in 1.91ms ,, 65536-(.00191/(4/8000000))= 61716
// ************************************************
//Timer value= 8bit/16bit_value - (Desigred_Time /( 4/ Osc_freq)
// ************************************************
setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(true){
output_low(PIN_D0); // Normal running code
delay_ms(1000);
output_high(PIN_D0);
delay_ms(1000);
}
} |
And config file is:
Code: |
#include <18F452.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV42 //Brownout reset at 4.2V
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPB //No Boot Block code protection
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=8000000)
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Fri Oct 18, 2013 5:03 pm |
|
|
from your code...
...this compiles
...this didn't
Notice how you didn't put 'void' before clock_isr() and didn't put 'void' inside the brackets.
The first 'void' tells the compiler that the function will not be returning a value, the second says you won't be inputting data to the function.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Sat Oct 19, 2013 12:58 am |
|
|
Other thing.
Never _ever_, _ever_ use 'enable_interrupts(GLOBAL)', inside an interrupt.
This _will_ cause the code to crash/not work, etc..
The _hardware_ disables the global interrupt bit, when you are inside an interrupt handler, and _automatically re-enables it, when the interrupt exits_. If you enable the global bit inside an interrupt handler, this will result in the handler being called repeatedly, and the loss of variables. This is an absolute 'capital offence' on the PIC. Read the data sheet about 'RETFIE', and interrupts in general, and get rid of those lines. Also a search here will find this discussed.
Code: |
#INT_EXT
void EXT_isr(void)
{
output_high(PIN_D1);
//set_rtcc(61716);
//enable_interrupts(INT_EXT); //not needed the interrupt is enabled
//or you would not get here....
//enable_interrupts(GLOBAL); //Never do this on a PIC.
}
#int_EXT1
void EXT1_isr(void)
{
output_low(PIN_D1);
//set_rtcc(61716);
//enable_interrupts(INT_EXT1); //same comment
//enable_interrupts(GLOBAL); //and again...
}
#INT_RTCC
void clock_isr(void) {
output_high(PIN_C5);
set_rtcc(61716);
//clear_interrupt(int_timer0); //not needed.
//enable_interrupts(INT_RTCC);
//enable_interrupts(GLOBAL);
}
|
Code to 'enable' an interrupt inside it's own handler, is not needed. The interrupt is enabled, or you could not get to the handler.
Code to enable the 'global' bit inside a handler is 'fatal', and must never be done.
Clearing an interrupt inside the handler is also not needed. The compiler does this automatically, unless told otherwise with the 'NOCLEAR' directive.
Generally, since the #INT_xxx directive is a command affecting the following routine, it should always be on the line immediately in front of the routine.
Best Wishes |
|
|
|
|
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
|