 |
#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时输出端的情况。
|
 |
10樓
巨大八爪鱼
2017-1-10 16:27
|