Angry Badger
Member
Hello,
I have two push buttons seperately connected to RB0 and RB1 on an 18F2420. Each triggers the external interrupt on it's respective pin. In the 'first' version of the code for this each button has it's own debounce routine and that works. In the second I've tried to use a common routine for both switches but although it appears to work when single stepping through it in debug mode it doesn't in real time.
The problem must be with the labels assigned to the pins, not sure why; In the ISR for button1 I've made buttonX = button1 and in button2 ISR, buttonX = button2. Then used that common 'buttonX' in the debounce routine.
Any chance of having a quick peek at this code and putting me right?
This works......
This doesn't.......
Thanks in advance for any help.
I have two push buttons seperately connected to RB0 and RB1 on an 18F2420. Each triggers the external interrupt on it's respective pin. In the 'first' version of the code for this each button has it's own debounce routine and that works. In the second I've tried to use a common routine for both switches but although it appears to work when single stepping through it in debug mode it doesn't in real time.
The problem must be with the labels assigned to the pins, not sure why; In the ISR for button1 I've made buttonX = button1 and in button2 ISR, buttonX = button2. Then used that common 'buttonX' in the debounce routine.
Any chance of having a quick peek at this code and putting me right?
This works......
Code:
// Stepper 15 -
// 21.12.10
#include <p18f2420.h>
#include <delays.h> // the code for the delay routines is in here
#pragma config OSC = INTIO7 // internal oscillator with Fosc/4 on RA6, I/O on RA7
#pragma config WDT = OFF
#pragma config PBADEN = ON // portb bits 0 thru 4 as digital input (analog by default at POR)
#define button1 PORTBbits.RB0 // pin 21 stop / start
#define button2 PORTBbits.RB1 // pin 22 direction
#define L297_enable PORTAbits.RA3 // pin 5
#define stepper_dir PORTAbits.RA4 // pin 6
#define clk PORTAbits.RA5 // pin 7
#define DetectsInARow 5
void ISR (void); // label
void clksig (void); // label
void interrupts_init (void); // label
void timer0_init (void); // label
//void Switch_Count (void);
#pragma udata // declare statically allocated uinitialized variables
unsigned char Switch_Count; // 8-bit variable
unsigned char button1flag; // 8-bit variable
unsigned char button2flag; // 8-bit variable
//________________________________________________________________________________________
#pragma code interrupt_vector_high = 0x08 // works ok without, here for reference.
void interrupt_vector_high (void)
{
_asm // assembly instructions follow
goto ISR // jump to interrupt routine
_endasm // end of assembly instructions
}
//________________________________________________________________________________________
#pragma code
void main (void)
{
unsigned char Switch_Count = 0;
OSCCON = 0b01100010; // set Fosc = 4Mhz = 1uS instruction cycle time
ADCON1 = 0xF; // sets all analog channels as digital inputs
INTCON2bits.RBPU = 0; // enable PORTB internal pullups
TRISBbits.TRISB0 = 1; // PORTB bit 0 (connected to switch) is input (1)
TRISBbits.TRISB1 = 1; // PORTB bit 1 (connected to switch) is input (1)
TRISAbits.TRISA3 = 0; // connected to L297 enable pin (10)
TRISAbits.TRISA4 = 0; // connected to L297 cw/ccw pin (17)
TRISAbits.TRISA5 = 0; // connected to L297 clk pin (18)
//LATAbits.LATA3 = 0;
PORTA = 0; // clear portA
PORTB = 0; // clear portb
button1flag = 0;
button2flag = 0;
interrupts_init(); // do the interrupts initialising routine
timer0_init(); // do the t0 initialising routine
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
while (1) // wait here until interrupted by TMR0 or buttons
{
if (button1flag == 1) // do this debounce routine
{
while (button1 != 1); // NOT EQUAL TO 1 - stay here
Switch_Count = 0;
do
{ // monitor switch input for 5 highs in a row (5mS)
if (button1 != 0) // button detected as not pressed
{
Switch_Count++; // increment count
}
else // OTOH if detected as pressed
{
Switch_Count = 0; // reset count
}
Delay10TCYx(100); // wait 1mS
} while (Switch_Count < DetectsInARow); //count <5 loop to DO again
button1flag = 0; // debounce done so clear flag to allow further interrupts
// on this button to be processed.
}
if (button2flag == 1) // do this debounce routine
{
while (button2 != 1); // NOT EQUAL TO 1 - stay here
Switch_Count = 0;
do
{ // monitor switch input for 5 highs in a row (5mS)
if (button2 != 0) // button detected as not pressed
{
Switch_Count++; // increment count
}
else // OTOH if detected as pressed
{
Switch_Count = 0; // reset count
}
Delay10TCYx(100); // wait 1mS
} while (Switch_Count < DetectsInARow); //count <5 loop to DO again
button2flag = 0; // debounce done so clear flag to allow further interrupts
// on this button to be processed.
}
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#pragma interrupt ISR
void ISR (void)
{
// Decision 1
if (INTCONbits.TMR0IF) // T0 rolled over
{
INTCONbits.TMR0IF = 0; // clear the T0 interrupt flag
if (clk ==0) // if RA5 is low
{
clk = 1; // make RA5 high
}
else // OTOH..if it was already high
{
clk = 0; // make it low
}
}
// Decision 2
if (INTCONbits.INT0IF) // button1 was pressed
{
INTCONbits.INT0IF = 0; // reset the interrupt flag
if (button1flag == 0) // if not still in a debounce routine from a previous press
{
button1flag = 1; // start a debounce routine after return from ISR
if (L297_enable == 0) // if L297chip disabled
{
L297_enable = 1; // enable it
}
else // OTOH...if it was already enabled
{
L297_enable = 0; // disable it
}
}
}
// Decision 3
if (INTCON3bits.INT1IF) // button2 was pressed
{
INTCON3bits.INT1IF = 0; // clear the interrupt flag
if (button2flag == 0) // if not still in a debounce routine from a previous press
{
button2flag = 1; // start a debounce routine after return from ISR
if (stepper_dir == 0) // if stepper was rotating ccw
{
stepper_dir = 1; // make it go cw
}
else // OTOH...if it was already going cw
{
stepper_dir = 0; // make it go ccw
}
}
}
} // return from the ISR
void interrupts_init (void) // instructions to initialise the interrupts
{
INTCON2bits.INTEDG0 = 0; // INT0 interrupt on falling edge
INTCON2bits.INTEDG1 = 0; // INT1 interrupt on falling edge
INTCONbits.INT0IF = 0; // clear the interrupt flag for INT0
INTCONbits.INT0IE = 1; // enables external interrupt INT0(RB0)
INTCON3bits.INT1IF = 0; // clear the interrupt flag for INT1
INTCON3bits.INT1IE = 1; // enables external interrupt for INT1 (RB1)
INTCONbits.GIE = 1; // enable all unmasked interrupts
}
void timer0_init (void) // instruction to initialise T0
{
//T0 interrupt settings:
INTCONbits.TMR0IF = 0; // clear T0 interrupt flag
INTCONbits.TMR0IE = 1; // enable T0 interrupt
//T0 control settings:
T0CONbits.T08BIT = 0; // 16 bit mode
T0CONbits.T0CS = 0; // use instruction cycle clock
T0CONbits.PSA = 1; // prescaler NOT used
TMR0H = 0; // clear the high byte
TMR0L = 0; // clear the low byte
T0CONbits.TMR0ON = 1; // start timer !!!!!!!!!!!!!!!
}
Code:
// Stepper 15 -
// 21.12.10
#include <p18f2420.h>
#include <delays.h> // the code for the delay routines is in here
#pragma config OSC = INTIO7 // internal oscillator with Fosc/4 on RA6, I/O on RA7
#pragma config WDT = OFF
#pragma config PBADEN = ON // portb bits 0 thru 4 as digital input (analog by default at POR)
#define button1 PORTBbits.RB0 // pin 21 stop / start
#define button2 PORTBbits.RB1 // pin 22 direction
#define L297_enable PORTAbits.RA3 // pin 5
#define stepper_dir PORTAbits.RA4 // pin 6
#define clk PORTAbits.RA5 // pin 7
#define DetectsInARow 5
void ISR (void); // label
void clksig (void); // label
void interrupts_init (void); // label
void timer0_init (void); // label
#pragma udata // declare statically allocated uinitialized variables
unsigned char Switch_Count; // 8-bit variable
unsigned char buttonX; // 8-bit variable
unsigned char buttonflag; // 8-bit variable
//________________________________________________________________________________________
#pragma code interrupt_vector_high = 0x08 // works ok without, here for reference.
void interrupt_vector_high (void)
{
_asm // assembly instructions follow
goto ISR // jump to interrupt routine
_endasm // end of assembly instructions
}
//________________________________________________________________________________________
#pragma code
void main (void)
{
unsigned char Switch_Count = 0;
OSCCON = 0b01100010; // set Fosc = 4Mhz = 1uS instruction cycle time
ADCON1 = 0xF; // sets all analog channels as digital inputs
INTCON2bits.RBPU = 0; // enable PORTB internal pullups
TRISBbits.TRISB0 = 1; // PORTB bit 0 (connected to switch) is input (1)
TRISBbits.TRISB1 = 1; // PORTB bit 1 (connected to switch) is input (1)
TRISAbits.TRISA3 = 0; // connected to L297 enable pin (10)
TRISAbits.TRISA4 = 0; // connected to L297 cw/ccw pin (17)
TRISAbits.TRISA5 = 0; // connected to L297 clk pin (18)
//LATAbits.LATA3 = 0;
PORTA = 0; // clear portA
PORTB = 0; // clear portb
buttonflag = 0;
interrupts_init(); // do the interrupts initialising routine
timer0_init(); // do the t0 initialising routine
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
while (1) // wait here until interrupted by TMR0 or buttons
if (buttonflag == 1) // do this debounce routine because a switch has been pressed
{
while (buttonX != 1); // NOT EQUAL TO 1 - stay here
Switch_Count = 0;
do
{ // monitor switch input for 5 highs in a row (5mS)
if (buttonX != 0) // button detected as not pressed
{
Switch_Count++; // increment count
}
else // OTOH if detected as pressed
{
Switch_Count = 0; // reset count
}
//Delay10TCYx(100); // wait 1mS
} while (Switch_Count < DetectsInARow); //count <5 loop to DO again
buttonflag = 0; // debounce done so clear flag to allow further interrupts
// on this button to be processed.
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#pragma interrupt ISR
void ISR (void)
{
// Decision 1
if (INTCONbits.TMR0IF) // T0 rolled over
{
INTCONbits.TMR0IF = 0; // clear the T0 interrupt flag
if (clk ==0) // if RA5 is low
{
clk = 1; // make RA5 high
}
else // OTOH..if it was already high
{
clk = 0; // make it low
}
}
// Decision 2 - BUTTON 1
if (INTCONbits.INT0IF) // button1 was pressed
{
INTCONbits.INT0IF = 0; // reset the interrupt flag
buttonX = button1;
if (buttonflag == 0) // if not still in a debounce routine from a previous press
{
buttonflag = 1; // start a debounce routine after return from ISR
if (L297_enable == 0) // if L297chip disabled
{
L297_enable = 1; // enable it
}
else // OTOH...if it was already enabled
{
L297_enable = 0; // disable it
}
}
}
// Decision 3 - BUTTON 2
if (INTCON3bits.INT1IF) // button2 was pressed
{
INTCON3bits.INT1IF = 0; // clear the interrupt flag
buttonX = button2;
if (buttonflag == 0) // if not still in a debounce routine from a previous press
{
buttonflag = 1; // start a debounce routine after return from ISR
if (stepper_dir == 0) // if stepper was rotating ccw
{
stepper_dir = 1; // make it go cw
}
else // OTOH...if it was already going cw
{
stepper_dir = 0; // make it go ccw
}
}
}
} // return from the ISR
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void interrupts_init (void) // instructions to initialise the interrupts
{
INTCON2bits.INTEDG0 = 0; // INT0 interrupt on falling edge
INTCON2bits.INTEDG1 = 0; // INT1 interrupt on falling edge
INTCONbits.INT0IF = 0; // clear the interrupt flag for INT0
INTCONbits.INT0IE = 1; // enables external interrupt INT0(RB0)
INTCON3bits.INT1IF = 0; // clear the interrupt flag for INT1
INTCON3bits.INT1IE = 1; // enables external interrupt for INT1 (RB1)
INTCONbits.GIE = 1; // enable all unmasked interrupts
}
void timer0_init (void) // instruction to initialise T0
{
//T0 interrupt settings:
INTCONbits.TMR0IF = 0; // clear T0 interrupt flag
INTCONbits.TMR0IE = 1; // enable T0 interrupt
//T0 control settings:
T0CONbits.T08BIT = 0; // 16 bit mode
T0CONbits.T0CS = 0; // use instruction cycle clock
T0CONbits.PSA = 1; // prescaler NOT used
TMR0H = 0; // clear the high byte
TMR0L = 0; // clear the low byte
T0CONbits.TMR0ON = 1; // start timer 0
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Thanks in advance for any help.