External interrupts on STM32F407VGT6 using Easy MxPro v7

mikroC, mikroBasic and mikroPascal for PRO ARM® MCUs, supporting STM32, Tiva, Kinetis, & CEC devices
Post Reply
Author
Message
jfarrant
Posts: 11
Joined: 27 Dec 2016 21:05

External interrupts on STM32F407VGT6 using Easy MxPro v7

#1 Post by jfarrant » 02 Jan 2018 21:43

I am needing some help with the program attached. Basically I have PD0, PD1, PD2, and PD3 configured as inputs with pull down resistors waiting for a logic level high which should trigger an external interrupt and toggle PD4, PD5, PD6, or PD7 respectively. For example applying 3.3 volts to PD0 should trigger the EXTI0 and in the handler for this interrupt PD4 output is toggled. The project is attached as a .zip and for quick reference the code is shown below:

The first block of code was written to test the Ext oscillator clock speed by routing it to PC9 (MCO2).

The program compiles error free, but when I load it onto the microcontroller none of the outputs toggle. I must have missed a step somewhere?


/*******************************************************************************
THIS IS AN EXAMPLE TO TOGGLE PORT D GPIO'S ON A STM32F407VGT6 MCU. THE FBUS
FREQUENCY IS 168 MHz.

GPIOD WILL BE USED FOR ALL INPUTS AND OUTPUTS. GPIOD PINS 0, 1, 2, 3 ARE CONFIGURED AS INPUTS WITH
INTERNAL PULL DOWN RESISTORS, AND WITH RISING EDGE DETECTION ENABLED. THEY ARE MAPPED AS EXTERNAL
INTERRUPTS IN THE SYSCFG_EXTI_CR1 REGISTER PORT D EXTI0 through EXTI3.

GPIOD PINS 4, 5, 6, AND 7 ARE CONFIGURED AS GENERAL PURPOSE, PUSH/PULL, MEDIUM SPEED OUTPUTS.

UPON APPLYING A LOGIC LEVEL HIGH TO EITHER PIN PD0, PD1, PD2, OR PD3, THE RESPECTIVE OUTPUT LED
WILL TOGGLE (PD4, PD5, PD6, OR PD7).

*****NOTE ON MIKROE development board STM32F407VGT6 THE FOLLOWING PINS CANT BE USED FOR GPIO,
PA1, PA2, PA7. THEY ARE RESERVED FOR ALTERNATE FUNCTIONS.

AUTHOR J. FARRANT
01/02/2017

*******************************************************************************/

/*******************************************************************************
CONFIGURE PC9 AS Alternate function DIGITAL OUTPUT
*******************************************************************************/
// CALL THIS FUNCTION TO TEST THE CLOCK FOR 25 MHz ON PIN PC9. COMMENT OUT AFTER
// TEST SUCCESSFUL.

void MCO2_Test(void){
// Not necessary to enable the clock because signal comes from extern osc.
GPIOC_MODER |= 0x00080000; // Write a 1 to bit 19
GPIOC_MODER &= ~0x00040000; // Clear bit 18
GPIOC_AFRH &= ~0x000000F0; // Clear bits 4 through 7 to set AF0
}
/**************************************************************************************************
CONFIGURE GPIOD FOR GPIO WITH EXTERNAL INTERRUPTS
**************************************************************************************************/

void PORTD_Init(void){

unsigned long int clock_stable;
RCC_AHB1ENR |= 0x00000008; // (1) enables clock on GPIO PORT D

// INPUTS
clock_stable = RCC_AHB1ENR; // (2) Allows clock to stabilize
GPIOD_MODER &= ~0x000000FF; // (3) Sets Pins 0 through 3 as inputs
GPIOD_PUPDR |= 0x000000AA; // (4) GPIOD Pins 0 through 3 with Pull down resistor
GPIOD_PUPDR &= ~0x00000055; // (4) Cleared necessary bits to accomplish above step

// OUTPUTS
GPIOD_MODER |= 0x00005500; // (5) GPIOD pins 4 through 7 as ouputs
GPIOD_MODER &= ~0x0000AA00; // (5) Cleared necessary bits to accomplish above
GPIOD_OTYPER &= ~0xF0; // (6) Clear bits 4 through 7 to set all to push pull
GPIOD_OSPEEDR |= 0x00005500; // (7) Sets to medium Toggle speed
GPIOD_OSPEEDR &= ~0x0000AA00; // (7) Clears Necessary bits to accomplish above
GPIOD_PUPDR &= ~0x0000FF00; // (8) No pull up or down on pins 4 through 7
GPIOD_ODR &= ~0x00F0; // (9) Initializes outputs 4 through 7 as LOW

// External interrupt pin mapping
SYSCFG_EXTICR1 |= 0x0003; // (10) Route PD0 to to EXTI0
SYSCFG_EXTICR1 |= 0x0030; // (11) Route PD1 to to EXTI1
SYSCFG_EXTICR1 |= 0x0300; // (12) Route PD2 to to EXTI2
SYSCFG_EXTICR1 |= 0x3000; // (13) Route PD3 to to EXTI3

// External interrupt configuration
EXTI_IMR |= 0x000F; // (14) Interrupt request from 0, 1, 2, 3 not masked
EXTI_EMR &= ~0x0F; // () Mask the event mask register
EXTI_RTSR |= 0x000F; // (15) Rising edge detection for PD0 through PD3
EXTI_FTSR &= ~0x000F; // (16) Falling edge detection disabled PD0 thru PD3

// Clear theinterrupt pending flags
EXTI_PR.PR0 = 1;
EXTI_PR.PR1 = 1;
EXTI_PR.PR2 = 1;
EXTI_PR.PR3 = 1;

// NVIC configuration
NVIC_SetIntPriority(IVT_INT_EXTI0, _NVIC_INT_PRIORITY_LVL0); // PD0 highest Pri.
NVIC_SetIntPriority(IVT_INT_EXTI1, _NVIC_INT_PRIORITY_LVL1); // PD1 2nd hi. Pri.
NVIC_SetIntPriority(IVT_INT_EXTI2, _NVIC_INT_PRIORITY_LVL2); // PD2 3rd hi. Pri.
NVIC_SetIntPriority(IVT_INT_EXTI3, _NVIC_INT_PRIORITY_LVL3); // PD3 4th hi. Pri.
NVIC_IntEnable(IVT_INT_EXTI0); // NVIC EXTI enable
NVIC_IntEnable(IVT_INT_EXTI1); // NVIC EXTI enable
NVIC_IntEnable(IVT_INT_EXTI2); // NVIC EXTI enable
NVIC_IntEnable(IVT_INT_EXTI3); // NVIC EXTI enable

}

