【示例1:高優先級中斷屏蔽並清除低優先級中斷】 #include <stm32f10x.h>
#define _BV(n) (1 << (n))
uint16_t status = 0; uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
void delay(void) { uint16_t i; for (i = 0; i < 20000; i++); }
void ser_in(uint8_t data) { uint8_t i; for (i = 0; i < 8; i++) { GPIOB->BRR = GPIO_BRR_BR9; // SCLK=PB9 if (data & 0x80) GPIOB->BSRR = GPIO_BSRR_BS7; // DIO=PB7 else GPIOB->BRR = GPIO_BRR_BR7; data <<= 1; GPIOB->BSRR = GPIO_BSRR_BS9; } }
void par_out(void) { GPIOB->BRR = GPIO_BRR_BR8; // RCLK=PB8 GPIOB->BSRR = GPIO_BSRR_BS8; }
// 單步數碼管掃描 void seg_scan(void) { static uint8_t i = 0; static uint16_t num; __disable_irq(); // 關總中斷, 防止74HC595晶片時序錯亂導致數碼管閃爍 if (i == 0) num = TIM1->CNT / 100; if (i == 5) num = status; ser_in(seg8[num % 10]); ser_in(_BV(i)); par_out(); delay(); num /= 10; // 數碼管0~2顯示定時器1計數值的百~萬位, 數碼管5~7顯示status的個~百位 // 從低位向高位掃描 if (i == 2) i = 5; else if (i == 7) i = 0; else i++; __enable_irq(); // 開總中斷, 並立即處理剛才中斷關閉時已經置位的中斷請求 }
/* // 這個數碼管掃描函數影響中斷處理的程度要高一些 // 功能和上面那個一樣 void seg_scan(void) { uint8_t i; uint16_t num = TIM1->CNT / 100; __disable_irq(); for (i = 0; i <= 2; i++) { ser_in(seg8[num % 10]); ser_in(_BV(i)); par_out(); delay(); num /= 10; } num = status; for (i = 5; i <= 7; i++) { ser_in(seg8[num % 10]); ser_in(_BV(i)); par_out(); delay(); num /= 10; } __enable_irq(); } */
int main(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_AFIOEN; GPIOB->CRH = 0x00000033; GPIOB->CRL = 0x30000008; GPIOB->BSRR = GPIO_BSRR_BS0; AFIO->EXTICR[0] = 0x01; // Px0 = PB0 EXTI->IMR |= EXTI_IMR_MR0; // 開Px0外中斷 EXTI->FTSR |= EXTI_FTSR_TR0; // Px0下降沿觸發 //EXTI->RTSR |= EXTI_RTSR_TR0; // Px0上升沿觸發 TIM1->ARR = 12099; TIM1->PSC = 48000; TIM1->DIER |= TIM_DIER_UIE; NVIC->ISER[0] = NVIC_ISER_SETENA_6 | NVIC_ISER_SETENA_25; TIM1->CR1 |= TIM_CR1_CMS | TIM_CR1_URS; TIM1->EGR |= TIM_EGR_UG; TIM1->CR1 &= ~TIM_CR1_URS; TIM1->CR1 |= TIM_CR1_CEN; while (1) { seg_scan(); } }
// 高優先級中斷(外部中斷) void EXTI0_IRQHandler(void) { status++; while ((GPIOB->IDR & GPIO_IDR_IDR0) == 0) // 等待按鍵釋放 { seg_scan(); if (NVIC->ICPR[0] & NVIC_ICPR_CLRPEND_25) { // 高優先級中斷清除低優先級中斷 // 只要按鍵沒有鬆開, 定時器中斷就無法觸發 TIM1->SR &= ~TIM_SR_UIF; NVIC->ICPR[0] |= NVIC_ICPR_CLRPEND_25; } } EXTI->PR |= EXTI_PR_PR0; }
// 低優先級中斷(定時器溢出中斷) void TIM1_UP_IRQHandler(void) { TIM1->SR &= ~TIM_SR_UIF; status += 10; }
|