The CM3 core supports 256 interrupts, including 16 core interrupts and 240 external interrupts, and has a total of 256
Programmable interrupt settings for the class. But STM32 did not use all of the CM3 kernel, but only part of it.
The STM32 has 76 interrupts, including 16 core interrupts and 60 unshielded interrupts, with a 16-level programmable interrupt priority.
And what we used to do is these 60 unshielded interrupts, so we're only going to cover these 60 masked interrupts.
Within MDK, the register associated with the Nvic, MDK defines the following structure for it:
typedef struct
{
Vu32 iser[2];
U32 reserved0[30];
Vu32 icer[2];
U32 rserved1[30];
Vu32 ispr[2];
U32 reserved2[30];
Vu32 icpr[2];
U32 reserved3[30];
Vu32 iabr[2];
U32 reserved4[62];
Vu32 ipr[15];
} nvic_typedef;
The interrupts of the STM32 are executed in an orderly manner under the control of these registers. Understand these interrupt registers so that you can easily
Interrupts using the STM32. These registers are highlighted below:
The Iser[2]:iser full name is: Interrupt set-enableregisters, which is an interrupt enable register group. Above
Said the STM32 can be shielded interrupt only 60, where 2 32-bit registers, a total of 64 interrupts can be represented.
and STM32 only used the first 60 of them. ISER[0] Bit0~bit31 respectively corresponds to the interrupt 0~31. ISER[1] of the bit0~27
Corresponds to interrupt 32~59, so that a total of 60 interrupts are respectively corresponding. If you want to enable an interrupt, you must set the appropriate Iser
Bit is 1, so that the interrupt is enabled (this is only enabled, but also with interrupt grouping, masking, IO port mapping and other settings are considered
A complete interrupt setting). For each specific interrupt, please refer to Stm32f10x_nvic. H inside the 36th line.
ICER[2]: The full name is: Interrupt clear-enableregisters, is an interrupt in addition to the Register group. The Register group
In contrast to the iser, it is used to clear the enable of an interrupt. The function of its corresponding bit is the same as icer.
This is to set a special icer to clear the interrupt bit, instead of writing to Iser to clear, because Nvic
The register is write 1 valid, write 0 is invalid. Specifically why this design, please see "CM3 authoritative Guide" on page 125th,
NVIC Overview Chapter.
ISPR[2]: The full name is: Interrupt set-pending registers, is an interrupt suspend control register group. Each bit
The corresponding interrupts and Iser are the same. By placing 1, you can suspend an in-progress interrupt while performing a sibling or higher level
The interrupt. Writing 0 is not valid.
ICPR[2]: The full name is: Interrupt clear-pendingregisters, is an interrupt-mount control register group. Its making
In contrast to ISPR, the corresponding bit is the same as the Iser. By setting 1, you can suspend a pending interrupt. Write 0 is invalid.
IABR[2]: The full name is: Active bit registers, which is an interrupt activation flag bit register set. The corresponding bit represents
Interrupts, like Iser, if 1, indicates that the interrupt corresponding to the bit is being executed. This is a read-only register,
It lets you know which interrupt is currently executing. Automatically zeroed out by the hardware when the interrupt is finished.
IPR[15]: The full name is: Interrupt priority registers, which is a register group for interrupt-precedence control. This mailing
Register Group is quite important! The interrupt grouping of STM32 is closely related to this register group. The IPR Register group consists of 15 32bit
Registers, each masked interrupt occupies 8bit, so that a total of 15*4=60 can be represented by a shielded interrupt. Just and
STM32 the number of masked interrupts is equal. IPR[0] [31~24],[23~16],[15~8],[7~0] respectively corresponding to the interrupt 3~0,
And so on, a total of 60 external interrupts are corresponding. The 8bit per shielded interrupt is not used in all, but only
With a high of 4 bits. These 4 bits are divided into preemption priority and sub-priority. Preemption priority is before, and child priority is behind. And this
Each of the two priority levels is determined by the set of interrupt groupings in the SCB->AIRCR.
Here is a brief introduction to the STM32 Interrupt grouping: STM32 breaks into 5 groups, group 0~4. The grouping is set
is defined by the bit10~8 of the SCB->AIRCR register. The specific distribution relationships are shown in the following table:
With this table, we can clearly see the configuration relationship for the group 0~4, for example, if the group is set to 3, then
For all 60 interrupts, the highest 3 bits in the high four bits of the interrupt priority register for each interrupt are preemption priority, and the low 1 bits are
The response priority level. For each interrupt, you can set preemption priority to 0~7, with a response priority of 1 or 0. Preemption of the priority level
The level is higher than the response priority. The smaller the value, the higher the priority.
In conjunction with an example, assume that the set interrupt priority group is 2 and then set the preemption priority for interrupt 3 (RTC interrupt)
is 3, and the response priority is 1. The preemption priority for interrupt 6 (external interrupt 0) is 4 and the response priority is 0. Interrupt 7 (Outside
Interrupt 1) has a preemption priority of 3 and a response priority of 0. Then the order of precedence for these 3 interrupts is: Interrupt 7>
Broken 3> Interrupt 6.
Here are 2 points to note:
If the response priority and the response priority of the two interrupts are the same, then the first execution is to see which interrupt occurs first.
A high-priority preemption priority is the ability to interrupt an ongoing low preemption priority interrupt. and preemption of the same priority level
Interrupt, high priority response priority does not interrupt low-response priority interrupts. Interrupt 3 and interrupt 7 in the above example
Interrupts that interrupt 6 can be interrupted. and interrupt 7 and interrupt 3 can not interrupt each other!
With the above introduction, we are familiar with the general process of STM32 interrupt setup. Next we show you how to use functions
Implementing the above interrupt setting simplifies our later interrupt setup.
The first one introduces the NVIC grouping function My_nvic_prioritygroupconfig, which is the parameter of the function
Nvic_group is the group number you want to set, with an optional range of 0~4 and a total of 5 groups. If the argument is illegal, it can result in unpredictable results. The My_nvic_prioritygroupconfig function code is as follows:
Set Nvic grouping
Nvic_group:nvic Group 0~4 Total 5 groups
void My_nvic_prioritygroupconfig (U8 nvic_group)
{
U32 TEMP,TEMP1;
temp1= (~nvic_group) &0x07;//three-bit temp1<<=8;
temp=scb->aircr; Read the previous settings
temp&=0x0000f8ff; Empty previous groupings
temp|=0x05fa0000; Write key
TEMP|=TEMP1;
scb->aircr=temp; Set grouping
}
With the previous introduction, we know that STM32 's 5 groupings are implemented by setting SCB->AIRCR Bit[10:8] to
Now, and through 2.7.2.1 's introduction we know that SCB->AIRCR's modifications need to be written through a high 16-bit 0X05FA this
Key, you should add the key to the high 16 bits of the content to be written before setting the AIRCR to protect
The AIRCR can be written correctly. When modifying the AIRCR, we generally use the read-and-write steps to achieve
Change the other settings of the AIRCR original. The above is the My_nvic_prioritygroupconfig function to set the interrupt priority sub-
Group of Ideas.
The second function is the NVIC set function My_nvic_init, which has 4 parameters, respectively:
Nvic_preemptionpriority, Nvic_subpriority, Nvic_channel, Nvic_group. First parameter
Nvic_preemptionpriority is the interrupt preemption priority value, the second parameter nvic_subpriority the interrupt sub-priority
Series values, the values of the first two parameters must be within the specified range, or an unexpected error may occur. A third parameter
Nvic_channel is the interrupt number (the range is 0~59), the last parameter nvic_group the interrupt grouping setting (fan
The 0~4). The function code is as follows:
Set Nvic
Nvic_preemptionpriority: preemption Priority
Nvic_subpriority: Response Priority
Nvic_channel: Interrupt Number
Nvic_group: Interrupt Grouping 0~4
Note that the priority cannot exceed the range of the set! Otherwise there will be unexpected errors.
Group Division:
Group 0:0 Bit preemption priority, 4-bit response priority
Group 1:1-bit preemption priority, 3-bit response priority
Group 2:2-bit preemption priority, 2-bit response priority
Group 3:3-bit preemption priority, 1-bit response priority
Group 4:4-bit preemption priority, 0-bit response priority
The principle of nvic_subpriority and nvic_preemptionpriority is that the smaller the number, the higher the priority
void My_nvic_init (U8 nvic_preemptionpriority,u8 Nvic_subpriority,u8nvic_channel,
U8 Nvic_group)
{
U32 temp;
U8 IPRADDR=NVIC_CHANNEL/4; Each group can only save 4, get the group address
U8 iproffset=nvic_channel%4;//offset within a group
iproffset=iproffset*8+4; Get the exact position of the offset
My_nvic_prioritygroupconfig (Nvic_group);//Set grouping
temp=nvic_preemptionpriority<< (4-nvic_group);
temp|=nvic_subpriority& (0x0f>>nvic_group);
temp&=0xf;//take the low four-bit if (nvic_channel<32) nvic->iser[0]|=1<<nvic_channel;//enable interrupt bit (to clear,
The opposite operation is OK)
elsenvic->iser[1]|=1<< (NVIC_CHANNEL-32);
nvic->ipr[ipraddr]|=temp<<iproffset;//setting response priority and steals priority
}
With the previous introduction, we know that the priority setting for each masked interrupt is in the IPR register group, each
The interrupt accounts for 8 bits, but only 4 of them are used, and the code above is to set each interrupt to
Should be of a high 4-bit numeric value. In this function, of course, the function of My_nvic_prioritygroupconfig is also referenced to
Sets the grouping. In fact, this grouping function in each system as long as set once enough, set multiple times, is the last
That is the time to prevail. But as long as the set number is the same, it's okay. Otherwise, the previously set interrupts will be
The change priority will change, this point in the use of special attention! A system code inside, all interrupts are divided
All groups must be unified!! , the above code is turned on by default for the interrupt number to be configured. That is, the value in Iser is set to 1
The
Through the above two functions, it realizes the management and configuration of NVIC. However, the settings for external interrupts also require a configuration phase
Register is not allowed. The configuration and use of external interrupts is described below.
The STM32 Exti Controller supports 19 external interrupt/event requests. Each interrupt has a status bit, each interrupt/event
Have separate trigger and mask settings. The 19 external interrupts for the STM32 are:
Line 0~15: input interrupt corresponding to external IO port.
Line 16: Connect to the PVD output.
Line 17: Connect to the RTC alarm event.
Line 18: Connect to the USB wake-up event.
For external interrupt Exti control MDK defines the following structure:
typedef struct
{
Vu32 IMR;
Vu32 EMR;
Vu32 RTSR;
Vu32 FTSR;
Vu32 Swier;
Vu32 PR;
} exti_typedef;
With the settings of these registers, the external interrupts can be set in detail. We will highlight the following
The function of the register.
IMR: Interrupt mask register. This is a 32 register. But only the first 19 bits are valid. When bit x is set to 1 o'clock,
The interrupt on this line is turned on, otherwise the interrupt on the line is turned off.
EMR: Event masking Register, same as IMR, except that the register is for event masking and opening.
RTSR: The rising edge triggers the selection register. The register is the same as IMR and is a 32 register, with only the first 19
bit is valid. Bit x corresponds to the rising edge of the line x and, if set to 1, allows the rising edge to trigger an interrupt/event. Otherwise
Not allowed.
FTSR: Drop Edge Trigger Select register. Same PTSR, but this register is set to the falling edge. Falling Edge and Upper
The rising edge can be set at the same time, so it becomes an arbitrary level trigger. Swier: Software interrupt event register. By writing 1 to the bit X of the register, the IMR and EMR are not set
The corresponding bit in the PR is set to hang. If IMR and EMR are set, an interrupt is generated. Set of Swier
Will be cleared after the corresponding bit in the PR is cleared.
PR: Suspend register. When a selected edge event occurs on an external interrupt line, the corresponding bit of the register is set to 1.
0, indicating that no triggering request has occurred on the corresponding line. This bit can be cleared by writing 1 to the corresponding bit of the register. In the interrupt service
In the service function, it is often written to the corresponding bit of the register to clear the interrupt request.
The above is a description of the interrupt related registers, in more detail, please refer to the "STM32 Reference manual" on page 95th,
Section 8.3 Exti register describes this chapter.
With the above configuration, external interrupts can be set up normally, but external IO port interrupts require a register
External interrupt configuration Register EXTICR in IO multiplexing. This is because STM32 any IO port can be
To be configured as an interrupt input port, but the number of IO ports is much larger than the number of broken wires (16). So STM32 designed it,
Gpioa~gpiog [15:0] corresponds to the interrupt line 15~0 respectively. This corresponds to a maximum of 7 IO ports for each of the line 0
As an example: it corresponds to gpioa.0, piob.0, gpioc.0, gpiod.0, gpioe.0, gpiof.0, gpiog.0. and
The disconnection can only be connected to 1 IO ports at a time, which requires EXTICR to determine which gpio the corresponding interrupt line is configured to
It's up.
EXTICR is defined in the structure of the Afio, as follows:
typedef struct
{
Vu32 EVCR;
Vu32 MAPR;
Vu32 Exticr[4];
} afio_typedef;
EXTICR Register Group, a total of 4, because the compiler register groups are numbered starting from 0, so
exticr[0]~ exticr[3], corresponds to exticr1~ EXTICR4 in the STM32 reference manual. Each EXTICR
Only its low 16 bits are used. EXTICR[0] is assigned as follows:
For example, if I want to set the Gpiob.1 map to 1, then only set exticr[0] bit[7:4] is 0001. Default
is 0000, which maps to GPIOA. As can be seen from Figure 5.7, exticr[0] just the Gpio 0~3 port, the corresponding
Other ports are managed by exticr[1~3]. Please refer to page 126th to 128th of the STM32 reference manual for details.
By analyzing the above we can complete the configuration of the external interrupts. The function is Ex_nvic_config, which has 3 parameters: Gpiox is Gpioa~g (0~6) and is defined in Sys.h. Represents the IO port to be configured. Bitx
Represents the first of the IO ports. TRIM for Trigger mode, low 2 bits valid (0x01 for descent trigger; 0X02 representative
The rising edge is triggered; 0x03 represents an arbitrary level trigger). The code is as follows:
External interrupt configuration function
Only for gpioa~g, not including PVD,RTC and USB wake-up these three
Parameters: Gpiox:0~6, representing Gpioa~g; BITX: The need to enable the bit; TRIM: Trigger mode, 1, down-rising edge, 2, Upper
3, Arbitrary level trigger
The function can only configure 1 IO ports at a time, multiple IO ports, need to be called multiple times
The function automatically turns on the corresponding interrupt, as well as the shielding line
void Ex_nvic_config (U8 gpiox,u8 bitx,u8 TRIM)
{
U8 extaddr;
U8 Extoffset;
extaddr=bitx/4;//gets the number of the interrupt register group
Extoffset= (bitx%4);
rcc->apb2enr|=0x01;//Enable IO multiplexing clock
Afio->exticr[extaddr]|=gpiox<<extoffset;//exti. BITX Mapping to GPIOX.BITX
Automatically set
exti->imr|=1<<bitx;//opening the interrupt on line BITX
exti->emr|=1<<bitx;//do not block events on the LINEBITX
if (trim&0x01) Exti->ftsr|=1<<bitx;//linebitx on event falling edge trigger
if (trim&0x02) Exti->rtsr|=1<<bitx;//linebitx on an event on the trigger
}
Ex_nvic_config was written entirely in accordance with our previous analysis, first based on the Gpiox bit to be interrupted to send
The number of the Register group, which is the number of the EXTICR, which bit in the EXTICR configuration should be configured to Gpiox.
Then enable the interrupt and event of the bit, and finally configure the trigger mode. This completes the configuration of the external interrupt. From the Code
You can see that the function by default is to turn on interrupts and events. The second thing to note is that the function can only be configured one at a time
IO port, if you have multiple IO ports to configure, you can call this function multiple times.
At this point, our interruption management of STM32 is over. And of course there are interrupt response functions, and we don't have
Introduction, which is described in the following example.
STM32 Interrupt Management function