Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

AutokeyReset function

Status
Not open for further replies.

nayakajit87

Member level 5
Joined
Aug 13, 2018
Messages
84
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
1,065
Dear all.
I am looking for code where i could achieve below functionality.
function requirement: Once Test button pressed in timer interrupt timing should start after 1 min automatically RUN_RESET() should be called.
in below code unless keyreset is pressed RUN_RESET() function wont be called. Can some one suggest how can implement logic

i have used PIC16F886
Code:
#include <htc.h>
#include <stdio.h>
#include <math.h>
#include "delay.h"

__CONFIG(WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & FCMEN_ON & IESO_OFF & CP_OFF & MCLRE_ON);
#define TEST RA5
#define RESET RC0
#define ACK RC1
#define MUTE RC2
#define AUTO_RST RA4 
unsigned char Auto_Counter=0;

void interrupt isr(void) {

 asm("clrwdt"); //ANN

 if (TMR1IF) {
  TMR1IF = 0;
  /// TMR1H = 0xD8; //
  // TMR1L = 0xFC; //
  TMR1H = 0xAF;
  TMR1L = 0xC8;

 }

 INTF = 0;


}

void InitController() {

 OSCCON = 0b01110010; //changes 8Mhz
 WREN = 0;
 WDTCON = 0b00010111; //2sec Watch Dog Reset //STP //ANN
 PORTA = 0b00000000;
 TRISA = 0b00111000;

 TRISB = 0b11001000;
 PORTB = 0b00000000;

 WPUB = 0b00000000;
 ANSEL = 0b00000000;
 ADCON0 = 0b00000000;

 // TRISC = 0b10000111;
 TRISC = 0b11001111;
 PORTC = 0b00000000;
 ANSELH = 0b00000000;

 ADDEN = 0;
 T1OSCEN = 0;
 INTEDG = 0; //falling edge
 INTF = 0;
 INTE = 1;
 PIE1 = 0b00000001;
 PIR1 = 0x01;
 INTCON = 0; //ANN
 T1CON = 0b00000101; //Timer Settings //ANN
 TMR1H = 0xF0; //ANN
 TMR1L = 0x61; //ANN
 TMR1IE = 1;

 PEIE = 1; //ANN
 GIE = 1; // Global interrupt enabled.

}


//********************************************************************************************
//// CHECK IF TEST IS PRESSED
//********************************************************************************************

void Key_CHK_TEST() {

 if (!TEST && !bits.KeyLock_TEST1) {
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_TEST1 = 1;
   RUN_TEST();

  }
 } else if (TEST && bits.KeyLock_TEST1) {
  bits.KeyLock_TEST1 = 0;
  Debounce = 0;
 }

}

//**********************************************************************************************
//// CHECK MUTE KEY pressed
//**********************************************************************************************

void Key_CHK_MUTE() {

 if (!MUTE && !bits.KeyLock_MUTE1) {
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_MUTE1 = 1;
   RUN_MUTE();
  }
 } else if (MUTE && bits.KeyLock_MUTE1) {
  bits.KeyLock_MUTE1 = 0;
  Debounce = 0;
 }

}

//**********************************************************************************************
//// CHECK ACK KEY PRESS IN RUN MODE
//**********************************************************************************************
void Key_CHK_ACK() {
 if (!ACK && !bits.KeyLock_ACK1) { // CHECK IF ack IS PRESSED
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_ACK1 = 1;
   RUN_ACK();
  }
 } else if (ACK && bits.KeyLock_ACK1) {
  bits.KeyLock_ACK1 = 0;
  Debounce = 0;
 }
}

//**********************************************************************************************
//// CHECK RESET KEY PRESS IN RUN MODE
//**********************************************************************************************

void Key_CHK_RESET() {

 if (!RESET && !bits.KeyLock_RESET1) { // CHECK IF SELECT IS PRESSED
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_RESET1 = 1;
   RUN_RESET();
  }
 } else if (RESET && bits.KeyLock_RESET1) {
  bits.KeyLock_RESET1 = 0;
  Debounce = 0;
 }
}






