|  | 【程序】STM32定时器1的强置输出模式(Forced output mode) | 
                
          |   一派護法 十九級 | 
              #include <stm32f10x.h>
 #define _BV(n) (1 << (n))
 
 void delay(void)
 {
 uint32_t i;
 for (i = 0; i < 5000000; i++);
 }
 
 int main(void)
 {
 RCC->APB2ENR = _BV(2) | _BV(11); // 开启PA和TIM1时钟,不用开AFIO时钟
 GPIOA->CRH = 0x0000000b; // PA8设为复用50MHz推挽输出
 
 TIM1->BDTR = _BV(15); // MOE=1(Main Output Enable)
 TIM1->CCER = 0x01; // CC1E=1(Capture/Compare 1 Output Enable)
 while (1)
 {
 // 如果只有CC1E为1, 那么输出端只能输出低电平
 TIM1->CCMR1 = 0x40; // OC1M=100(forced inactive level)
 TIM1->CCER |= _BV(1); // CC1P=1(active为低电平, 输出为高电平, LED灭)
 delay();
 TIM1->CCER &= ~_BV(1); // CC1P=0(active为高电平, 输出为低电平, LED亮)
 delay();
 
 // 只有MOE和CC1E同时为1时, 下面才能产生正确的输出
 // 否则两个都只能输出低电平
 TIM1->CCMR1 = 0x50; // OC1M=101(forced active level)
 TIM1->CCER &= ~_BV(1); // CC1P=0(active为高电平, 输出为高电平, LED灭)
 delay();
 TIM1->CCER |= _BV(1); // CC1P=1(active为低电平, 输出为低电平, LED亮)
 delay();
 }
 }
 
 | 
                
          |   一派護法 十九級 | 
              STM32的官方手册上没有讲清楚,此模式下MOE和CC1E必须同时为1,否则上述的四种状态就不能正常工作。如果MOE=CC1E=0,那么该通道就会被强制限制在Inactive level,TIM1->CCMR1 = 0x40(把通道设为Inactive)有效,但TIM1->CCMR1 = 0x50(把通道设为Active)无效。
 如果只有CC1E为1,那么无论怎么设置,输出端都是输出低电平,LED灯一直亮着。
 
 | 
                
          |   一派護法 十九級 | 
              【程序运行结果】把PA8用杜邦线接到有LED灯的端口上,LED灯闪烁,且亮的时间和熄灭的时间完全相等,最开始LED灯是熄灭状态。
 若MOE=CC1E=0,则LED亮着的时间是熄灭的时间的三倍,且刚开始时LED是熄灭的。(因为OC1M=101模式不能正常工作,一直输出低电平)
 若只有CC1E=1,则LED灯一直亮着。
 | 
                
          |   一派護法 十九級 | 
              int main(void){
 RCC->APB2ENR = _BV(2) | _BV(11);
 GPIOA->CRH = 0x0000000b;
 
 // MOE=0, CC1E=0的情况下
 while (1)
 {
 TIM1->CCMR1 = 0x40; // force inactive => clock is not present => 输出端OC1取决于CC1P
 TIM1->CCER |= _BV(1); // active=>low, 输出高电平, LED灭
 delay();
 TIM1->CCER &= ~_BV(1); // active=>high, 输出低电平, LED亮
 delay();
 
 TIM1->CCMR1 = 0x50; // force active => clock becomes present => 输出端OC1取决于OIS1
 TIM1->CR2 |= _BV(8); // OIS1=1, 输出高电平, LED灭
 delay();
 TIM1->CR2 &= ~_BV(8); // OIS1=0, 输出低电平, LED亮
 delay();
 }
 }
 | 
                
          |   一派護法 十九級 | 
              int main(void){
 RCC->APB2ENR = _BV(2) | _BV(11);
 GPIOA->CRH = 0x0000000b;
 
 // MOE=0, CC1E=1的情况下
 TIM1->CCER = 0x01;
 while (1)
 {
 TIM1->CCMR1 = 0x40; // force inactive, CC1E=1 => clock is present => 输出端OC1取决于OIS1
 TIM1->CR2 |= _BV(8); // OIS1=1, 输出高电平, LED灭
 delay();
 TIM1->CR2 &= ~_BV(8); // OIS1=0, 输出低电平, LED亮
 delay();
 
 TIM1->CCMR1 = 0x50; // force active => clock is present => 输出端OC1取决于OIS1
 TIM1->CR2 |= _BV(8); // OIS1=1, 输出高电平, LED灭
 delay();
 TIM1->CR2 &= ~_BV(8); // OIS1=0, 输出低电平, LED亮
 delay();
 }
 }
 | 
                
          |   一派護法 十九級 | 
              int main(void){
 RCC->APB2ENR = _BV(2) | _BV(11);
 GPIOA->CRH = 0x0000000b;
 
 // MOE=1, CC1E=0的情况下
 TIM1->BDTR = 0x8000;
 while (1)
 {
 // 若OSSR=0, 则输出低电平, LED亮
 TIM1->BDTR &= ~_BV(11);
 delay();
 
 // 若OSSR=1, 则输出端取决于CC1P
 TIM1->BDTR |= _BV(11);
 TIM1->CCER |= _BV(1); // active=>low, 输出高电平, LED灭
 delay();
 TIM1->CCER &= ~_BV(1); // active=>high, 输出低电平, LED亮
 delay();
 }
 }
 | 
                
          |   一派護法 十九級 | 
              int main(void){
 RCC->APB2ENR = _BV(2) | _BV(11);
 GPIOA->CRH = 0x0000000b;
 
 // MOE=0, OSSI=1, CC1E=1时, 输出端OC1取决于OIS1
 TIM1->BDTR = _BV(10);
 TIM1->CCER = _BV(0);
 while (1)
 {
 TIM1->CR2 |= _BV(8); // OIS1=1, 输出高电平, LED灭
 delay();
 TIM1->CR2 &= ~_BV(8); // OIS1=0, 输出低电平, LED亮
 delay();
 }
 }
 | 
                
          |   一派護法 十九級 | 
              int main(void){
 RCC->APB2ENR = _BV(2) | _BV(11);
 GPIOA->CRH = 0x0000000b;
 
 // MOE=0, OSSI=1, CC1E=0时, 输出端OC1取决于CC1P
 TIM1->BDTR = _BV(10);
 while (1)
 {
 TIM1->CCER |= _BV(1); // active=>low, 输出高电平, LED灭
 delay();
 TIM1->CCER &= ~_BV(1); // active=>high, 输出低电平, LED亮
 delay();
 }
 }
 | 
                
          |   一派護法 十九級 | 
              4楼的代码是当MOE=0, OSSI=0, CC1E=0时输出端的情况。5楼的代码则是当MOE=0, OSSI=0, CC1E=1时输出端的情况。
 
 | 
                
          |   一派護法 十九級 |  |