This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Help on Interrupt control; Freescale FRDM-K64F board

Need help on a small interrupt project using Freescale FRDM-K64F demo board.

The goal is:
(1) when power is on, an external LED will blink
(2) Push button SW2, LED will be constantly on
(3) Push button SW3, LED will be off
(4) Push button SW2 and SW3, LED will be constantly on

I wrote code to achieve goal (1), (2), and (3). But after one button is pushed, it sometimes takes two pushes of the other button to achieve the function of that button.
Second question is how to achieve goal (4).

//main.c program
//Start of main.c
#include "MK64F12.h"

void DelayFunction (void);

int main(void)
{ SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; /*Enable Port B Clock Gate Control*/
SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; /*Enable Port C Clock Gate Control*/
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /*Enable Port A Clock Gate Control*/

PORTB_PCR23 = 0x100;
PORTC_PCR6 = 0x90100; //Push button SW2
PORTA_PCR4 = 0x90100; //Push button SW3

GPIOB_PDDR |= (1 << 23); //external LED connected to PTB-23 pin
GPIOC_PDDR |= (0 << 6); //Push button SW2 connected to PORTC-6
GPIOA_PDDR |= (0 << 4); //Push button SW3 connected to PORTA-4

PORTC_ISFR = PORT_ISFR_ISF(0x40); /* Clear interrupt status flag */
PORTA_ISFR = PORT_ISFR_ISF(0x10);
NVIC_EnableIRQ(PORTC_IRQn); /*Enable the PORTC interrupt*/
NVIC_EnableIRQ(PORTA_IRQn);

for (;;)
{

GPIOB_PTOR |= (1 << 23); //Toggle external LED
DelayFunction(); } return 0;
}

void PORTC_IRQHandler(void)
{ PORTA_ISFR = PORT_ISFR_ISF(0x10);
GPIOB_PSOR |= (1 <<23); //Turn on external LED
}

void PORTA_IRQHandler(void)
{ PORTC_ISFR = PORT_ISFR_ISF(0x40);
GPIOB_PCOR |= (1 <<23); //Turn off external LED
}

void DelayFunction(void)
{ int cnt;
for(cnt=0; cnt<1000000; cnt++)
{ }
} //end of main.c

  • You haven't even documented if changed behavior should be while button is pressed, or should continue to persist after button has been released. That makes a difference.

    Both buttons pressed? You need to add some memory feature (where directly polling port pin states represents one memory alternative).

    Another thing - if main loop blinks, it will continue to want to blink even if you keep pressing buttons unless you have level-trigged interrupts since the ISR will just be trigged on the state change. And if you do select level-trigged instead of edge-trigged interrupts then your processor will burn all CPU capacity it has servicing interrupts until all buttons have been released.

    Anyway - with main blinking you can't see instantly that the program reacts to a press unless the press represents an inversion of LED state compared to current state driven by main loop.

    Finally - did you see the instructions how to post source code? How come you didn't?

  • Thanks! I am new to this forum and embedded programming. I added source code at the end of last post.

    The goal is: after button is released, external LED state changes. LED state while button is pressed doesn't matter.

    The error I have is as below:
    (1) power on, LED blinks, running "for" loop of "main" function --> as expected
    (2) push SW2 button and release, running SW2 interrupt, LED constantly on --> as expected
    (3) push SW3 button and release, LED blinks --> wrong, SW3 interrupt should turn LED off
    (4) push SW3 button and release again, LED off --> as expected