| 
            
            
             
              【示例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; }              
                       |