zoukankan      html  css  js  c++  java
  • 《SLAM机器人基础教程》第三章 单片机与STM32:定时器实验

    3.7节 定时器实验

    在上一节我们使用SysTick实现了延时,本节介绍使用定时器实现延时。

    a.实验准备:USB转串口模块,ST-Llink下载器,CHEAPX机器人控制板

    b.实验目的:使用定时器延时检验上一节SysTick延时函数的准确度

    c.相关知识点:

    STM32定时器和串口一样,具有中断函数。但我们打开定时器时,定时器就会按我们设置好的频率开始计数直到溢出,溢出会产生溢出中断。同样的,我们可以通过计数的数值转化为时间。STM32F1系列芯片的定时器的分辨率可以达到1/72us。

    d.编程及运行

    (1)初始化定时器TIM4,编写中断函数

    void initTimeStamp(void)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//开启TIM4时钟
        
        //TIM4
        TIM_TimeBaseStruct.TIM_ClockDivision = 0;  //时钟分割,不分割,即为该定制器时钟最大值72M
        TIM_TimeBaseStruct.TIM_Prescaler = 0;         //预分频值,不分频,即为该定制器时钟值72M
        TIM_TimeBaseStruct.TIM_Period = 65000-1;     //最大计数值,也是计数周期=1/72M*65000s=65000/72us
        TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);//传入结构TIM_TimeBaseStruct,配置TIM4
        TIM_ClearFlag(TIM4, TIM_FLAG_Update);       //清除更新中断
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE );   //开启更新中断,计数器到达最大值65000-1,从该值转变至0时,会产生一次更新中断
        
        NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;           //通道值:定时器4
      NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0,最高
      NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;        //子优先级 1,次高
      NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;           //使能
      NVIC_Init(&NVIC_InitStruct);                           //传入结构体NVIC_InitStruct,配置NVIC
    
        TIM_ARRPreloadConfig(TIM4, ENABLE);//开启自动装载
        TIM_Cmd(TIM4, ENABLE);
    }
    void TIM4_IRQHandler(void) 
    {
      if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //判断是否为更新中断
        {
            timerTSCount++;
          TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //清除更新中断标志 
        }
    }

    (2)编写SysTick测试函数。我们只需要记录SysTick实现的延时函数前后的TIM4计数值即可。

    void testTimestamp(void)
    {
        u32 T=0;
        u32 lastT=0;
        u32 deltaT=0;
        printf("Timestamp Test
    ");
        while(1)
        {
            lastT=getTimestampUS();
            T=getTimestampUS();
            deltaT=T-lastT;
            
            lastT=getTimestampUS();
        delay_us(1);
            T=getTimestampUS();
            printf("cmd=1us,Real:%6fus;",((T-lastT-deltaT)/72.0f));
            
            lastT=getTimestampUS();
        delay_ms(1);
            T=getTimestampUS();
            printf("cmd=1000us,Real:%6fus
    ",((T-lastT-deltaT)/72.0f));
            
            delay_ms(1000);
    
        }
    }
    volatile static u32   timerTS=0;       //TimeStamp(unit:1/72us)
    volatile static u32   timerTSH=0;      //TimeStamp(unit:65000/72us)    
    volatile static u8    timerTSCount=0;  //TimeStamp(unit:65000/72us)
    /*** unit:1/72us ***/
    u32 getTimestampUS(void)
    {
        timerTSH+=timerTSCount;
        timerTS=timerTSH*65000+TIM4->CNT;
        timerTSCount=0;
        return timerTS;
    }

    (3)主函数

    //定时器实验
    int main(void)
    {        
        
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中断分组设置 组2(2位抢占优先级,2位响应优先级)
        initDebugSerial(500000);//初始化调试串口USART1,波特率500000
        initSysTick();//初始化滴答定时器和TIM4定时器
        showVersion();//显示版本
        
        while(1)
        {
            ;
        }
        
    }

    (4)实验结果:

    e.实验总结:TIM定时器除了定时外还可以用于输出PWM等,是STM32芯片中很重要的外设资源。因此,我们常用SysTick系统滴答定时器实现延时。

  • 相关阅读:
    TODO supply a title
    three.js ---- 3d页面开发入门
    ProgressBar.Style ---- Marquee
    C#中的Task.Delay()延迟与异步执行返回结果
    位运算-实现加减乘除
    2020年专项附加扣除信息,个税纳税记录查询
    C#动态执行JS和VBS脚本
    windows下bat批处理实现守护进程(有日志)
    C#创建快捷方式的两种方法
    C#中创建程序的快捷方式
  • 原文地址:https://www.cnblogs.com/Baron-Lu/p/13378565.html
Copyright © 2011-2022 走看看