Hey guys,
I wanted to build a circuit and a program to test switch debouncing routines to see how well each one works. The general idea was that I would build a small circuit with a 7-segment display that starts at the number 0. Each time the button is pressed it generates an interrupt that increments the number, and after a delay of 6 seconds, writes the number to eeprom so that after a reset, the 7-segment would return to that number. This would indicate whether the button press was incrementing the desired loop by more than 1 in order to see how stable the debounce routine is.
The problem in my code is, that after a button press, the number doesn't increment on the display until after the 6 seconds has expired and the eeprom write completes. Before that, it continues to display the previous number. For instance, if the 7-segment is showing a 0 and I press a button, the display continues to show 0 for 6 seconds and then increments to 1, rather than going to 1 immediately after the button press like I want.
You can find the program and a schematic of the circuit below. One other thing I would like to know is whether the way I've programmed the display is the best way (flashing 1 segment at a time rapidly in order to keep current from exceeding device limits). Thanks for the help.
I wanted to build a circuit and a program to test switch debouncing routines to see how well each one works. The general idea was that I would build a small circuit with a 7-segment display that starts at the number 0. Each time the button is pressed it generates an interrupt that increments the number, and after a delay of 6 seconds, writes the number to eeprom so that after a reset, the 7-segment would return to that number. This would indicate whether the button press was incrementing the desired loop by more than 1 in order to see how stable the debounce routine is.
The problem in my code is, that after a button press, the number doesn't increment on the display until after the 6 seconds has expired and the eeprom write completes. Before that, it continues to display the previous number. For instance, if the 7-segment is showing a 0 and I press a button, the display continues to show 0 for 6 seconds and then increments to 1, rather than going to 1 immediately after the button press like I want.
You can find the program and a schematic of the circuit below. One other thing I would like to know is whether the way I've programmed the display is the best way (flashing 1 segment at a time rapidly in order to keep current from exceeding device limits). Thanks for the help.
Rich (BB code):
// CONFIGURATION
#include <htc.h>
#define _XTAL_FREQ 4000000
__CONFIG(BOREN_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO & LVP_OFF);
/*****************************************************/
// GLOBAL VARIABLS
unsigned char fpnum; //FLASH PATTERN NUMBER
unsigned char dlycnt; //COUNTER FOR DELAY
unsigned char count; //GENERAL COUNTER VARIABLE
unsigned char dbnce; //SWITCH DEBOUNCE COUNTER
unsigned char tcnt; //COUNTER FOR TIMER 0
bit ewrit; //SETS READY TO WRITE EEPROM
/*****************************************************/
// MAIN PROGRAM
void main()
{
unsigned char address = 0; //ADDRESS FOR EEPROM DEFINED
// OPTIONS
T0CS = 0; //TMR0 SOURCE IS INTERNAL CLOCK
PSA = 0; //PRESCALER IS ASSIGNED TO TMR0
PS2 = 1;
PS1 = 1;
PS0 = 1; //PRESCALER IS 1:256
// INTCON
INTE = 1; //ENABLE EXTERNAL INTERRUPT ON RB0/INT
GIE = 1; //ENABLE GLOBAL INTERRUPTS
// GPIO PORT
TRISA=0X3C; //TRISA <7:6>OUT <5:2>IN <1:0>OUT
TRISB=0XF; //TRISB <7:4>OUT <3:0>IN
fpnum = eeprom_read(address); //COPY EEPROM TO FPNUM
PORTA=0;
PORTB=0; //CLEAR PORTS
for (count=0; count<4; count++)
{
RB5=1;
__delay_ms(250);
RB5=0;
__delay_ms(250); //FLASH THE DECIMAL POINT 4 TIMES
}
while(1) //BEGIN MAIN LOOP
{
/******************DISPLAY A "1"**********************/
if (fpnum==1)
{
while (ewrit!=0) //IF EEPROM FLAG IS SET
{
eeprom_write(address, fpnum); //WRITE FPNUM TO THE EEPROM
ewrit=0; //AND CLEAR THE EEPROM FLAG
}
while (ewrit==0) //IF EEPROM FLAG IS CLEAR
{
RB6=1;
__delay_us(100);
RB6=0;
RB4=1;
__delay_us(100);
RB4=0;
}
}
/*****************DISPLAY A "2"***********************/
else if (fpnum==2)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RB6=1;
__delay_us(100);
RB6=0;
RA0=1;
__delay_us(100);
RA0=0;
RA7=1;
__delay_us(100);
RA7=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
/****************DISPLAY A "3"************************/
else if (fpnum==3)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RB6=1;
__delay_us(100);
RB6=0;
RA0=1;
__delay_us(100);
RA0=0;
RB4=1;
__delay_us(100);
RB4=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
/***************DISPLAY A "4"*************************/
else if (fpnum==4)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RA1=1;
__delay_us(100);
RA1=0;
RB6=1;
__delay_us(100);
RB6=0;
RA0=1;
__delay_us(100);
RA0=0;
RB4=1;
__delay_us(100);
RB4=0;
}
}
/***************DISPLAY A "5"*************************/
else if (fpnum==5)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RA1=1;
__delay_us(100);
RA1=0;
RA0=1;
__delay_us(100);
RA0=0;
RB4=1;
__delay_us(100);
RB4=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
/***************DISPLAY A "6"*************************/
else if (fpnum==6)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RA1=1;
__delay_us(100);
RA1=0;
RA0=1;
__delay_us(100);
RA0=0;
RA7=1;
__delay_us(100);
RA7=0;
RB4=1;
__delay_us(100);
RB4=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
/*****************DISPLAY A "7"***********************/
else if (fpnum==7)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RB6=1;
__delay_us(100);
RB6=0;
RB4=1;
__delay_us(100);
RB4=0;
}
}
/*****************DISPLAY A "8"***********************/
else if (fpnum==8)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RA1=1;
__delay_us(100);
RA1=0;
RB6=1;
__delay_us(100);
RB6=0;
RA0=1;
__delay_us(100);
RA0=0;
RA7=1;
__delay_us(100);
RA7=0;
RB4=1;
__delay_us(100);
RB4=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
/******************DISPLAY A "9"**********************/
else if (fpnum==9)
{
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RA1=1;
__delay_us(100);
RA1=0;
RB6=1;
__delay_us(100);
RB6=0;
RA0=1;
__delay_us(100);
RA0=0;
RB4=1;
__delay_us(100);
RB4=0;
}
}
/******************DISPLAY A "0"**********************/
else
{
fpnum=0;
while (ewrit!=0)
{
eeprom_write(address, fpnum);
ewrit=0;
}
while (ewrit==0)
{
RB7=1;
__delay_us(100);
RB7=0;
RA1=1;
__delay_us(100);
RA1=0;
RB6=1;
__delay_us(100);
RB6=0;
RA7=1;
__delay_us(100);
RA7=0;
RB4=1;
__delay_us(100);
RB4=0;
RA6=1;
__delay_us(100);
RA6=0;
}
}
}//main program loop
}//main program end
/*************INTERRUPT SERVICE ROUTINE***************/
void interrupt isr(void)
{
/*************BUTTON PRESS INTERRUPT******************/
if(INTF==1) //IF INTF FLAG SET
{
for(dbnce=0; dbnce<20; dbnce++) //DEBOUNCE SWITCH
{
__delay_ms(5);
}
TMR0=0; //CLEAR TIMER 0
T0IE=1; //ENABLE TMR0 INTERRUPTS
fpnum++; //INCREMENT LOOP NUMBER
tcnt=0; //CLEAR THE TIMER COUNTER VARIABLE
INTF=0; //CLEAR THE INTERRUPT FLAG
PORTA=0; //CLEAR PORT A
PORTB=0; //CLEAR PORT B
}
/************TIMER 0 OVERFLOW INTERRUPT***************/
if(T0IF==1) //IF TIMER 0 OVERFLOWED
{
if(tcnt<92) //TIMER COUNTER HAS NOT REACHED 6 SECONDS
{
tcnt++; //INCREMENT THE TIMER COUNTER VARIABLE
T0IF=0; //CLEAR THE TIMER 0 OVERFLOW INTERRUPT FLAG
}
if(tcnt>=92) //TIMER COUNTER HAS REACHED 6 SECONDS
{
T0IF=0; //CLEAR TIMER 0 INTERRUPT FLAG
T0IE=0; //DISABLE TIMER 0 INTERRUPTS
ewrit=1; //SET THE EEPROM WRITE NOTIFIER
}
}
}
Attachments
-
12.4 KB Views: 50
Last edited: