|
|
View previous topic :: View next topic |
Author |
Message |
colin
Joined: 08 Sep 2003 Posts: 3
|
interrupt - external(pin b0) |
Posted: Tue Sep 09, 2003 5:32 pm |
|
|
Hi all,
would you guys pls show me how to write an interrupt to trigger a switch(connected to Pin B0) from high to low?
I followed the example (ex_wake.c), however, it worked once, and didn't work after that <- weird, huh?! I'm tring to implement a sleep mode (try put it sleep and weak it up by a switch).
I have a timer interrupt and it works fine. when I have a delay_ms(1000) function in #INT_EXT, void ext_isr(), it also delay my timer2?! I also tried put a printf function and a output_high(R1) function in ext_isr() but it showed nothing. It seems the ext_isr() function didn't call at all. I cehcked the INTCON register, bit 7 should be 1, but it showed 0. when I took out the delay function in ext_isr(), everything became normal.
I'm using Mplab 6.3, PCM 3.176, 16F877, PICDEM 2 Plus, ICD 2
Here's my code (took out unnecessary part):
Code: |
#include <test_sleep_mp.h>
#include <timer2.c>
//==========================================
void main() {
long counter;
sleep_mode=FALSE;
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
//initialize function
init_timer2();
enable_interrupts(global);
while(1)
{
if(sleep_mode)
sleep();
output_high(PIN_B3);
delay_ms(1000);
output_low(PIN_B3);
delay_ms(1000);
printf("while");
}
}
-------------------
timer source file
-------------------
#include <test_sleep_mp.h>
#include <timer2.h>
void init_timer2(void) {
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
//setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,42,15);
enable_interrupts(INT_TIMER2);
}
//interrupt function - count for 1 sec
#int_TIMER2
void TIMER2_isr(void) {
if(++ten_msec_count>=100){
ten_msec_count = 0;
output_high(PIN_B2);
}
else if(++ten_msec_count<=50){
output_low(PIN_B2);
}
}
#INT_EXT
void ext_isr() {
static short button_pressed=FALSE;
if(!button_pressed) // if button action and was not pressed
{
button_pressed=TRUE; // the button is now down
//sleep_mode=TRUE; // activate sleep
printf("The processor is now sleeping.\r\n");
ext_int_edge(L_TO_H); // change so interrupts on release
}
else // if button action and was pressed
{
button_pressed=FALSE; // the button is now up
sleep_mode=FALSE; // reset sleep flag
ext_int_edge(H_TO_L); // change so interrupts on press
}
if(!input(PIN_B0)) // keep button action sychronized wth button flag
button_pressed=TRUE;
printf("EXT_INT\n\r");
delay_ms(100); // debounce button
output_high(PIN_B1); //** commented out upper park and test if this function called by interrupt
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 09, 2003 6:01 pm |
|
|
Here's an example of how you can use INT_EXT with a push-button
switch. I don't have time to integrate it into your Sleep program.
But hopefully it will give you some hints.
#include "16F877.h"
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use Delay(Clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#zero_ram
//-------------------------------
// GLOBALS
char got_interrupt;
char interrupt_count;
#bit INTF_BIT = 0x0B.1
//-----------------------------
// FUNCTION PROTOTYPES
#int_ext
void int_ext_isr(void);
//=============================
void main(void)
{
// Make pin B0 into an input.
output_float(PIN_B0);
// Enable pullups on all port B pins.
port_b_pullups(TRUE);
// Wait for them to pull up.
delay_us(10);
// Initialize the variables used by the interrupt routine,
// before enabling interrupts.
interrupt_count = 0;
got_interrupt = FALSE;
// Since we have port B pullups enabled, the normal state
// of Pin B0 is a high level. Let's set up the external
// interrupt to occur whenever we get a change from
// a high to a low level.
// We will connect a Normally-open push-button switch to Pin B0.
// The "common" pin of the switch goes to Ground.
// When we press the button, Pin B0 will go to logic low level.
ext_int_edge(H_TO_L);
// Make sure the external interrupt flag bit is cleared
// before enabling external interrupts.
INTF_BIT = 0;
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
// Wait in this loop. Check the got_interrupt flag to see
// if an interrupt occurred. If so, display the count.
// Then clear the flag, wait 50 ms to avoid any "bounce"
// (multiple interrupts) when we press the pushbutton switch,
// which puts Ground on pin B0. Then re-enable interrupts.
while(1)
{
if(got_interrupt == TRUE)
{
printf("%d\n\r", interrupt_count);
// Clear the global flag which was set in the interrupt routine.
got_interrupt = FALSE;
// Wait for debounce period. This allows time for the switch contacts
// to quit bouncing.
delay_ms(50);
// Clear any interrupt which might have occurred during the debounce period.
INTF_BIT = 0;
// Then re-enable interrupts.
enable_interrupts(INT_EXT);
}
}
}
//========================
#int_ext
void int_ext_isr(void)
{
got_interrupt = TRUE;
interrupt_count++;
disable_interrupts(INT_EXT);
} |
|
|
colin
Joined: 08 Sep 2003 Posts: 3
|
thanks |
Posted: Tue Sep 09, 2003 6:10 pm |
|
|
PCM programmer,
thanks for your advice b4 taking off.
thanks again.
Hope your program helps. |
|
|
sliders_alpha
Joined: 03 Mar 2008 Posts: 55
|
|
Posted: Sun Apr 19, 2009 11:57 am |
|
|
i was looking or that, thanks
Code: |
#bit INTF_BIT = 0x0B.1 |
and doing that after each interrupt :
is still required those day (CCS 4.057)? _________________ yup, i know, i don't speak english very well
CCS V4.057 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 19, 2009 12:16 pm |
|
|
The compiler does not clear a peripheral interrupt flag when you call
the enable_interrupt() function. This applies to old versions of the
compiler and to new versions.
For example, these lines do not clear the INTF flag:
Quote: | enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL); |
The modern compiler now has a function to clear the flag,
so you can call it like this:
Quote: | clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL); |
|
|
|
|
|
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
|