声明在前:本系列以程序设计为主,适用于刚学会32,想完成一个基本项目却不知道怎么上手的小伙伴。想学习硬件方面如:电路、画板等内容的朋友请不要在本系列耽误您的时间,关闭即可。
在上一期32循迹第一天.的内容里,主要讲述了与GPIO有关的理论知识和具体在各种模块上的应用以及程序写法。
那么,从理论上来讲,就只剩下定时器的内容没有讲了,(当然,在应用层面是另一回事)。今天就把定时器讲完,这样下一期就可以毫无顾虑地讲方案了/doge,接下来,直入正文:
想看程序的从“实际应用"开始
定时器
理论知识
- 按照上一期的习惯,在明确用法之前,我们首先来了解一下定时器的知识:
学51的时候我们知道,51有两个定时器,并且这两个定时器都是中断源。在使用51的定时器之前,我们都要初始化定时器——配置各寄存器的参数。在32中,也是同理:
初始化
第一个要初始化的定时器以 TIM4 为例,我们首先在Basic文件夹里新建tim4文件夹,再新建TIM4.c和TIM4.h文件
接下来我们打开 TIM4.c
定时器初始化:arr、psc
在初始化之前,32定时器有两点要注意:
- 设置好定时器之后要明确定时器中断的优先级:用NVIC来配置
- 每个定时器都有一定数量的通道,用于输出pwm、输入捕获等等(TIM1/8是高级定时器,TIM2345是通用定时器,TIM67是基本定时器,具体有什么区别,就等以后有机会再讲了)
先看程序:(以有四个通道的通用定时器TIM4为例)
void TIM4_Init(u16 arr,u16 psc){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
}
这里面只有一个要注意的点:就是这个初始化函数输入的参数:arr 和 psc
如果不想了解这两个参数有什么用的话,记住下面这个公式:
接下来我们来明确一下arr和psc的含义:
- arr:自动重装值
自动重装值的意思很好理解:如图
如果不设置arr的话,在每个周期都会走向100%,而这和持续的“1”没有区别。在加了arr以后我们才能够控制这个输出的具体值。
arr并非不可修改,即使在初始化配置完了以后,仍然可以通过TIMx -> ARR =____控制寄存器来直击修改它的值(这一点稍后在讲舵机的时候会用到)
- psc:预分频值
我们知道,stm32f103的时钟频率是 ,72MHz 而预分频的作用就是把这个 72M 再分一下:假如我让 psc + 1 = 72,那么分频完以后的时钟频率就是 1M。而在上述的公式中,常用来计算频率的除数(1/时间),用72可以理解为便于计算,
明确了arr和psc以后,我们再来看看其它几句的程序
——————接下来回到程序:
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE );
对一般的小程序,见RCC便知:时钟初始化。
- TIM_TimeBaseStructure.TIM_ClockDivision = 0 ;
别看这句话很多定时器初始化程序都带,还都等于0,但是实际上,这玩意跟pwm没关系:)它跟输入捕获有关。
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up
这是向上计数模式,即从0开始一直到 ARR 然后再自动重装。一般情况下用这个就好,我们Go to一下这个TIM_CounterMode_Up,可以看见除了它还有有其他指令,以及他们各自的含义就不多说了,我相信买板子的附赠教程里会说的:)
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
这是库里自带的初始化程序,类似之前GPIO那个库自带初始化。
NVIC
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
- TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE );
同样是自带函数,使能中断,允许中断更新
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn ;
指定定时器4的中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVI