作者共發了4篇帖子。 內容轉換:不轉換▼
 
點擊 回復
635 3
【验证性实验】TIM1定时器死区时间(dead-time)的加入及检测
一派護法 十九級
1樓 發表于:2017-1-10 17:53
【程序】
#include <stm32f10x.h>

#define _BV(n) (1 << (n))

uint8_t i = 0;
uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};

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);
        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)
{
    // OC1输出端PA8用杜邦线接PA15, OC1N互补输出端PB13接PC13
    // 同时PC13上有一个低电平点亮的LED指示灯
    RCC->APB2ENR = _BV(2) | _BV(3) | _BV(4) | _BV(11); // 开启PA、PB、PC和TIM1时钟, 不需要开启AFIO的时钟
    GPIOA->CRH = 0x8000000b; // PA15设为带下拉的输入, PA8设为复用50MHz推挽输出
    GPIOA->CRL = 0x00000003; // PA0设为50MHz推挽输出
    GPIOB->CRH = 0x00b00000; // PB13设为复用50MHz推挽输出
    GPIOC->CRH = 0x33800000; // PC13设为带下拉的输入, PC14~15设为50MHz推挽输出

    TIM1->ARR = 5099; // 计数值
    TIM1->PSC = 65535; // 定时器分频
   
    TIM1->CCR1 = 2000;
    TIM1->CCMR1 = 0x70; // OC1M=111, PWM模式2, 输出比较匹配时OC1REF信号产生上升沿
    TIM1->BDTR = 0x80ff; // MOE=1, 并添加死区时间, 大约为几us, 输出端OC1的dead-time延迟产生在OC1REF信号的上升沿
    // TIM1->BDTR = 0x8000; // 不加死区时间的情况
    TIM1->CCER = 0x05; // CC1NE=1, CC1E=1
   
    // 刷新寄存器
    TIM1->CR1 = 0x204; // CKD=10, URS=1
    TIM1->EGR = 0x01; // UG=1
   
    // 开始计数
    TIM1->CR1 |= _BV(0); // CEN=1
   
    SerIn(seg8[0]);
    SerIn(_BV(0));
    ParOut();
           
    while (1)
    {
        // 如果检测到OC1、OC1N同时输出低电平, 则表明有dead-time延迟
        if ((GPIOA->IDR & _BV(15)) == 0 && (GPIOC->IDR & _BV(13)) == 0)
        {
            i++;
            if (i > 9)
                i = 0;
            SerIn(seg8[i]);
            SerIn(_BV(0));
            ParOut();
            while ((GPIOA->IDR & _BV(15)) == 0 && (GPIOC->IDR & _BV(13)) == 0);
        }
    }
}
一派護法 十九級
2樓 發表于:2017-1-10 17:58
【运行结果】
刚开始时LED灯是灭的,数码管显示0
之后每当LED由灭变亮(输出比较匹配),以及LED由亮变灭(定时器归0并重新开始计时),数码管的数字都会加1

如果把程序改成不加死区时间,即TIM1->BDTR = 0x8000,那么理论上数码管就会一直显示0。不过程序实际运行时最开始的那段时间有一次数码管会在LED灯状态翻转的时候从0跳到1,但是之后一直保持1,这只能算实验误差。
一派護法 十九級
3樓 發表于:2017-1-10 18:13

如图,加了死区时间后,OC1会在上升沿那里出现延迟,而OC1N会在下降沿那里出现延迟。所以一个计数周期内会出现两次OC1=OC1N=0,使数码管的值加1。

一派護法 十九級
4樓 發表于:2017-1-10 18:14
如果没有加入死区时间,那么理论上OC1的波形就会和OC1REF完全相同,OC1N和OC1完全相反,不会出现OC1=OC1N=0的情况,因此数码管的值一直不变。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:635 回複數:3
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2017-1-10 18:14
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用共享創意姓名標示-相同方式分享 3.0 Unported許可協議進行許可。