 |
#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
|