In this section, we will introduce how to use the external input interrupt of STM32. Through the study of Sections 1 and 2, we have mastered the most basic operations of STM32 IO ports. In this section, we will introduce what settings STM32 needs to make as an external interrupt input port. This section is divided into the following parts:
3.4.1 Introduction to STM32 external interrupts
3.4.2 Hardware Design
3.4.3 Software Design
3.4.4 Download and test
3.4.1 Introduction to STM32 external interrupts
The IO ports of STM32 are introduced in detail in the first section of this chapter, and the external interrupts are also explained in detail in Chapter 2. Here we will introduce how to combine the two to realize external interrupt input.
Each IO port of STM32 can be used as an interrupt input, which is very useful. To use an IO port as an external interrupt input, there are several steps:
1) Initialize the IO port as input.
In this step, you set the state of the IO port you want to use as the external interrupt input. You can set it to pull-up/pull-down input or floating input, but when floating, you must use an external pull-up or pull-down resistor. Otherwise, the interrupt may be triggered continuously. In places with large interference, even if you use pull-up/pull-down, it is recommended to use an external pull-up/pull-down resistor, which can prevent the influence of external interference to a certain extent.
2) Enable the IO port multiplexing clock and set the mapping relationship between the IO port and the interrupt line.
The correspondence between the STM32 IO port and the interrupt line needs to configure the external interrupt configuration register EXTICR, so we need to first turn on the multiplexed clock, and then configure the correspondence between the IO port and the interrupt line. Only then can the external interrupt be connected to the interrupt line.
3) Enable the online interrupt/event corresponding to the IO port and set the trigger condition.
In this step, we need to configure the conditions for interrupt generation. STM32 can be configured as rising edge trigger, falling edge trigger, or any level change trigger, but it cannot be configured as high level trigger or low level trigger. Configure according to your actual situation. At the same time, you need to enable the interrupt on the interrupt line. It should be noted that if you use an external interrupt and set the EMR bit of the interrupt, the software simulation will not be able to jump to the interrupt, but the hardware can. Without setting EMR, the software simulation can enter the interrupt service function, and the hardware can also do so. It is recommended not to configure the EMR bit.
4) Configure the interrupt group (NVIC) and enable interrupts.
In this step, we configure the interrupt grouping and enable it. For STM32 interrupts, only when the NVIC settings are configured and enabled can they be executed, otherwise they will not be executed into the interrupt service function. For a detailed introduction to NVIC, please refer to the previous chapter.
5) Write the interrupt service function.
This is the last step of interrupt setting. The interrupt service function is essential. If the interrupt is enabled in the code but the interrupt service function is not written, it may cause a hardware error, which may cause the program to crash! So after enabling an interrupt, you must remember to write a service function for the interrupt. Write the operation you want to perform after the interrupt in the interrupt service function.
Through the settings of the above steps, we can use external interrupts normally.
In this section, we will implement functions similar to those in the second section, but here we use interrupts to detect key presses, and use the WK_UP key to flip DS0 and DS1 at the same time, press KEY0 to flip DS0, and press KEY1 to flip DS1.
The hardware circuit here is exactly the same as in Section 2, so I will not introduce it in detail.
We still add software design to the previous project. First, create a new folder EXTI in the HARDWARE folder. Then open the project in the USER folder, create a new exti.c file and exti.h header file, save them in the EXTI folder, and add the EXTI folder to the header file include path (that is, set the compiler include path, which has been introduced in Chapter 2. The following is similar).
We enter the following code in exit.c:
#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
//Mini STM32 development board
//External interrupt driver code
//Atom on point @ALIENTEK
//2010/5/30
//External interrupt 0 service routine
void EXTI0_IRQHandler(void)
{
delay_ms(10); //debounce
if(KEY2==1) //Key 2
{
LED0=!LED0;
LED1=!LED1;
}
EXTI->PR=1<<0; //Clear the interrupt flag on LINE0
}
//External interrupt 15~10 service program
void EXTI15_10_IRQHandler(void)
{
delay_ms(10); //debounce
if(KEY0==0) //Key 0
{
LED0=!LED0;
}else if(KEY1==0)//Key 1
{
LED1=!LED1;
}
EXTI->PR=1<<13; //Clear the interrupt flag on LINE13
EXTI->PR=1<<15; //Clear the interrupt flag on LINE15
}
//External interrupt initialization routine
//Initialize PA0, PA13, PA15 as interrupt input.
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<2; //Enable PORTA clock
RCC->APB2ENR|=1<<0; //Turn on the auxiliary clock
AFIO->MAPR&=0XF8FFFFFF; //Clear [26:24] of MAPR
AFIO->MAPR|=0X04000000; //Disable JTAG
GPIOA->CRL&=0XFFFFFFF0; //PA0 is set as input
GPIOA->CRL|=0X00000008;
GPIOA->CRH&=0X0F0FFFFF; //PA13, 15 are set as input
GPIOA->CRH|=0X80800000;
GPIOA->ODR|=1<<13; //PA13 is pulled up, PA0 is pulled down by default
GPIOA->ODR|=1<<15; //PA15 pull-up
Ex_NVIC_Config(GPIO_A, 0, RTIR); //Rising edge trigger
Ex_NVIC_Config(GPIO_A, 13, FTIR); //Falling edge trigger
Ex_NVIC_Config(GPIO_A, 15, FTIR); //Falling edge trigger
MY_NVIC_Init(2, 2, EXTI0_IRQChannel, 2); //Preempt 2, subpriority 2, group 2
MY_NVIC_Init(2, 2, EXTI15_10_IRQChannel, 2); //Preempt 2, subpriority 1, group 2
}
The exit.c file contains 3 functions in total. One is the external interrupt initialization function void EXTIX_Init(void), and the other two are interrupt service functions. void EXTI0_IRQHandler(void) is the service function of external interrupt 0, responsible for the interrupt detection of the WK_UP key. void EXTI15_10_IRQHandler(void) is the interrupt service function of external interrupts 10~15. Here we use interrupts 13 and 15, and these two interrupts share an interrupt service function. Let's introduce these functions separately.
First is the external interrupt initialization function void EXTIX_Init(void), which strictly follows the previous steps to initialize the external interrupt. There is an operation to turn off JTAG, which is the same as the function in the second section. Two functions Ex_NVIC_Config and MY_NVIC_Init are called here. Their functions have been introduced in Chapter 2. If you don’t understand, you can turn to the front and take a look. I won’t say more here. It should be noted that because our WK_UP button is high-level valid, KEY0 and KEY1 are low-level valid, so we set the WK_UP button to pull down input, and KEY0 and KEY1 to pull up input. When the interrupt is triggered, a rising edge will be detected on WK_UP, and a falling edge will be generated on KEY0 and KEY1. Here we assign all interrupts to the second group, set the preemption priority of the buttons to the same, but the sub-priority is different. The sub-priority of KEY0 and KEY1 is greater than WK_UP.
Next, we will introduce two interrupt service functions. First, let's look at the interrupt service function of WK_UP void EXTI0_IRQHandler (void). The function code is relatively simple. It first delays 10ms to eliminate jitter, and then detects whether KEY2 (WK_UP) is still at a high level. If it is, it executes this operation (flips DS0 and DS1). If not, it skips directly. At the end, there is a sentence EXTI->PR=1<<0; This sentence clears the interrupt request that has occurred. Let's look at the interrupt service function of KEY0 and KEY1 void EXTI15_10_IRQHandler (void). This function is a little different from the interrupt service function of KEY2. From the function name, we can see that it serves interrupt lines 10~15, that is, interrupts on multiple interrupt lines share an interrupt service function. In this function, we first distinguish the signals entering the interrupt (by judging the level on the interrupt input IO port), and then process them separately. Finally, the interrupt request on the interrupt line is cleared by writing 1 to the corresponding bit of EXTI->PR.
We save the exti.c file and add it to the HARDWARE group. In the exti.h file, we enter the following code:
#ifndef __EXTI_H
#define __EXIT_H
void EXTIX_Init(void); //IO initialization
#endif
This part of the code is very simple, we won't say much here, just save it. Then we write the following content in test.c:
#include
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
//Mini STM32 development board example code 4
//External interrupt experiment
//Atom on point @ALIENTEK
//2010.5.27
int main(void)
{
Stm32_Clock_Init(9); //System clock settings
delay_init(72); //delay initialization
uart_init(72,9600); //Serial port initialization
LED_Init(); //Initialize the hardware interface connected to the LED
EXTIX_Init(); //External interrupt initialization
while(1)
{
printf("OK\n");
delay_ms(1000);
}
}
This part of the code is very simple. After initializing the interrupt, it enters an infinite loop and waits. Here, a printf function is used in the infinite loop to tell us that the system is running. I will not say more about the rest here.
After successful compilation, we can download the code to the MiniSTM32 development board to verify whether our program is correct. After downloading the code, you can press KEY0, KEY1, KEY2 to see whether DS0 and DS1 change with the key changes.
Previous article:STM32 Systick Timer
Next article:STM32 Learning 4 Reset
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- Access Denied problem occurs in Ubuntu 20 window ssh connection
- USB download cable driver installation.pdf
- MicroPython Hands-on (39) - Image Basics of Machine Vision
- Sinlinx A33 Development Board Android Development (Part 1)
- National Undergraduate Electronic Design Competition Training Series
- 2019 Electric Competition Comprehensive Evaluation Waveform Generator Help! ! Urgent! !
- Free application: Pingtou Ge CB5654 intelligent voice development board, quickly realize storytelling machine and other products
- [Hongmeng Development Board Neptune] Building the HarmonyOS development environment is the hardest part
- Switching Power Supply Interest Group Task 08
- Current control scheme of three-phase four-wire active filter based on FPGA