zoukankan      html  css  js  c++  java
  • 【华为云技术分享】stm32定时器的妙用

    使用定时器去计算获取一条指令的时间

    一、初步了解定时器

    stm32定时器时钟图如下:
    image.png
    定时器2-7:普通定时器
    定时器1、8:高级定时器
    image.png
    image.png

    二、使用定时器

    以下,我使用定时器7(以下TIM7)去实现计算获取一条指令的运行时间。

    1.TIM7初始化

    以下初始化函数中

    • 入口参数:TIMx:TIM7,arr:重载值,psc分频值
    • 函数功能:TIM7的定时配置
    • 返回参数:无
    • 说明:和timer7只具有更新中断功能

      void Timer7_Init(TIM_TypeDef * TIMx, unsigned short arr, unsigned short psc)
      {
        TIM_TimeBaseInitTypeDef timer_initstruct;
        NVIC_InitTypeDef nvic_initstruct;
      
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
      
        nvic_initstruct.NVIC_IRQChannel = TIM7_IRQn;
      
        timer_initstruct.TIM_CounterMode = TIM_CounterMode_Up;
        timer_initstruct.TIM_Period = arr;
        timer_initstruct.TIM_Prescaler = psc;
      
        TIM_TimeBaseInit(TIMx, &timer_initstruct);
      
        TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);                    //使能更新中断
      
        nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
        nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 1;
        nvic_initstruct.NVIC_IRQChannelSubPriority = 1;
        NVIC_Init(&nvic_initstruct);
        TIM_Cmd(TIMx, ENABLE); //使能定时器
      }
      

    2.中断服务函数

    产生更新中断时进入

    void TIM7_IRQHandler(void)
    {
        if(TIM_GetITStatus(TIM7, TIM_IT_Update) == SET)
        {
            TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
    
            timer_info.timer7Out++;
        }
    }
    

    其中timer_info为结构体,存放更新次数变量(也可以用静态变量)

    typedef struct
    {
        unsigned char timer7Out;
    } TIM_INFO;
    extern TIM_INFO timer_info;
    TIM_INFO timer_info = {0};
    

    3.使用例程

    • 调用初始化函数 Timer6_7_Init(TIM7, 49999, 71);//1us计数一次,50ms中断一次
    • 关闭定时器,清零计数 TIM_Cmd(TIM7, DISABLE); TIM_SetCounter(TIM7, 0);
    • 在指令之前打开定时器,指令完成之后关闭定时器
    • 计算时间,通过中断次数、计数器剩余值判断。
    • 清零

    以下代码为计算usart1发送"hello word!"的时间

    #include "stm32f10x.h"
    
    #include "delay.h"
    #include "usart.h"
    #include "timer.h"
    
    void Hardware_Init(void)
    {
    
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断控制器分组设置
    
        Delay_Init();            //Systick初始化,用于普通的延时
        Usart1_Init(9600);        //初始化串口1,波特率9600
        Timer6_7_Init(TIM7, 49999, 71);    //1us计数一次,50ms中断一次
        TIM_Cmd(TIM7, DISABLE);        //关闭定时器
        TIM_SetCounter(TIM7, 0);        //清零计数器
    }
    
    
    int main(void)
    {
        unsigned int time = 0;
        Hardware_Init();                                    //硬件初始化
    
        while(1)
        {
            TIM_Cmd(TIM7, ENABLE);                            //使能定时器计时
            UsartPrintf(USART1, "
    hello word!!n
    ");
            TIM_Cmd(TIM7, DISABLE);                            //关闭定时器
    
            time = timer_info.timer7Out * 50000;            //测算时间-中断次数*中断周期
            time += TIM_GetCounter(TIM7);                    //获取当前中断前的剩余值
            TIM_SetCounter(TIM7, 0);                        //清零
            timer_info.timer7Out = 0;
            UsartPrintf(USART1, "发送时间: %d微秒
    ", time);
            DelayMs(2500);
        }
    }
    

    效果如下

    image.png

     点击这里,了解更多精彩内容

  • 相关阅读:
    【Oracle-DBA】Oracle连接非常慢APPARENT DEADLOCK
    【PC-x86-x64】JDK 32bit与64bit的区别及x64 PC的发展历程【转】
    css框架,一把锋利的剑
    OnContextMenu事件(转)
    960网格,一个web时代的标志。
    程序员取名:用大数据分析一下宝宝取名时最容易重复的名字
    创建你的第一个JavaScript库
    5个经典的前端面试问题,你行吗?
    一个由SEO优化展开的meta标签大讲解
    HTML5页面开发的基础性模板
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13164674.html
Copyright © 2011-2022 走看看