• 【菜鸟必看】stm32定时器的妙用


    摘要:本文为你带来关于stm32定时器的使用的便利和优势之处。

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

    一、初步了解定时器

    stm32定时器时钟图如下:

    定时器2-7:普通定时器
    定时器1、8:高级定时器

    二、使用定时器

    以下,我使用定时器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);
        }
    }

    效果如下

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    jar包制作
    eclipse 编译出错(java.io.ObjectInputStream)的解决办法
    Onmouseover被调用多次
    【驱动】——模块参数
    【驱动】——驱动入门用例
    【linux】——FTP出现500 OOPS: cannot change directory的解决方法
    【驱动】——错误: 初始值设定项里有未知的字段‘ioctl’
    【C】——动态库中函数的作用范围
    【C】——如何生成静态库和动态库
    【C】——C语言字符串比较函数
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/13099161.html
Copyright © 2020-2023  润新知