| 
            
            
             
              #include <stm32f10x.h>
  #define _BV(n) (1 << (n))
  uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; uint8_t data = 0; uint8_t flag = 0;
  void delay(void) {     uint32_t i;     for (i = 0; i < 20000; i++); }
  void SerIn(uint8_t data) {     uint8_t i;     for (i = 0; i < 8; i++)     {         GPIOC->BRR = _BV(15);         if (data & 0x80)             GPIOA->BSRR = _BV(0); // 之前的PC13信号线转移到了PA0上,因为使用了上面接的LED         else             GPIOA->BRR = _BV(0);         GPIOC->BSRR = _BV(15);         data <<= 1;     } }
  void ParOut(void) {     GPIOC->BRR = _BV(14);     GPIOC->BSRR = _BV(14); }
  int main(void) {     RCC->APB2ENR = _BV(2) | _BV(4) | _BV(11); // 开启PA、PC和TIM1时钟     GPIOA->CRH = 0x00000008; // PA8设为输入     GPIOA->CRL = 0x00000003;     GPIOA->BSRR = _BV(8); // PA8为带上拉的输入     GPIOC->CRH = 0x33300000; // PC13~15设为输出     GPIOC->BSRR = _BV(13); // 熄灭LED指示灯
      TIM1->ARR = 25500; // 数码管只显示前三位变得慢的数值     TIM1->PSC = 65535;     TIM1->DIER = 0x03; // UIE=1, CC1IE=1     NVIC->ISER[0] = _BV(25) | _BV(27);          // 配置输入比较     //TIM1->CCMR1 = 0xf1; // CC1S=01, IC1F=1111     TIM1->CCMR1 = 0x01; // CC1S=01, 只有不进行按键消抖才有可能出现overcapture     TIM1->CCER = 0x03; // CC1P=1, CC1E=1          // 刷新寄存器     TIM1->CR1 = 0x54; // URS=1     TIM1->EGR = 0x01; // UG=1          // 开始计数     TIM1->CR1 = 0x351; // CKD=10, CEN=1          while (1)     {         // 显示计数器的高三位的值         SerIn(seg8[TIM1->CNT / 10000]);         SerIn(_BV(2));         ParOut();         delay();                  SerIn(seg8[TIM1->CNT % 10000 / 1000]);         SerIn(_BV(1));         ParOut();         delay();                  SerIn(seg8[TIM1->CNT % 1000 / 100]);         SerIn(_BV(0));         ParOut();         delay();                  // 向下计数时显示负号         if (TIM1->CR1 & _BV(4))         {             SerIn(0xbf);             SerIn(_BV(3));             ParOut();         }         delay();                  // 显示捕获的输入         SerIn(seg8[data / 100]);         SerIn(_BV(6));         ParOut();         delay();                  SerIn(seg8[data % 100 / 10]);         SerIn(_BV(5));         ParOut();         delay();                  SerIn(seg8[data % 10]);         SerIn(_BV(4));         ParOut();         delay();                  // 显示是否有overcapture标志         if (flag)         {             SerIn(0xbf);             SerIn(_BV(7));             ParOut();         }         delay();     } }
  // 定时器溢出中断函数 void TIM1_UP_IRQHandler(void) {     TIM1->SR &= ~_BV(0); // Status register (UIF: Update interrupt flag = 0)     GPIOC->ODR ^= _BV(13); // 定时器溢出中断触发后反转LED指示灯 }
  // 输入捕获中断函数 void TIM1_CC_IRQHandler(void) {     data = TIM1->CCR1 / 100; // 读计数器的值, 同时清除CC1IF     if (TIM1->SR & _BV(9))     {         flag = 1;         TIM1->SR &= ~_BV(9); // CC1OF=0     }     else         flag = 0; }              
                       |