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