Skip to content

STM32F103C8T6 (4. Pertrauktys (angl. interrupts))

blahlt edited this page Jan 19, 2017 · 8 revisions

STM32F103C8T6 turi 16 (realiai 10(?)) standartinių Cortex-M3 pertraukties linijų (angl. interrupt lines) vadinamų sisteminėmis išimtimis (angl. system exceptions) ir 43(?) maskuojamas1 (angl. maskable) išorines pertrauktis (angl. external interrupts).
1 Maskuojama (angl. maskable) pertrauktis vadinama ta pertrauktis, kurią galima išjungti CPU pagalba. Nemaskuojama (angl. nonmaskable) pertrauktis yra ta, kurios negalima išjungti/ignoruoti.

Daugumai pertraukčių galima nustatyti prioriteto (angl. priority) lygį (viso 16 skirtingų prioritetų). Kuo mažesnis prioriteto numeris tuo aukštesnį prioritetą pertrauktis turi. Prioriteto numerį taip pat galima padalinti į dvi grupes - prioriteto ir subprioriteto. Jei yra įjungtas padalijimas ir dvi pertrauktys turi tą patį prioriteto numerį tai pirmiausia bus vykdomas tos pertraukties kodas, kurios subprioritetas turės aukštesnį prioritetą (mažesnį numerį).

SysTick pertrauktis

Sukuriam projektą ir į main.cpp įtraukiam bibliotekas:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "cortexm/ExceptionHandlers.h"

apsirašom direktyvas:

#define LEDPORTCLK			RCC_APB2Periph_GPIOC
#define LEDPORT				GPIOC
#define LEDB 				GPIO_Pin_13

#define BUTTONPINSOURCE		GPIO_PinSource0
#define BUTTONPORTSOURCE	GPIO_PortSourceGPIOA

į main funkciją įrašom sisteminio laikrodžio konfigūraciją (maksimali reikšmė - 16777216):

int
main(int argc, char* argv[])
{
	// Šviesos diodo konfigūracija
	RCC_APB2PeriphClockCmd(LEDPORTCLK,  ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = LEDB;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LEDPORT, &GPIO_InitStructure);
	
	// Pertraukties konfigūracija
	SysTick_Config(16777216);

	while (1)
	{
	}
}

Project Explorer einam į system/src/cortexm/exception_handlers.c ir užkomentuojam šias eilutes:

//void __attribute__ ((section(".after_vectors"),weak))
//SysTick_Handler (void)
//{
//  // DO NOT loop, just return.
//  // Useful in case someone (like STM HAL) inadvertently enables SysTick.
//  ;
//}

main.cpp faile pridedam funkciją pertraukties apdorojimui:

void
SysTick_Handler(void)
{
	if(GPIO_ReadOutputDataBit(LEDPORT, LEDB))
	{
		GPIO_ResetBits(LEDPORT, LEDB);
	}
	else
	{
		GPIO_SetBits(LEDPORT, LEDB);
	}
}

EXTI0 pertrauktis

Sukuriam projektą. Project->Properties einam į C/C++ General->Paths and Symbols, tada į Source Location skiltį (reikia nustatyti ir Debug ir Release konfigūracijoms atskirai). Pažymim /{projekto pavadinimas}/system ir spaudžiam Edit Filter.... Pašalinam src/stm32f1-stdperiph/stm32f10x_exti.c įrašą ir spaudžiam OK, OK. Po šio veiksmo einam į Project Explorer ir išskleidžiam system/src/stm32f1-stdperiph ir turi matytis stm32f10x_exti.c failas nepapilkintas ir neperbraukta ikona. Į main.cpp įtraukiam bibliotekas:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "cortexm/ExceptionHandlers.h"

apsirašom direktyvas:

#define LEDPORTCLK			RCC_APB2Periph_GPIOC
#define LEDPORT				GPIOC
#define LEDB 				GPIO_Pin_13

#define BUTTONPORTSOURCE	GPIO_PortSourceGPIOA
#define BUTTONPINSOURCE		GPIO_PinSource0

į main funkciją įrašom konfigūracijas:

