|
|
View previous topic :: View next topic |
Author |
Message |
cascaded Guest
|
Single Button Counter |
Posted: Thu Oct 02, 2008 7:18 am |
|
|
Anybody know any program for a pushbutton to make counter on LCD?
And how to make it read during button_Released or during button_pushed?
TQ |
|
|
Guest
|
|
Posted: Thu Oct 02, 2008 3:24 pm |
|
|
you can either use interrupt on portb - #int_rb
or external trigger - setup_ext_int
or ccp module in capture mode |
|
|
Guest
|
|
Posted: Thu Oct 02, 2008 3:25 pm |
|
|
sorry,
external interrupt is ext_int_edge() function |
|
|
cascaded Guest
|
|
Posted: Thu Oct 02, 2008 5:51 pm |
|
|
Can anybody give coding example or tutorial? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 03, 2008 6:22 pm |
|
|
Mark has some code for this in the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=22145
See the code posted below. It has been modified so it will work with
a 4 MHz crystal. It also has the bug-fix incorporated into it that was
mentioned in one of the replies to Mark's original post. It also uses
the "Flex" LCD driver from the Code Library forum.
I don't really want to do any more work on this for you. You must write
your own code. If the code posted below seems too complicated then
look at these other links for a few more examples:
Here is the "Button Command" code that I wrote for the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837
Here's a version of it that polls the buttons during a timer interrupt:
http://www.ccsinfo.com/forum/viewtopic.php?t=31849
Here is another button debounce program that's even more simple:
http://www.ccsinfo.com/forum/viewtopic.php?t=19874
Mark's code (modified slightly, as listed above):
Code: |
// Multi-Event Switch Action for Microchip Microcontrollers
#include <16F877.h>
#fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#include "flex_lcd.c"
#define CLICK_TIME 250 // Time to press/release a click in ms
#define DBL_CLICK_TIME 500 // Time to wait for a dbl_click in ms
#define SWITCH_READ_TIME 10 // Interval to read the switches in ms
#define NUM_SWITCHES 2 // Max 8 switches
#define SW0_PIN PIN_A4
#define SW1_PIN PIN_B0
#define LED0 PIN_B3
#define LED1 PIN_B2
// Different types of click events
enum SWITCH_STATES
{
SWITCH_IDLE,
SWITCH_DOWN,
SWITCH_HELD,
SINGLE_CLICK,
DOUBLE_CLICK
};
int8 Miliseconds;
int8 Read_Switch_Timer = 0;
int1 Read_Switch_Flag = FALSE;
int16 Click_Timer[NUM_SWITCHES];
enum SWITCH_STATES Switch_State[NUM_SWITCHES];
//--------------------------------------------------
#int_timer2
void timer2_isr(void)
{
if (Miliseconds < 0xFF)
Miliseconds++;
}
//--------------------------------------------------
void Switch_Released(int8 number)
{
// Make sure this is a valid switch
if (number < NUM_SWITCHES)
{
switch (Switch_State[number])
{
case SWITCH_DOWN:
// Set the timer to the maximum time between a press and release to
// consider this a single click
Click_Timer[number] = CLICK_TIME;
Switch_State[number] = SINGLE_CLICK;
break;
case SWITCH_HELD:
// Just set the timer to a small number so that it will fire as soon
// as we release the switch
Click_Timer[number] = 1;
// Don't change the state here, the timers will take care of it
break;
case SINGLE_CLICK:
// Set the timer for the maximum time we will wait for a double click
Click_Timer[number] = DBL_CLICK_TIME;
Switch_State[number] = DOUBLE_CLICK;
break;
case DOUBLE_CLICK:
// The user is just clicking away at the button. We won't really do
// until he stops or we could cancel the operation by setting the state
// to idle and the timer to 0
Click_Timer[number] = DBL_CLICK_TIME;
Switch_State[number] = DOUBLE_CLICK;
break;
default:
Click_Timer[number] = 0;
Switch_State[number] = SWITCH_IDLE;
break;
}
}
}
//--------------------------------------------------
void Switch_Pressed(int8 number)
{
// Make sure this is a valid switch
if (number < NUM_SWITCHES)
{
// Set the state to down only if we haven't just processed a click
if (Switch_State[number] == SWITCH_IDLE)
Switch_State[number] = SWITCH_DOWN;
Click_Timer[number] = DBL_CLICK_TIME;
}
}
//--------------------------------------------------
// Handles debouncing of the switches
void Switch_Read_Value(void)
{
static int8 last_read = 0xFF;
static int8 last_state = 0xFF;
static int8 debounce_count;
int8 result = 0xFF;
int8 i;
int8 changed;
if (!input(PIN_A4))
bit_clear(result,0);
if (!input(PIN_B0))
bit_clear(result,1);
// See if it changed
if (result != last_read)
{
// It did so debounce it
debounce_count = 5;
last_read = result;
}
// We are debouncing
else if (debounce_count)
{
debounce_count--;
// Done debouncing
if (debounce_count == 0)
{
// See if the state of the switch has changed
changed = (result ^ last_state);
// Determine what type of event occurred
for(i=0;i<8;i++)
{
if (bit_test(changed,i))
{
if (bit_test(result,i))
Switch_Released(i);
else
Switch_Pressed(i);
}
// Save the current state
last_state = result;
}
}
}
}
//--------------------------------------------------------------
// What we do if a switch was pressed longer than the click time
void Switch_Pressed_Event(int8 number)
{
// TO ADD MORE SWITCHES you need to add the cases
switch(number)
{
case 0:
// Light an LED on RB3 of the picdem2 plus board
output_high(LED0);
printf(lcd_putc,"\fSW1 Pressed");
break;
case 1:
// Light an LED on RB2 of the picdem2 plus board
output_high(LED1);
printf(lcd_putc,"\fSW2 Pressed");
break;
default:
break;
}
}
//-----------------------------------------------------------------
// What we do if a switch was pressed and held longer than the click time
// and then released
void Switch_Release_Event(int8 number)
{
// TO ADD MORE SWITCHES you need to add the cases
switch(number)
{
case 0:
// Turn off the LED on RB3 of the picdem2 plus board
output_low(LED0);
printf(lcd_putc,"\fSW1 Released");
break;
case 1:
// Turn off the LED on RB2 of the picdem2 plus board
output_low(LED1);
printf(lcd_putc,"\fSW2 Released");
break;
default:
break;
}
}
//----------------------------------------------------------------
// What we do on a single click
void Single_Click_Event(int8 number)
{
// TO ADD MORE SWITCHES you need to add the cases
switch(number)
{
case 0:
// Light an LED on RB3 of the picdem2 plus board
output_high(LED0);
if (Switch_State[1] == SWITCH_HELD)
printf(lcd_putc,"\fSW1 Click\nWhile SW2 Held");
else
printf(lcd_putc,"\fSW1 Click");
break;
case 1:
// Light an LED on RB2 of the picdem2 plus board
output_high(LED1);
if (Switch_State[0] == SWITCH_HELD)
printf(lcd_putc,"\fSW2 Click\nWhile SW1 Held");
else
printf(lcd_putc,"\fSW2 Click");
break;
default:
break;
}
}
//----------------------------------------------------
void Double_Click_Event(int8 number)
{
switch(number)
{
case 0:
// Turn off the LED on RB3 of the picdem2 plus board
output_low(LED0);
if (Switch_State[1] == SWITCH_HELD)
printf(lcd_putc,"\fSW1 Dbl_Click\nWhile SW2 Held");
else
printf(lcd_putc,"\fSW1 Dbl_Click");
break;
case 1:
// Turn off the LED on RB2 of the picdem2 plus board
output_low(LED1);
if (Switch_State[0] == SWITCH_HELD)
printf(lcd_putc,"\fSW2 Dbl_Click\nWhile SW1 Held");
else
printf(lcd_putc,"\fSW2 Dbl_Click");
break;
default:
break;
}
}
//---------------------------------------------------
void Switch_Timers(void)
{
int8 i;
if(Read_Switch_Timer == 0)
Read_Switch_Flag = TRUE;
else
Read_Switch_Timer--;
for(i=0; i<NUM_SWITCHES; i++)
{
if(Click_Timer[i])
{
Click_Timer[i]--;
if(Click_Timer[i] == 0)
{
switch (Switch_State[i])
{
case SWITCH_DOWN:
Switch_Pressed_Event(i);
Switch_State[i] = SWITCH_HELD;
break;
case SWITCH_HELD:
Switch_Release_Event(i);
Switch_State[i] = SWITCH_IDLE;
break;
case SINGLE_CLICK:
Single_Click_Event(i);
Switch_State[i] = SWITCH_IDLE;
break;
case DOUBLE_CLICK:
Double_Click_Event(i);
Switch_State[i] = SWITCH_IDLE;
break;
default:
Switch_State[i] = SWITCH_IDLE;
break;
}
}
}
}
}
// Handles all our switch tasks
void Switch_Tasks(void)
{
if (Read_Switch_Flag)
{
Switch_Read_Value();
Read_Switch_Timer = SWITCH_READ_TIME;
Read_Switch_Flag = FALSE;
}
}
//---------------------------------
// System counter
void System_Tick(void)
{
while (Miliseconds)
{
Switch_Timers();
Miliseconds--;
}
}
//=======================================================
void main (void)
{
int8 i;
// Initialize all of the timers and states
for(i=0; i<NUM_SWITCHES; i++)
{
Click_Timer[i] = 0;
Switch_State[i] = SWITCH_IDLE;
}
setup_timer_2(T2_DIV_BY_4, 250, 1); // Interrupt every 1ms
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
lcd_init();
printf(lcd_putc,"PICDEM Switch\nEvent Test");
Miliseconds = 0;
while(1)
{
System_Tick();
Switch_Tasks();
}
} |
|
|
|
Guest
|
|
Posted: Sat Oct 04, 2008 7:30 am |
|
|
Thanks. That's what i'm looking for. TQ |
|
|
|
|
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
|