-1

我在 STM8S103F3 上创建了一个程序,使用 TIM2 模块生成微秒的延迟,但计时器没有按预期滴答作响,当我尝试使用它调用 5 秒延迟时,它给出了大约 3 秒的延迟。我使用的是 16MHz HSI 振荡器,定时器预标量设置为 16。请参阅下面的代码。请帮我弄清楚我的代码有什么问题。

void clock_setup(void)
{
       CLK_DeInit();
       CLK_HSECmd(DISABLE);
       CLK_LSICmd(DISABLE);
       CLK_HSICmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
       CLK_ClockSwitchCmd(ENABLE);
       CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
       CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
                            DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
}

void delay_us(uint16_t us)
{
    volatile uint16_t temp;
    TIM2_DeInit(); 
    TIM2_TimeBaseInit(TIM2_PRESCALER_16, 2000); //Prescalar value 8,Timer clock 2MHz
    TIM2_Cmd(ENABLE);  
    do{
        temp = TIM2_GetCounter();
    }while(temp < us);
    TIM2_ClearFlag(TIM2_FLAG_UPDATE);
    TIM2_Cmd(DISABLE); 
} 

void delay_ms(uint16_t ms)
{
    while(ms--)
    {
        //delay_us(1000);
        delay_us(1000);
    }
}
4

1 回答 1

1

最好使用 10us 时基来舍入延迟。那么为了实现 10us 时基,如果您使用 16MHz 主时钟并将 TIM2 预分频 16,那么您将获得 1us 增量时间,对吗?但是我们希望 TIM2 溢出来生成一个名为 16us 事件的事件。因为我们知道定时器每 1us 递增一次,如果我们使用重载值 65536 - 10 = 65526,这将给我们 10us 溢出,因此,10us 时基。如果在延迟代码之前我们都可以,我们只需检查 TIM2 更新标志以了解它是否溢出。请参阅下面的示例代码片段。

// Set up it once since our time base is a fixed 10us
void setupTIM2(){
    TIM2_DeInit(); 
    TIM2_TimeBaseInit(TIM2_PRESCALER_16, 65526); //Prescalar value 16,Timer clock 1MHz
}

void delay_us(uint16_t us)
{
    volatile uint16_t temp;
    
    TIM2_Cmd(ENABLE);
    const uint16_t count = us / 10; //Get the required counts for 10us time base
    // Loop until the temp reaches the required count value
    do{
        while(TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == RESET); //Wait for the TIM2 to overflow
        TIM2_ClearFlag(TIM2_FLAG_UPDATE); // Clear the overflow flag
        temp++;
    } while(temp < count);
    
    TIM2_Cmd(DISABLE); 
} 

void delay_ms(uint16_t ms)
{
    while(ms--)
    {
        //delay_us(1000);
        delay_us(1000);
    }
}

void main(void){
    ...
    setupTIM2();
    ...
    delay_ms(5000);
}
于 2020-12-25T20:22:26.593 回答