void CHECK_SEQ(void) {
 if (AUTO_RST == 1) { 
  bits.MANUAL_RESET = 1;
  bits.AUTO_RESET = 0;

 }

 if (AUTO_RST == 0) {
  bits.MANUAL_RESET = 0;
  bits.AUTO_RESET = 1;

 }

}





void main() {
 InitController();
 CHECK_SEQ();
 while(1) {
  Key_CHK_TEST();
  Key_CHK_MUTE();
  Key_CHK_ACK();
  if (bits.MANUAL_RESET == 1)
   Key_CHK_RESET();

  if (bits.AUTO_RESET == 1) {
   Auto_Counter++;
   if (Auto_Counter >= 100) {
    Auto_Counter = 0;
    RUN_RESET();
   }

  }
 }



}
 

More information is needed to answer exactly but the easiest way to achieve it is to follow this principle:

Accept that unless you have a very low clock frequency you will not be able to make delays as long as one minute using a timer alone.

inside the ISR:
1. remove the "clrwdt" line. It is useful elsewhere but not inside an ISR because an interrupt routine can continue to run if the rest of the program crashes.
2. Set the values in TMR1H and TMR1L so it overflows and interrupts say every 100mS. Your code is good but I can't tell if the values are correct without knowing the clock frequency.
3. You need to count the interrupts, maybe this is what your "Auto_Counter" is supposed to do but bear in mind that for 1 minute you need to count 60 seconds of 1/10 S (60 * 10) = 600 so a char size variable is too small. Use a volatile int instead.
4. Add the line "if(Auto_Counter > 0) Auto_Counter--;" so if it contains more than zero it counts down at each interrupt. If it reaches zero it stops counting.

in your main() code:
1. Check for the test button being pressed.
2. When pressed, load the value (600 in my example) into Auto_Counter;
3. If "Auto_Counter" holds zero, run your RUN_RESET() routine.
4. If Auto Counter is not yet zero you are still waiting so do a "clrwdt" and go back to step 3.

Note that if you use this method, you can create any delay from 100mS to 327.68 seconds (~5 minutes 45 seconds) by simply loading different numbers into Auto_Counter.
If you want to use the watchdog timer you first have to enable it in the config settings!

Brian.
 

i dint find any sample code in your thread.
 

I have tried but it didn't worked.

Currently its doing like this.

Manually: When Test button pressed RUN_TEST() called;

When MUTE button pressed RUN_Mute() called;
When ACK button pressed RUN_ACK() called;
When RESET button pressed RUN_RST() called;
Auto Mode:

When Test button pressed RUN_TEST() called;

When MUTE button pressed RUN_Mute() called;

When ACK button pressed RUN_ACK() called;

Here RunReset function automatically called.



Now I am looking for feature.Where once Test Button pressed RUN_Test() should be called. Wait for 1 min

within 1 min if any of key is not pressed automatically RUN_RST() should be called.else wait for other key to presses and other operation should be perform.







Code:
void int Test_Button_Counter=0;
void interrupt isr(void) {

if (TMR1IF) {
TMR1IF = 0;
TMR1H = 0xAF;
TMR1L = 0xC8;
if(bits.KeyLock_TEST1==1) {
Test_Button_Counter++;
if(Test_Button_Counter>200) {
Test_Button_Counter=0;
bits.AUTO_RESET =1;
}
}
}

INTF = 0;


}

void main() {

while(1) {
Key_CHK_TEST();
Key_CHK_MUTE();
Key_CHK_ACK();
if (bits.MANUAL_RESET == 1)
Key_CHK_RESET();

if (bits.AUTO_RESET == 1) {

RUN_RESET();
}

 

}

}
 

I have no idea what your schematic and setup is but that isn't what you originally asked for and you didn't do as I suggested.
Firstly, please comment your code and indent the functions, it makes it far easier to read. I've reformatted your original code below:
Code:
void int Test_Button_Counter=0;
void interrupt isr(void)
{
    if (TMR1IF) 
    {
        TMR1IF = 0;
        TMR1H = 0xAF;
        TMR1L = 0xC8;
        if(bits.KeyLock_TEST1==1) 
        {
            Test_Button_Counter++;
            if(Test_Button_Counter>200) 
            {
                Test_Button_Counter=0;
                bits.AUTO_RESET =1;
            }
        }
    }

    INTF = 0;
}


