IMPORTANT: Updates at bottom of post
I'm trying to set up interrupts for pins 0,5, and 2 of Port D of my FRDM-KL25z. I want the interrupts to trigger on a falling edge. For testing purposes, I have written the ISR to turn on the Red LED, using code that wrote for a previous project (LED.c). Below is my main code file.
I've tried to execute the following steps to set up interrupts:
Unfortunately, the red LED is not turning on when I transition any of the pins from logical 1 to 0. I've confirmed that the pins are functioning as inputs through some code that I haven't included in this post, so I must conclude that I have done something incorrectly or that I have missed a step.
Main code file:
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MKL25Z4.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "LED.h"
/* TODO: insert other definitions and declarations here. */
/*
* @brief Application entry point.
*/
const uint32_t INPUT_CONFIG = PORT_PCR_IRQC(1010) | // IRQ Falling Edge
PORT_PCR_MUX(001) | // Pin set to GPIO
PORT_PCR_DSE(0) | // Low drive strength
PORT_PCR_PFE(0) | // TODO: Passive filter disabled, try enabling if noisy
PORT_PCR_SRE(0) | // TODO: Fast slew rate, look up what slow would mean
PORT_PCR_PE(0) | // Pull resistor is disabled
PORT_PCR_PS(0); // Pull resistor is set to pulldown (but is still disabled)
int main(void) {
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
NVIC_EnableIRQ(PORTD_IRQn);
// LED Initialization
LED_Initialize();
LED_Off();
// Enable and setup 3 pins in PORTA
SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; //Enable the clock to port D
PORTD->PCR[5] = INPUT_CONFIG; //Setup PTD5
PORTD->PCR[0] = INPUT_CONFIG; //Setup PTD0
PORTD->PCR[2] = INPUT_CONFIG; //Setup PTD2
/* Force the counter to be placed into memory. */
volatile static int i = 0 ;
/* Enter an infinite loop, just incrementing a counter. */
while(1) {
i++ ;
/* 'Dummy' NOP to allow source level single stepping of
tight while() loop */
__asm volatile ("nop");
}
return 0 ;
}
void PORTD_IRQHandler(void){
//TODO: USE ISFR to see which pin triggered the interrupt
LEDRed_On();
//CLEAR INTERRUPT FLAG
PORTD->ISFR = 0xFFFFFFFF;
}
LED Utility Functions
#include <MKL25Z4.h>
#include <LED.h>
/*----------------------------------------------------------------------------
Function that initializes LEDs
Note: You need to perform the following steps
1. Turn on the clock gating to the appropriate ports
2. Set the pin MUX to GPIO
3. Set the pin to output
----------------------------------------------------------------------------*/
void LED_Initialize(void){
//ENABLE RED LED
SIM->SCGC5 |= (1 << 10); //Enable the clock to port B
PORTB->PCR[18] = PORT_PCR_MUX(001); //Set up PTB18 as GPIO
PTB->PDDR |= (1 << 18); //Set bit 18 of PDDR for Port B to 1 (Port data direction register)
//ENABLE GREEN LED
//clock is already enabled to port B, don't need to do it again
PORTB->PCR[19] = PORT_PCR_MUX(001); //Set up PTB19 as GPIO
PTB->PDDR |= (1 << 19); //Set bit 19 of PDDR for Port B to 1 (Port data direction register)
//Enable Blue LED
SIM->SCGC5 |= (1 << 12); //Enable the clock to port D
PORTD->PCR[1] = PORT_PCR_MUX(001); //Set up PTD1 as GPIO
PTD->PDDR |= (1 << 1); //Set bit 1 of PDDR for Port D to 1 (Port data direction register)
}
/*---------------------------------------------------------------------------
Three functions for toggling the current state of each LED individually
----------------------------------------------------------------------------*/
void LEDRed_Toggle(void){
if(((PTB->PDOR >> 18) & 0b1) == 1){ //If pin 18 of port B is 1, the LED is off
LEDRed_On(); //so turn it on
}else{
LEDRed_Off(); //else turn it off
}
}
void LEDGreen_Toggle(void){
if(((PTB->PDOR >> 19) & 0b1) == 1){ //If pin 19 of port B is 1, the LED is off
LEDGreen_On(); //so turn it on
}else{
LEDGreen_Off(); //else turn it off
}
}
void LEDBlue_Toggle(void){
if(((PTD->PDOR >> 1) & 0b1) == 1){ //If pin 1 of port D is 1, the LED is off
LEDBlue_On(); //so turn it on
}else{
LEDBlue_Off(); //else turn it off
}
}
/*---------------------------------------------------------------------------
Three functions for toggling the turning ON LEDs individually
----------------------------------------------------------------------------*/
void LEDRed_On(void){
PTB->PCOR |= (1 << 18); //Turn on the red LED (Using PCOR because LED is active-low)
}
void LEDGreen_On(void){
PTB->PCOR |= (1 << 19); //Turn on the green LED (Using PCOR because LED is active-low)
}
void LEDBlue_On(void){
PTD->PCOR |= (1 << 1); //Turn on the blue LED (Using PCOR because LED is active-low)
}
/*---------------------------------------------------------------------------
Three functions for toggling the turning OFF LEDs individually
----------------------------------------------------------------------------*/
void LEDRed_Off(void){
PTB->PSOR |= (1 << 18); //Turn off the red LED (Using PSOR because LED is active-low)
}
void LEDGreen_Off(void){
PTB->PSOR |= (1 << 19); //Turn off the green LED (Using PSOR because LED is active-low)
}
void LEDBlue_Off(void){
PTD->PSOR |= (1 << 1); //Turn on the blue LED (Using PSOR because LED is active-low)
}
/*---------------------------------------------------------------------------
One function turning OFF all 3 LEDs
----------------------------------------------------------------------------*/
void LED_Off(void){
LEDRed_Off();
LEDGreen_Off();
LEDBlue_Off();
}
UPDATE: I have confirmed that bits in Port D's ISFR are being set when pins 0,5, and 2 experience a falling edge. This makes me think that the problem lies how I have enabled Port D interrupts rather than how I have configured the pins. The program continues running as normal despite the interrupt flags not being cleared. It seems that PORTD_IRQHandler is never being called.
UPDATE 2: The interrupts do not seem to be reaching NVIC->ISPR register. Attached is a console screenshot showing this behavior.
已解决! 转到解答。
I discovered the problem. In my declaration of the INPUT_CONFIG const, I wrote.
PORT_PCR_IRQC(1010)
I intended to have this value be binary, but I forgot to write indicate it as such. Replacing it with the below line fixed the issue.
PORT_PCR_IRQC(0b1010)
I discovered the problem. In my declaration of the INPUT_CONFIG const, I wrote.
PORT_PCR_IRQC(1010)
I intended to have this value be binary, but I forgot to write indicate it as such. Replacing it with the below line fixed the issue.
PORT_PCR_IRQC(0b1010)