PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 05, 2015 4:58 pm |
|
|
Here is a demo program which shows how to debounce a push-button
switch by polling it in an interrupt routine which runs every 10 ms.
This program will display a 'P' in a terminal window (ex. TeraTerm)
each time you press the push-button. Example (pressed it 5 times):
Code: |
#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
// This pushbutton must have a pull-up (4.7K or 10K, etc)
// on the PIC pin, and the other end of the switch must
// go to ground. The idle state will be at Vdd, and the
// "pushed" state of the button will be at ground.
#define BUTTON_PIN PIN_B0
// Example of external circuit for pushbutton
//
// +5v
// |
// <
// > 4.7K
// < ___ Pushbutton switch
// To | _|_|_
// PIC -----------------o o------
// pin |
// --- GND
// -
//
//----------------------------------------------
// The Timer0 preload value calculated below will
// will give a Timer0 interrupt rate of 100 Hz.
// This is intended for a PIC oscillator of 4 to 20 MHz.
// The code below saves you from having to manually
// calculate the Timer0 preload value. It's done for you.
#define FOSC getenv("CLOCK") // Get PIC oscillator frequency
#if(FOSC < 21000000)
#define TIMER0_PRELOAD (256 - (FOSC/4/256/100))
#else
#error Oscillator frequency is too high: FOSC
#endif
//----------------------------------------------
// Setup Timer0 to provide a 10ms tick for the pushbutton
// debounce interrupt.
void timer0_init(void)
{
setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
set_timer0(TIMER0_PRELOAD);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
//------------------------------
// This global value is how the debounce interrupt
// routine communicates with the code in main()
// to inform it if the button has been pushed.
int8 button_pressed = FALSE;
//------------------------------
// The button pin is polled every 10ms in this interrupt
// routine. This assumes the "bounce" period for the
// button is less than 10 ms. Usually this will be the
// case, except for very cheap, sloppy switches.
#int_timer0
void timer0_isr(void)
{
int8 current_value;
static int8 previous_value = 1; // Idle state of button is a logic high
set_rtcc(TIMER0_PRELOAD); // Reload Timer0 for 10ms rate
current_value = input(BUTTON_PIN); // Read the button
// Look for a falling edge, which indicates the
// button has been pushed.
if((previous_value == 1) && (current_value == 0))
button_pressed = TRUE;
previous_value = current_value; // Save current value for next time
}
//===================================
void main()
{
printf("Start: ");
timer0_init();
while(TRUE)
{
if(button_pressed == TRUE)
{
button_pressed = FALSE; // Clear the button pushed flag
// Display a 'P' in TeraTerm every time the button is pushed.
putc('P');
}
}
}
|
This post has an alternative method of debouncing a push-button switch,
that does not use a timer interrupt:
http://www.ccsinfo.com/forum/viewtopic.php?t=53622&start=7
Edit: 'previous_value' must be a static variable.
Last edited by PCM programmer on Fri Jul 12, 2019 12:42 am; edited 1 time in total |
|