設置 | 登錄 | 註冊

目前共有10篇帖子。

【程序】STM32定時器1的強置輸出模式(Forced output mode)

1樓 巨大八爪鱼 2017-1-9 11:42
#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();
    }
}
2樓 巨大八爪鱼 2017-1-9 11:46
STM32的官方手冊上沒有講清楚,此模式下MOE和CC1E必須同時為1,否則上述的四種狀態就不能正常工作。
如果MOE=CC1E=0,那麼該通道就會被強制限制在Inactive level,TIM1->CCMR1 = 0x40(把通道設為Inactive)有效,但TIM1->CCMR1 = 0x50(把通道設為Active)無效。
如果只有CC1E為1,那麼無論怎麼設置,輸出端都是輸出低電平,LED燈一直亮着。
3樓 巨大八爪鱼 2017-1-9 11:50
【程序運行結果】
把PA8用杜邦線接到有LED燈的端口上,LED燈閃爍,且亮的時間和熄滅的時間完全相等,最開始LED燈是熄滅狀態。
若MOE=CC1E=0,則LED亮着的時間是熄滅的時間的三倍,且剛開始時LED是熄滅的。(因為OC1M=101模式不能正常工作,一直輸出低電平)
若只有CC1E=1,則LED燈一直亮着。
4樓 巨大八爪鱼 2017-1-10 15:31
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();
    }
}
5樓 巨大八爪鱼 2017-1-10 15:36
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();
    }
}
6樓 巨大八爪鱼 2017-1-10 16:10
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();
    }
}
7樓 巨大八爪鱼 2017-1-10 16:15
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();
    }
}
8樓 巨大八爪鱼 2017-1-10 16:19
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();
    }
}
9樓 巨大八爪鱼 2017-1-10 16:21
4樓的代碼是當MOE=0, OSSI=0, CC1E=0時輸出端的情況。
5樓的代碼則是當MOE=0, OSSI=0, CC1E=1時輸出端的情況。
10樓 巨大八爪鱼 2017-1-10 16:27
【參考資料】
淺談STM32高級定時器TIM1的OSSR和OSSI、OISX,OISXN的作用和區別
http://blog.csdn.net/u014170207/article/details/50885511

內容轉換:

回覆帖子
內容:
用戶名: 您目前是匿名發表。
驗證碼:
看不清?換一張
©2010-2025 Purasbar Ver3.0 [手機版] [桌面版]
除非另有聲明,本站採用知識共享署名-相同方式共享 3.0 Unported許可協議進行許可。