OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4011|回复: 0

STM32F4使用定时器进行精准延时

[复制链接]

2

主题

2

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-3-22
在线时间
4 小时
发表于 2018-3-22 17:28:36 | 显示全部楼层 |阅读模式
使用定时器进行精准延时从时钟树中我们可以得知 :(1)高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11的时钟来源是APB2总线
(2)通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7的时钟来源是APB1总线
从STM32F4的内部时钟树可知:当APB1和APB2分频数为1的时候,TIM1、TIM8~TIM11的时钟为APB2的时钟,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟;
而如果APB1和APB2分频数不为1,那么TIM1、TIM8~TIM11的时钟为APB2的时钟的两倍,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍。
因为系统初始化SystemInit函数里初始化APB1总线时钟为4分频即42M,APB2总线时钟为2分频即84M,
所以TIM1、TIM8~TIM11的时钟为APB2时钟的两倍即168M,
TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍即84M。
知道定时器的时钟源频率我们用定时器做延时就很方便了,只要设定合适的分频系数即可,附一下用中断实现延时的公式:(摘自原子的STM32F4开发指南)
Tout = ((arr+1)*(psc+1))/Tclk;公式中psc就是分频系数,arr就是计数值,达到这个计数就会发生溢出中断,Tclk就是我上述分析的时钟源频率的倒数。
主函数,定时器的配置

void TIM2_Init(void )
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
​
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
​
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);                                                      
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;      
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
​
    TIM_TimeBaseStructure.TIM_Period = 9999;        //  计数值 arr
    TIM_TimeBaseStructure.TIM_Prescaler = 839;     //分频系数 psc
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
​
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM2, ENABLE);
​
}








中断函数

void TIM2_IRQHandler(void)
{
     //加入一些要在中断里做的事
    TIM_ClearFlag(TIM2,TIM_FLAG_Update);              
}








这里还有一个使用定时器精准延时1us的函数

void BSP_Delay_Init(void )
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
  TIM_TimeBaseStructure.TIM_Period = 1;                 
  TIM_TimeBaseStructure.TIM_Prescaler = 41;      
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;   
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;  
  TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
}
​
void BSP_Delay1us(uint32_t  delayTime)
{
    uint16_t TIMCounter = delayTime*2;
    TIM_Cmd(TIM5, ENABLE);
    TIM_SetCounter(TIM5, TIMCounter);
    while (TIMCounter >= 1)
    {
        TIMCounter = TIM_GetCounter(TIM5);
    }
    TIM_Cmd(TIM5, DISABLE);
​
}









正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 02:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表