快速学会使用STM32F103的定时器
欢迎
我是一名在读的大学生,近期在准备全国大学生电子设计竞赛的电源题,对于电源题的话,硬件部分的设计和软件配合是不可或缺的,对于电源题,对软件的需求没有像控制类的那么高,但是不论如何。不管我们打什么题目我们都要学习定时器、中断等等外设。纵观自己学习stm32的这一路来,我总结了一些快速上手定时器的方案和使用技巧。让我们更加高效率的使用定时器。
定时器的作用
定时器的功能有非常多,我所讲的是针对以下这几种情况:
- 定时器采样ad数据 ,这是电赛达到对交流电压采集必须要做到的;
- 定时器中断采集频率 通过定时器,中断采集频率,可以达到较高的精度;
- 定时器开关LED、BEEP等开关器件
使用教程:
首先我们要先了解一下这个公式: Tout就是我们定时器定时的时间了,TIMx_ARR和TIMx_PSC+1我们会在导入定时器模板时用到,对其进行更改就好。 接下来就是确定我们使用的定时器时钟多少,我们的定时器要有一个对时间的基准就是靠的时钟,如图TIM1是APB2,TIM2-TIM7是使用APB1
假设我们的定时器时钟是72Mhz,这个值是固定的。也就是图片中的Tclk。 那我们把TIMx_ARR和TIMx_PSC+1分别设置为71和999的话,切记不要超过65535因为最大只能容纳2的16次方。 这样子通过公式计算就是(71+1)(999+1)/72Mhz == 721000/72000000 == 1/1000 也就是1ms。 所以我们根据需求来对arr和psc进行设置。那有了这些基础我们进行代码移植。找到可以使用的timer头文件和c文件。 把他们放在同一文件夹下。 然后找到你要使用使用的工程,放进自己要使用的工程中。 timer4就是我们要用到的定时器,然后我们打开工程 点击USER然后右键点击add existing file to group,找到刚刚的timer.c文件然后点击"魔法棒" 然后把我们的定时器文件夹加进去即可 然后就一直按oK就好啦,我们就添加好了定时器。 然后我们要进行修改的就是TIM的IEQHandler函数,这个是定时器的处理函数,我们把我们要定时做的内容写入if循环中即可。比如我这边对led0,进行反转,也就是进行闪烁(记得我们的定时时间可以设的长一点,不然看不出来led在闪烁) 这样就完成了,然后我们要把timer4.h添加到main.c中,并且把timer4的初始化也加到我们的main函数中。编译会发现有这些问题;
也有人可能没有问题,有这个问题的话,我们就一样要加入.c文件,我们要加入的是stm32f10x_tim.c文件,在自己的工程中找到它,加入即可,缺啥加啥,我们看文件名称就大概知道了,tim就是定时器。 该文件一般都在STM32F10x_FWLib中SRC文件目录下。添加完毕,我们在进行编译就可以通过了。 最后我们导入程序,观察发现灯是常亮的那我们就更改arr和psc的值:
我们现在是1ms执行一次,721000/72000000,我们更改为719和1999也就是7202000/72000000也就是20ms执行一次。 我们就调到我们可以用肉眼看见的程度既可以,然后编译的时候要记得勾选文件编译自动重装,不然直接点编译的话,烧写进去的代码还是之前的代码。 这样子我们的实验就结束了。接下来贴上timer4.c和timer4.h的源代码
timer4.c
#include "timer4.h"
#include "led.h"
#include "delay.h"
void Timer4_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
TIM_TimeBaseStructure.TIM_Period = 9999-1;
TIM_TimeBaseStructure.TIM_Prescaler = 719-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_DeInit(TIM4);
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4,ENABLE);
}
void TIM4_IRQHandler()
{
u8 st;
st = TIM_GetFlagStatus(TIM4,TIM_IT_Update);
if(st!=0)
{
TIM_ClearFlag(TIM4,TIM_IT_Update);
LED1 = !LED1;
}
}
timer4.h
```c
#ifndef _timer4_
#define _timer4_
#include "sys.h"
void Timer4_init(void) ;
#endif
```c
#include "led.h"
#include "delay.h"
#include "timer4.h"
int main(void)
{
delay_init();
LED_Init();
Timer4_init( );
while(1)
{
LED0=!LED0;
delay_ms(500);
}
}
##main.c
#include "led.h"
#include "delay.h"
#include "timer4.h"
int main(void)
{
delay_init();
LED_Init();
Timer4_init( );
while(1)
{
LED0=!LED0;
delay_ms(500);
}
}
THE END
个人总结:对于STM32定时器的话,我认为这是一个很高效实用的用法。 如果有写的不好的地方,尽情见谅
|