int
main(int argc, char* argv[])
{
	RCC_APB2PeriphClockCmd(LEDPORTCLK,  ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = LEDB;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LEDPORT, &GPIO_InitStructure);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

	GPIO_EXTILineConfig(BUTTONPORTSOURCE, BUTTONPINSOURCE);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, DISABLE);

	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	while (1)
	{
	}
}

į system/include/cortexm/ExceptionHandlers.h įrašom

extern void
EXTI0_IRQHandler (void);

main.cpp pridam pertraukties funkciją:

void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) != RESET)
	{
		if(GPIO_ReadOutputDataBit(LEDPORT, LEDB))
		{
			GPIO_ResetBits(LEDPORT, LEDB);
		}
		else
		{
			GPIO_SetBits(LEDPORT, LEDB);
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}

Schema: A0 per 10k rezistorių prijungiam prie 3.3V, A0 prijungiam prie mygtuko (1) išvado, (2) mygtuko išvadą prijungiam prie GND

Pavyzdys (pertrauktis PB0, šviesos diodas PC13)

Svarbu: RCC_APB2Periph_AFIO privalom įjungti, nes kviečiam GPIO_EXTILineConfig() funkciją, kuri nustato AFIO->EXTICR registro reikšmes.

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "cortexm/ExceptionHandlers.h"

#define BUTTON_GPIO         GPIOB
#define BUTTON_CLK          RCC_APB2Periph_GPIOB
#define BUTTON_PIN          GPIO_Pin_0
#define BUTTON_PORT_SOURCE  GPIO_PortSourceGPIOB
#define BUTTON_PIN_SOURCE   GPIO_PinSource0
#define BUTTON_EXTI_LINE    EXTI_Line0
#define BUTTON_NVIC_CHANNEL EXTI0_IRQn

#define LED_GPIO            GPIOC
#define LED_CLK             RCC_APB2Periph_GPIOC
#define LED_PIN             GPIO_Pin_13

void Init_Led(void);
void Init_Interrupt(void);

#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, char* argv[])
{
    Init_Led();
    Init_Interrupt();

    while (1)
    {
    }
}

void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(BUTTON_EXTI_LINE) != RESET)
    {
        if (GPIO_ReadInputDataBit(LED_GPIO, LED_PIN))
        {
            GPIO_ResetBits(LED_GPIO, LED_PIN);
        }
        else
        {
            GPIO_SetBits(LED_GPIO, LED_PIN);
        }
    }
    EXTI_ClearITPendingBit(BUTTON_EXTI_LINE);
}

