STM32F103 -- Introduction to EXIT external interrupt

preface

This section will summarize STM32 (V)

Each IO of STM32 can be used as an interrupt input port for external interrupts, which is also the strength of STM32. The interrupt controller of STM32F103 supports 19 external interrupt / event requests. Each interrupt has a status

Bit, each interrupt / event has independent trigger and mask settings

--------------------

catalogue

1. Description of external interrupt

2. Introduction to exti interrupt

3. Take the rotary encoder as the course to introduce the code

--------------------

1, Introduction to external interrupt

(1) Interrupt system

Interrupt: during the operation of the main program, a specific interrupt trigger condition occurs, causing the CPU to suspend the currently running program and process the interrupt program. After completion, it returns to the original suspended position to continue working

Interrupt priority: when multiple interrupts start, the CPU will respond to more urgent interrupts according to the severity of things

Interrupt nesting: when an interrupt is running normally and a higher-level interrupt comes, it will first do the new high-level interrupt and then return in sequence
--------

(2) Interrupt of STM32

1. 68 maskable interrupt channels, including EXTI,TIM,ADC,USART,SPI,IIC,RTC and other peripherals

2. Use NVIC to uniformly manage interrupts. Each interrupt has 16 programmable priority levels, which can be grouped

(if we want to use interrupts, we must configure NVIC, which will be explained later)

--------

2, Introduction to EXTI external interrupt

1. EXTI can monitor the level signal of the specified GPIO port. When the level of the GPIO port changes, EXTI will immediately send an interrupt} application to the NVIC, and let the CPU execute the interrupt program after the decision of the NVIC

2. Trigger mode: rising edge (low to high), falling edge (high to low), bilateral edge (the first two are OK), software start (start by writing code, which has nothing to do with GPIO)

4. GPIO: all GPIO ports are supported, but the same Pin cannot trigger an interrupt

5. Number of channels: 16 pins (plus PVD output, RTC alarm clock, USB wake-up, Ethernet wake-up)

6. Trigger response mode: interrupt response, event response

Let's use the following photo to help us understand its basic structure

It should be noted that the same pin can only be used once, that is, only one port of PA0 and PB0 is interrupted
--------

(2) Brief introduction to AFIO

AFIO port mainly completes two tasks: multiplexing function, pin remapping and interrupt pin selection

(we also refer to the figure above)

--------

3, Take the rotary encoder as the course to introduce the code

1. What is rotary encoder?

Rotary encoder: a tool that can be used to measure the position in the speed direction. When it rotates, its output terminal can output the waveform corresponding to the speed direction

And it is through these waves that we program

2. Waveform of rotary encoder

Knowing the waveform of rotary encoder is the key to our programming idea

 

3. Configuration of rotary encoder

The rotary encoder module has five pins, GND (-), VCC (+), SW, DT and CLK. VCC and GND are used to connect power and ground. According to the abbreviation, SW should be Switch, CLK is Clock and DT is Data

4. Programming ideas

Here, we will use the single thread method, that is, while reading the high and low levels of one wave with an interrupt, we will read the state of another wave level, so as to calculate the direction and times of rotation

Of course, like normal mechanical buttons, we all have to shake

------------------

Programming part

As always, let's give our overall programming idea first

1 - initialize IO port as input.
2 -- turn on the multiplexing clock of the IO port and set the mapping relationship between the IO port and the interrupt line.
3 - initialize online interrupt, set trigger conditions, etc.
4 - configure interrupt packet (NVIC) and enable interrupt.
5 -- write interrupt service function
--------

First set our rotary encoder function - void Encoder_Init(void)

---------

1. Clock enable. The clocks of EXTI and NVIC are always on, so we don't need to turn them on again

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

-------

2.GPIO initialization

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//Configured as pull-up mode
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

Note here that we said earlier that our rotary encoder has five pins, but the middle key pin is not used here

------

3. Configure AFIO

 // GPIO_PinRemaConfig() can be used for pin remapping
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); //Configure the data selector of AFIO to select the pin we want and specify the external interrupt line

That is, we select PB0 as the interrupt port, PB0 as the interrupt source, and set our interrupt line

--------—

4. Configure EXIT

	EXTI_InitTypeDef EXTI_InitStructure;//Structure definition
	EXTI_InitStructure.EXTI_Line = EXTI_Line0 ;//We need to configure the interrupt line. We use line0 where PB0 is located
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//Open interrupt
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//Interrupt mode
	EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Rising_Falling ;//Set trigger mode
	EXTI_Init(&EXTI_InitStructure);//By calling this parameter, you can

Our interrupt trigger mode is selected according to our use. Here, we select the rising / falling edge trigger (in fact, both rising and falling can be selected)

---------

5. Configure NVIC

(write in front)

1. NVIC is a nested vector interrupt controller, which controls the functions related to the interrupt of the whole chip

2. NVIC is closely related to the kernel and is a peripheral in the kernel

We divide it into preemption and response. Preemption is greater than response. We give priority to the size of preemption (starting from 0, the smaller the first). When preemption is the same, we look at the response again. The comparison method is the same. High priority preemption can interrupt low priority preemption, but when preemption is the same, high priority response cannot interrupt low priority response

(1) Interrupt packet

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

(2) Initial configuration

	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //Select the triggered channel
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // Enable
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//Preemption Priority 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//Response priority
	NVIC_Init(&NVIC_InitStructure);

-----------

6. Configuration of interrupt function

To read the value of the encoder, we need to return it, so we set two values here, one for recording and the other for returning

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = Encoder_Count;
	Encoder_Count = 0;
	return Temp;
}

Next, we enter our interrupt function

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)//Judge an interrupt flag bit. If the interrupt is set to 1, the interrupt is triggered (the trigger mode is selected above), and enter the following if statement
	{	
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 1)//First judge the level of one of the waves
		{
			Delay_ms(3);//Remove jitter
			if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)//Then judge the level state of the second wave
			{
				Encoder_Count --;
			}else{
				Encoder_Count ++;
			}
		
	}

-----------------

After writing the interrupt function, it becomes very simple. Next, we just need to display the numbers we rotate on the OLED
 

int16_t Num;

int main(void)
{
	OLED_Init();
	Encoder_Init();
	OLED_ShowString(1, 1, "Num:");
	
	while (1)
	{
		Num += Encoder_Get();
		OLED_ShowSignedNum(1, 5, Num, 3);
	}
}

--------------------
 

Keywords: Single-Chip Microcomputer stm32 ARM

Added by Fearpig on Mon, 17 Jan 2022 08:33:53 +0200