void main() 
{
    while(1) 
    {
        Key_CHK_TEST();
        Key_CHK_MUTE();
        Key_CHK_ACK();
        if (bits.MANUAL_RESET == 1) Key_CHK_RESET();
        if (bits.AUTO_RESET == 1) 
        {
            RUN_RESET();
        }
    }
}

What I suggested was to use to interrupt routine to maintain a count-down timer. It is far easier and quicker to see if a value is zero or not than to compare it to another number.
More like this:
Code:
#define TIMEOUT_PERIOD 100

volatile int Test_Button_Counter=0;

void interrupt isr(void)
{
    if (TMR1IF) 
    {
        TMR1IF = 0;
        TMR1H = 0xAF;       // without knowing your clock and prescaler I can't confirm these values
        TMR1L = 0xC8;
 
        if(Test_Button_Counter > 0) Test_Button_Counter--; // count down to zero then stop
     }

    INTF = 0;
}


void main() 
{
    while(1) 
    {
        Key_CHK_TEST();
        Key_CHK_MUTE();
        Key_CHK_ACK();
        
        if (Test button pressed)
        {
            RUN_TEST();
            Test_Button_Counter = TIMEOUT_PERIOD; // start the countdown period for 1 min.
        }
         
        if (Test_Button_Counter == 0)
        {
            RUN_RST();
        }
    }
}

You need to set the value in the #define according to how fast your clock runs, it will decide how long it take before RUN_RST() is automatically called. Bigger number = longer wait.
Also note two other 'bugs' you might encounter:
1. the main() has a while(1) loop that continues after RUN_RST() has been called, check this is what you want to happen.
2. the timer values are only initialized inside the ISR so the first time it is run after a reset will take 0xFFFF counts instead of 0xAFC8. If you want the timing ot be accurate on the first run, you need to put the values in the timer registers BEFORE the ISR is called as well as inside it.

Brian.
 

i have tested code . All above mentioned condition are working as per mentioned but it is not resetting .i have checked in debug when key pressed It load the value and some iteration it became zero. But it wont Reset at all.

Old Program:
Code:
void Key_CHK_TEST() {

 if (!TEST && !bits.KeyLock_TEST1) {
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_TEST1 = 1;
   RUN_TEST();

  }
 } else if (TEST && bits.KeyLock_TEST1) {
  bits.KeyLock_TEST1 = 0;
  Debounce = 0;
 }

}

void Key_CHK_RESET() {

 if (!RESET && !bits.KeyLock_RESET1) { // CHECK IF SELECT IS PRESSED
  Debounce++;
  if (Debounce > 30) {
   Debounce = 0;
   bits.KeyLock_RESET1 = 1;
   RUN_RESET();
  }
 } else if (RESET && bits.KeyLock_RESET1) {
  bits.KeyLock_RESET1 = 0;
  Debounce = 0;
 }
}


Changes:
Code:
void Key_CHK_TEST() {

	if (!TEST && !bits.KeyLock_TEST1) {
		Debounce++;
		if (Debounce > 30) {
			Debounce = 0;
			bits.KeyLock_TEST1 = 1;
			RUN_TEST();
			TCounter=TIMEOUT_PERIOD;

		}
	} else if (TEST && bits.KeyLock_TEST1) {
		bits.KeyLock_TEST1 = 0;
		Debounce = 0;
	}

}


void RUN_TEST() {

	bits.KeyTEST_PRESS=1;

		if(TCounter==0)
	{
		bits.KeyLock_TEST1 = 0;
		bits.KeyLock_RESET1 = 1;
		bits.KeyTEST_PRESS = 1;
     	RUN_RESET();
	}

}


void RUN_RESET() {

	if (bits.KeyTEST_PRESS == 1)
		bits.KeyTEST_PRESS = 0;
		
		// Other Function related to REset fun But not any flags realted to Key
		
	}
 