/**************************************************************************************************
External interrupt execution functions
**************************************************************************************************/
// When PD0 is pressed execute the following task:
void Switch_0() iv IVT_INT_EXTI0 ics ICS_AUTO {
GPIOD_ODR ^= 0x0010; // Toggle PD4
EXTI_PR.PR0 = 1; // Acknowledge interrupt
}

// When PD1 is pressed execute the following task:
void Switch_1() iv IVT_INT_EXTI1 ics ICS_AUTO {
GPIOD_ODR ^= 0x0020; // Toggle PD5
EXTI_PR.PR1 = 1; // Acknowledge interrupt
}

// When PD2 is pressed execute the following task:
void Switch_2() iv IVT_INT_EXTI2 ics ICS_AUTO {
GPIOD_ODR ^= 0x0040; // Toggle PD6
EXTI_PR.PR2 = 1; // Acknowledge interrupt
}

// When PD3 is pressed execute the following task:
void Switch_3() iv IVT_INT_EXTI3 ics ICS_AUTO {
GPIOD_ODR ^= 0x0080; // Toggle PD7
EXTI_PR.PR3 = 1; // Acknowledge interrupt
}

/**************************************************************************************************
MAIN
**************************************************************************************************/
void main() {

MCO2_Test(); // Call MCO2 Test Function to route 25 MHz to PC9
PORTD_Init(); // Call PORTD_Init function
EnableInterrupts(); // Enable global interrupts

while(1); // Wait for interrupts
}
Attachments
EXTI_HELP.zip
(297.16 KiB) Downloaded 143 times

User avatar
dusan.poluga
mikroElektronika team
Posts: 780
Joined: 02 Feb 2017 14:21

Re: External interrupts on STM32F407VGT6 using Easy MxPro v7

#2 Post by dusan.poluga » 03 Jan 2018 09:57

Hi,

We have a written example for external interrupts that comes with our compilers for this micro controller.
I am attaching the example to this post.

Best Regards,
Attachments
External Interrupt.zip
(6.31 KiB) Downloaded 174 times
Dusan Poluga.

jfarrant
Posts: 11
Joined: 27 Dec 2016 21:05

Re: External interrupts on STM32F407VGT6 using Easy MxPro v7

#3 Post by jfarrant » 04 Jan 2018 02:30

Hi Dusan,

I have fixed my code and it is working properly now. There were two issues I found.

1. I had to enable the SYSCFGEN bit in the APB2 register.
So others reading this can benefit it can be done a few different ways:

RCC_APB2ENR |= 0x00004000; // bit 14 Hi

OR

SYSCFGEN_bit = 1;


2. Because the Clock MCU is operating at such a fast speed, without a delay in my external interrupt handlers nothing ever appeared to happen when I pressed the buttons. After adding a very small delay everything worked as it should!

Example of the delay added to external interrupt handler:

// When PD0 is pressed execute the following task:
void Switch_0() iv IVT_INT_EXTI0 ics ICS_AUTO {
GPIOD_ODR ^= 0x0010; // Toggle PD4
EXTI_PR.B0 = 1; // Acknowledge interrupt
delay_ms(20);
}

User avatar
dusan.poluga
mikroElektronika team
Posts: 780
Joined: 02 Feb 2017 14:21

Re: External interrupts on STM32F407VGT6 using Easy MxPro v7

#4 Post by dusan.poluga » 04 Jan 2018 13:45

Hi,

Thank you for sharing this information with us.

I am glad that you have resolved your problem.

Best Regards,
Dusan Poluga.

Post Reply

Return to “ARM PRO Compilers”