First of all, your indentation needs work.
Code:
#pragma config FOSC = INTRCIO // Oscillator Selection bit
#pragma config WDTE = OFF // Watchdog Timer Enable bit
#pragma config PWRTE = OFF // Power-up Timer Enable bit
#pragma config MCLRE = OFF // MCLR Pin Function Select bit
#pragma config CP = OFF // Code Protection bit
#pragma config CPD = OFF // Data Code Protection bit
#pragma config BOREN = ON // Brown-out Reset Selection bits
#pragma config IESO = ON // Internal External Switchover bit
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit
#include <xc.h> // Include HITECH CC header file
void FirstFlash(int);
void pause(unsigned short usvalue);
void msecbase(void);
void Initialize(void);
void Delay_5mS(void);
void OneToSixLoop(void);
//----------------------PROGRAM MEMORY----------------------
void Delay_5mS(void)
{
T0IF = 0; //Make sure the T0IF is cleared.
TMR0 = 100; //Preload the TMR0 register.
while (T0IF == 0); //Sit here and wait for Timer0 to overflow.
}
/*** INTERRUPT CODE ***/
void interrupt PB_PressISR(void)
{
if (INTE && INTF)
INTF = 0; //Check to see if the interrupt was caused by
//the external interrupt on RA2.
//If so, clear the external interrupt flag
//to allow subsequent interrupts to be detected.
if (RA2 == 0) //Check to see if the RA2 pin is 0;
{ //(i.e. push button pressed).
Delay_5mS(); //If RA2 is 0, delay for 5mS to filter
} //any switch bounce.
if (RA2 == 0) {
PORTC = 0x00;
OneToSixLoop();
}
}
void main(void)
{
Initialize();
OneToSixLoop();
} //end main
void Initialize(void)
{ /*** Configure Timer0 to overflow ever 5ms ***/
T0CS = 0; // Select FOSC/4 as Timer0 clock source.
T0SE = 0; // Increment TMR0 on rising clock edge.
PSA = 0; // Assign prescaler to Timer0.
PS0 = 0; // Select a 1:32 prescaler.
PS1 = 0;
PS2 = 1;
/*** Initialize Ports ***/
ANSEL = 0; // Intialize A/D ports off
CM1CON0 = 0; // Initialize Comparator 1 off
CM2CON0 = 0; // Initialize Comparator 2 off
PORTC = 0x00; //Clear PortC port
TRISC = 0x00; //All PortC I/O outputs
TRISA = 0xFF; //All PortA I/O inputs
ANS2 = 0;
/*** Initialize Interrupts ***/
INTEDG = 0; // Interrupt occurs on High/Low transition of RA2 voltage.
INTE = 1; // Enable the RA2/PIN17 external interrupt.
INTF = 0; // Clear the external interrupt flag.
GIE = 1; // Enable global interrupt capability on the PIC16F690--
// ***ALWAYS DONE LAST*****
}
//*******************************************************
void pause(unsigned short usvalue) // Pause function
{
unsigned short x;
for (x = 0; x <= usvalue; x++) // Loop through a delay equal to usvalue
{ // in milliseconds.
msecbase(); // Jump to millisec delay routine.
}
}
//*******************************************************
void msecbase(void) // Msecbase function
{
OPTION_REG = 0 b00000001; // Set prescaler to TMRO 1:4
TMR0 = 0xD; // Preset TMRO to overflow on 250 counts
while (!T0IF); // Stay until TMRO overflow flag equals 1
T0IF = 0; // Clear the TMR0 overflow flag
}
//*******************************************************
void FirstFlash(int DiceRND)
{
int Pattern;
INTF = 0;
for (Pattern = 0; Pattern <= 4; Pattern++) {
PORTC = 0xFF;
pause(100);
PORTC = 0x00;
pause(100);
}
if (DiceRND == 1)
PORTC = 0b00001000;
if (DiceRND == 2)
PORTC = 0b01000001;
if (DiceRND == 3)
PORTC = 0b01001001;
if (DiceRND == 4)
PORTC = 0b01100011;
if (DiceRND == 5)
PORTC = 0b01101011;
if (DiceRND == 6)
PORTC = 0b01110111;
pause(10000);
PORTC = 0x00;
}
void OneToSixLoop(void)
{
while (1 == 1)
{
int DiceRND;
for (DiceRND = 1; DiceRND <= 6; DiceRND++) {
if (RA2 == 0) {
FirstFlash(DiceRND);
} else if (DiceRND == 6) {
DiceRND = 0;
}
}
}
}
> I've been trying to use that RA2 pin as both the input (start) trigger for one of my functions and as an interrupt to get out of that function,
Well the hardware isn't that smart.
Every time you hit the switch, you get an interrupt.
Code:
if (RA2 == 0) //Check to see if the RA2 pin is 0;
{ //(i.e. push button pressed).
Delay_5mS(); //If RA2 is 0, delay for 5mS to filter
} //any switch bounce.
if (RA2 == 0) {
PORTC = 0x00;
OneToSixLoop();
}
Bad bad bad!
1. Do not call delay() in an isr
2. Do NOT call a function containing a while(true) loop.
ISR code should do the least amount of work possible.
This is typically
- acknowledge the interrupt to the hardware ( like INTF = 0; )
- read the information (key press, pin, port register)
- store the result somewhere in memory (say a buffer)
- signal (say set a flag variable in memory) that an interrupt has been received, and there is data to process)
- that's it!
From that, you should be able to implement in your main code
- waitForSwitchStateChange()
- isSwitchOn()
- isSwitchOff()
or other functions in a similar style.
For the debouncing, start with something like this.
Do you know for sure that the key isn't already fully debounced? If it is, then count should reliably increment by just one on each switch event.
Code:
int count = 0;
void interrupt PB_PressISR(void)
{
if (INTE && INTF)
INTF = 0; //Check to see if the interrupt was caused by
count++;
}
int main ( ) {
while ( 1 ) {
Delay_20mS();
// format count as a string, send to serial port
}
}