This what changes i made.When i debug TestFlag became 1 and after define time became zero but it wont call reset funs(). for testing i kept Test period very low instead of 200 kept 5.

Code:
#define AUTO_RST		RA4
#define RESET			RC0
#define	ACK				RC1
#define MUTE			RC2

volatile int TCounter=0;
unsigned char TestFlag=0;
unsigned char Debounce =0;
#define TIMEOUT_PERIOD 5
unsigned char TestFlag=0;

void Key_CHK_TEST() {

	if (!TEST && !bits.KeyLock_TEST1) {
		Debounce++;
		if (Debounce > 30) {
			Debounce = 0;
			bits.KeyLock_TEST1 = 1;
			RUN_TEST();
			TCounter=TIMEOUT_PERIOD;
			TestFlag=1;

		}
	} else if (TEST && bits.KeyLock_TEST1) {
		bits.KeyLock_TEST1 = 0;
		Debounce = 0;

	}

}


void RUN_TEST() {
	bits.KeyTEST_PRESS=1;
	// funs realted to Test
}

void Key_CHK_MUTE() {

	if(!MUTE && !bits.KeyLock_MUTE1) {
		Debounce++;
		if(Debounce >30) {
			Debounce = 0;
			bits.KeyLock_MUTE1 = 1;
			RUN_MUTE();
		}
	} else if(MUTE && bits.KeyLock_MUTE1) {
		bits.KeyLock_MUTE1 = 0;
		Debounce = 0;
	}

}


void RUN_MUTE() {

// funs related to Run_Mute

}


void Key_CHK_ACK() {
	if(!ACK && !bits.KeyLock_ACK1 ) {	// CHECK IF ack IS PRESSED
		Debounce++;
		if(Debounce >30) {
			Debounce = 0;
			bits.KeyLock_ACK1 = 1;
			RUN_ACK();
		}
	} else if(ACK && bits.KeyLock_ACK1) {
		bits.KeyLock_ACK1 = 0;
		Debounce = 0;
	}
}


void RUN_ACK() {
	// funs related to RunACk

}

void Key_CHK_RESET() {

	if(!RESET && !bits.KeyLock_RESET1) {		// CHECK IF SELECT IS PRESSED
		Debounce++;
		if(Debounce > 30) {
			Debounce = 0;
			bits.KeyLock_RESET1 = 1;
			RUN_RESET();
		}
	} else if(RESET && bits.KeyLock_RESET1) {
		bits.KeyLock_RESET1 = 0;
		Debounce = 0;
	}
}

void RUN_RESET() {

	if (bits.KeyTEST_PRESS == 1)
		bits.KeyTEST_PRESS = 0;
	// fUNC ASSOCIATED WITH RESET
}

void ISR() {
	if (TMR1IF) {
		TMR1IF = 0;
		TMR1H = 0xAF;
		TMR1L = 0xC8;

		if(TCounter>0) {
			TCounter--;
		}

	}

	INTF = 0;
	if (PRG_RUN == 1) {
		if (bits.KeyTEST_PRESS == 0) {
		}
	}

}


void CHECK_SEQ(void) { //STP

	if (AUTO_RST==1) { // CHECK IF HIGH - MANUAL
		bits.MANUAL_RESET = 1;
		bits.AUTO_RESET = 0;

	}

	if (AUTO_RST==0) { // CHECK IF LOW - AUTO
		bits.MANUAL_RESET = 0;
		bits.AUTO_RESET = 1;

	}

}
void main() {
	InitController();
	CHECK_SEQ();
	while(1) {
		Key_CHK_TEST() ;
		Key_CHK_MUTE();
		Key_CHK_ACK();

		if(TestFlag==1) {
			if(TCounter==0) {
				bits.KeyTEST_PRESS=0;
				RUN_RESET();
				TestFlag=0;
			}

		}


		if (bits.MANUAL_RESET == 1)
			Key_CHK_RESET();

		if (bits.AUTO_RESET == 1) {

			RUN_RESET();
		}
	}

}
 

I can provide you a working code but only mikroC PRO PIC code if you are interested and if you can port it to your XC8 code because I don't use XC8 Compiler much.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top