scan 4*4 keypad with interrupt

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi.
i write this code for scan 4*4 keypad with interrupt but when i push a key on keypad, ISR Constantly run!!
does any body knows what is the problem of my code?!
thanks.

void InitInterrupt( void )
{
	/* Configure PC0 as input, triggered on rising edge. */
	PORT_ConfigurePins( &PORTB,
	                    0xFF,
	                    false,
	                    false,
	                    PORT_OPC_PULLUP_gc,
	                    PORT_ISC_BOTHEDGES_gc );

	/* Configure Interrupt0 to have medium interrupt level, triggered by pin 0. */
	PORT_ConfigureInterrupt0( &PORTB, PORT_INT0LVL_MED_gc, 0xFF );

	/* Enable medium level interrupts in the PMIC. */
	PMIC.CTRL |= PMIC_MEDLVLEN_bm;

	/* Enable the global interrupt flag. */
	sei();
}


/*! \brief Interrupt service routine for Example4()
 *
 *  When initialized using Example4(), this ISR is called on every rising edge
 *  on PC0.
 */
ISR(PORTB_INT0_vect)
{
   PutCharOnLCD(keypadScan());
}

char key;
char keypadScan()
{
	PORTB.DIR=0x0f;
	PORTB.OUT=0xf0;
	_delay_ms(20);
	key = PORTB.IN;
	PORTB.DIR=0xf0;
	PORTB.OUT=0x0f;
	_delay_ms(20);
	key = key | PORTB.IN;
	switch(key){
		case 0xEE:
		return '1';
		break;
		case 0xDE:
		return '2';
		break;
		case 0xBE:
		return '3';
		break;
		case 0xED:
		return '4';
		break;
		case 0xDD:
		return '5';
		break;
		case 0xBD:
		return '6';
		break;
		case 0xEB:
		return '7';
		break;
		case 0xDB:
		return '8';
		break;
		case 0xBB:
		return '9';
		break;
		case 0xD7:
		return '0';
		break;
		default:
		return '`';
		break;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't do the work in the ISR(). Just set a flag then service it in main().

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for your consideration.
but my code in main is too large! and priority of keypad is very high and if i use flag and check it in main maybe scan keypad faces with delay and it is not good.
do you have any other idea?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the main code execution takes so long then maybe you can check the flag in multiple points in main

check flag
do some work
check flag
do some more work
check flag etc

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

why i can not write scankeypad in ISR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can but you have a code that will take 40ms+ to execute and during that period everything else including other interrupts will have to wait.
If you think this is not a problem then use the way you like but sooner or later you will face problems when more than one interrupt need to be serviced (which can partially be solved using recursive interrupts but can get out of hand)

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for guiding me:).