stm32f103 External Interrupt Programming
Interruption, as the name implies, is to stop the work at hand, to do another urgent work, finish the urgent work and then back to continue to do the work at hand.
MCU, like people, sometimes there are more urgent procedures need to execute, and then return to execute before the execution of the program. Try it today. How to let the microcontroller interrupt the current task, perform other tasks.
Let's take a look at the resources on my lab board for external interrupts:
For example, under the board there are three independent keys, the right bottom has three SMD LED, wherein the circuit diagram of these two parts as shown:
1, independent key circuit:
It is known that three independent keys are connected to the PB7, PB8, and PB9 pins of the STM32 respectively.
2. LED Circuit:
It is known that three LEDs are connected to the PC1, PC3, PC13 pins of the STM32, respectively,
Our plan is when press the button K2, let the Light D2 blink for a while. At this time K2 is an external interrupt, when pressed, triggering interrupt service function, the light D2 flashing program is the interrupt service function.
Now open Keil V5 for programming:
Check the following options in the Manage Run-time environment interface first:
When the tick is complete, start programming:
1. Write the interrupt initialization function:
void Exit_configuration (void)
{
/*
* Define Structure body
*/
Exti_inittypedef exti_initstructure;
Gpio_inittypedef gpio_initstructure;
Nvic_inittypedef nvic_initstructure;
/*
* Clock configuration (to turn on the Afio clock)
*/
Rcc_apb2periphclockcmd (rcc_apb2periph_gpiob| rcc_apb2periph_gpioc| rcc_apb2periph_afio,enable);
/*
* External interrupt use of GPIO configuration using PB Port 9 pin
*/
Gpio_initstructure.gpio_pin = Gpio_pin_9;
Gpio_initstructure.gpio_mode = gpio_mode_in_floating;
Gpio_init (Gpiob, &gpio_initstructure);
/*
* External interrupt using GPIO pin that is PB Port 9 pin connected to EXTILine9
*/
Gpio_extilineconfig (GPIO_PORTSOURCEGPIOB,GPIO_PINSOURCE9);
/*
* Configure external interrupts
*/
Exti_initstructure.exti_line =exti_line9;
Exti_initstructure.exti_mode = Exti_mode_interrupt;
Exti_initstructure.exti_trigger = exti_trigger_rising;
Exti_initstructure.exti_linecmd = ENABLE;
Exti_init (&exti_initstructure);
/*
* Configuration Nvic
*/
Nvic_prioritygroupconfig (NVIC_PRIORITYGROUP_0);
Nvic_initstructure.nvic_irqchannel = EXTI9_5_IRQN;
nvic_initstructure.nvic_irqchannelpreemptionpriority = 0;
nvic_initstructure.nvic_irqchannelsubpriority = 0;
Nvic_initstructure.nvic_irqchannelcmd = ENABLE;
Nvic_init (&nvic_initstructure);
}
2, after the interrupt initialization function has been written, it is necessary to write the Interrupt service function:
void Exti9_5_irqhandler (void)
{
U16 aa=10;
if (Exti_getitstatus (exti_line9)!=reset) {
Gpio where the initialization lamp is located
Gpio_inittypedef gpio_initstructure;
Gpio_initstructure.gpio_pin = Gpio_pin_3;
Gpio_initstructure.gpio_mode = gpio_mode_out_pp;
Gpio_init (GPIOC, &gpio_initstructure);
Let the light blink through the loop
while (AA) {
Gpio_setbits (Gpioc,gpio_pin_3);
Delay_us (100000);
Gpio_resetbits (Gpioc,gpio_pin_3);
Delay_us (100000);
aa--;
}
Clear Interrupt Flag
Exti_clearitpendingbit (EXTI_LINE9);
To extinguish the lamp's state
Gpio_setbits (Gpioc,gpio_pin_3);
}
}
3, of course, the implementation of the delay function is the system tick timer, the function is implemented as follows:
/*******************************************************************************
* Function Name: Delay_us
* Function function : delay function, delay US
* Input: I
* Output: None
*******************************************************************************/
void Delay_us (U32 i)
{
U32 temp;
systick->load=9*i; //Set reload value at 72MHZ
systick->ctrl=0x01; //Enable, minus to zero is no action, using an external clock source
systick->val=0; //Clear 0 counter
Do
{
temp=systick->ctrl; //Read current inverted count value
}
while (TEMP&0X01) && (! ( temp& (1<<16))); //wait time arrives
systick->ctrl=0; //Off counter
systick->val=0; //Empty counter
}
4, the above is completed after we can write the main function, the main function is very simple, as long as the external interrupt initialization, and then you can empty loop waiting for the interrupt. Of course, in normal projects, the main program generally does not empty loop. The main function is as follows;
int main () {
Exit_configuration ();
while (1)
{
;
}
}
When the program is finished we download to the board to test, press the button Key2, found that the light is not as we imagined the flicker, why? Look back at the program:
Exti_initstructure.exti_trigger = exti_trigger_rising; The meaning of this sentence is explained in the official library function document:
This means that you can set whether the interrupt will be interrupted as a rising or falling edge or rising or falling edge. Look back at our hardware circuit:
PB9 is grounded by a key, that is, when the key is pressed down, the input level of the PB9 is low, and the original Gpio in our program is the following statement:
Gpio_initstructure.gpio_mode = gpio_mode_in_floating;
Gpio mode configuration is the float input, when no signal input is equivalent to low level, and we press the button again, is still low, so there is no rise or fall edge, so we need to modify the circuit, how to modify it, Connect a large resistor to VCC on the PB9, so that when the key is not pressed, the PB9 input is high, and when the key is pressed down, the PB9 input is low, which is equivalent to triggering an external interrupt. The resistor we added is the pull-up resistor, which is explained in the use of resistors before my electronic components.
You can see through the above operation that when you press the button, the light flashes up as you wish. This is the external interrupt usage process for STM32.
Summarize:
To use STM32 external interrupts, the following steps are required:
1. Use the Rcc_apb2periphclockcmd () function to configure the clock
2. Use the Gpio_extilineconfig () function to connect the interrupt-generated pins
3. Use the Exti_init () function to configure external interrupts
4. Use Nvic_init () to configure interrupt priority, etc.
5. Write Interrupt Service function Exti9_5_irqhandler ()
One might wonder, what does the 9_5 in the name of the interrupt service function mean?
The PXN pins share the external interrupt line extin and the external interrupt vector extin_irqn and interrupt service entry Extin_irqhandler, where [9...5] share exti9_5_irqn and Exti9_5_irqhandler, [ 15...10] Share exti15_10_irqn and exti15_10_irqhandler, so whether we use PA9 or PB9, we use Exti9_5_irqhandler as a function.
From the picture above, we can see what it means.
And where does exti9_5_irqn use it? Everybody go back to see the program for configuring Nvic:
Nvic_initstructure.nvic_irqchannel = EXTI9_5_IRQN;
If you find it useful, please follow the public number:
stm32f103 External Interrupt Programming