void Init_Interrupt(void)
{
    RCC_APB2PeriphClockCmd(BUTTON_CLK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = BUTTON_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(BUTTON_GPIO, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    GPIO_EXTILineConfig(BUTTON_PORT_SOURCE, BUTTON_PIN_SOURCE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, DISABLE);

    EXTI_ClearITPendingBit(BUTTON_EXTI_LINE);

    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = BUTTON_EXTI_LINE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = BUTTON_NVIC_CHANNEL;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void Init_Led(void)
{
    RCC_APB2PeriphClockCmd(LED_CLK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = LED_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(LED_GPIO, &GPIO_InitStructure);
}

STM32F103C8T6 pertrauktys

Position Priority Type of priority Acronym Description Address
-16 - - _Stack_ _Initial main stack pointer_ 0x0000_0000
-15 -3 (highest) fixed Reset Reset 0x0000_0004
-14 -2 fixed NMI Non maskable interrupt. The RCC Clock Security System (CSS) is linked to the NMI vector. 0x0000_0008
-13 -1 fixed HardFault All class of fault 0x0000_000C
-12 0 settable MemManage Memory management 0x0000_0010
-11 1 settable BusFault Prefetch fault, memory access fault 0x0000_0014
-10 2 settable UsageFault Undefined instruction or illegal state 0x0000_0018
-9 - - - Reserved 0x0000_001C
-8 - - - Reserved 0x0000_0020
-7 - - - Reserved 0x0000_0024
-6 - - - Reserved 0x0000_0028
-5 3 settable SVCall System service call via SWI instruction 0x0000_002C
-4 4 settable Debug Monitor Debug Monitor 0x0000_0030
-3 - - - Reserved 0x0000_0034
-2 5 settable PendSV Pendable request for system service 0x0000_0038
-1 6 settable SysTick System tick timer 0x0000_003C
0 7 settable WWDG Window watchdog interrupt 0x0000_0040
1 8 settable PVD PVD through EXTI Line detection interrupt 0x0000_0044
2 9 settable TAMPER Tamper interrupt 0x0000_0048
3 10 settable RTC RTC global interrupt 0x0000_004C
4 11 settable FLASH Flash global interrupt 0x0000_0050
5 12 settable RCC RCC global interrupt 0x0000_0054
6 13 settable EXTI0 EXTI Line0 interrupt 0x0000_0058
7 14 settable EXTI1 EXTI Line1 interrupt 0x0000_005C
8 15 settable EXTI2 EXTI Line2 interrupt 0x0000_0060
9 16 settable EXTI3 EXTI Line3 interrupt 0x0000_0064
10 17 settable EXTI4 EXTI Line4 interrupt 0x0000_0068
11 18 settable DMA1_Channel1 DMA1 Channel1 global interrupt 0x0000_006C
12 19 settable DMA1_Channel2 DMA1 Channel2 global interrupt 0x0000_0070
13 20 settable DMA1_Channel3 DMA1 Channel3 global interrupt 0x0000_0074
14 21 settable DMA1_Channel4 DMA1 Channel4 global interrupt 0x0000_0078
15 22 settable DMA1_Channel5 DMA1 Channel5 global interrupt 0x0000_007C
16 23 settable DMA1_Channel6 DMA1 Channel6 global interrupt 0x0000_0080
17 24 settable DMA1_Channel7 DMA1 Channel7 global interrupt 0x0000_0084
18 25 settable ADC1_2 ADC1 and ADC2 global interrupt 0x0000_0088
19 26 settable USB_HP_CAN_TX USB High Priority or CAN TX interrupts 0x0000_008C
20 27 settable USB_LP_CAN_RX0 USB Low Priority or CAN RX0 interrupts 0x0000_0090
21 28 settable CAN_RX1 CAN RX1 interrupt 0x0000_0094
22 29 settable CAN_SCE CAN SCE interrupt 0x0000_0098
23 30 settable EXTI9_5 EXTI Line[9:5] interrupts 0x0000_009C
24 31 settable TIM1_BRK TIM1 Break interrupt 0x0000_00A0
25 32 settable TIM1_UP TIM1 Update interrupt 0x0000_00A4
26 33 settable TIM1_TRG_COM TIM1 Trigger and Commutation interrupts 0x0000_00A8
27 34 settable TIM1_CC TIM1 Capture Compare interrupt 0x0000_00AC
28 35 settable TIM2 TIM2 global interrupt 0x0000_00B0
29 36 settable TIM3 TIM3 global interrupt 0x0000_00B4
30 37 settable TIM4 TIM4 global interrupt 0x0000_00B8
31 38 settable I2C1_EV I 2 C1 event interrupt 0x0000_00BC
32 39 settable I2C1_ER I 2 C1 error interrupt 0x0000_00C0
33 40 settable I2C2_EV I 2 C2 event interrupt 0x0000_00C4
34 41 settable I2C2_ER I 2 C2 error interrupt 0x0000_00C8
35 42 settable SPI1 SPI1 global interrupt 0x0000_00CC
36 43 settable SPI2 SPI2 global interrupt 0x0000_00D0
37 44 settable USART1 USART1 global interrupt 0x0000_00D4
38 45 settable USART2 USART2 global interrupt 0x0000_00D8
39 46 settable USART3 USART3 global interrupt 0x0000_00DC
40 47 settable EXTI15_10 EXTI Line[15:10] interrupts 0x0000_00E0
41 48 settable RTCAlarm RTC alarm through EXTI line interrupt 0x0000_00E4
42 49 settable USBWakeup USB wakeup from suspend through EXTI line interrupt 0x0000_00E8

Clone this wiki locally