定时器的3种功能
1、捕获器:测量波形的频率和宽度
2、比较器:分为模拟比较器和输出比较器
模拟比较器:比较两组输入电压的大小(STM32F103无此功能)
输出比较器:产生可调频率和可调占空比的脉冲波形
3、PWM:脉宽调制器,产生固定频率但占空比可调的脉冲波形
其中PWM功能前面已经介绍,下面介绍其他功能
普通定时
定时器可以用于独立时间计时功能,原理和嘀嗒定时器、看门狗基本相同。
定时时间到时,可等待CPU检查标志位(查寻方式),或产生“定时器中断”
一般都是让定时器产生中断。
定时原理图如下(设置为向上加计数)
通过定义定时器的4个独立通道设置为输入或者输出即可完成下面介绍的功能。
捕获器
捕获什么?输入接口的电平变化 (. 上升沿或下降沿)
有什么用?可 测量脉冲的宽度,或者测量脉冲频率
工作过程! 当接口产生.上升沿或下降沿时,将当前定时器值保存。
主要捕获数字信号的方波。捕获方波对应的上升沿或者下降沿。
捕获高(低)电平宽度时序图
记录第一次捕获上升沿时间为T1(计数值C1),记录第二次捕获下降沿时间为T2(计数值C2),再相减计算,便得到高电平的时间宽度。
同理
记录第一次捕获下降沿时间为T1(计数值C1),记录第二次捕获上升沿时间为T2(计数值C2),再相减计算,便得到低电平的时间宽度。
测频原理图如下:
记录第一次捕获上升沿(下降沿)时间为T1(计数值C1),记录第二次捕获上升沿(下降沿)时间为T2(计数值C2),再相减计算,便得到一个周期的宽度,即可以完成测频。
输出比较器
可输出脉冲,可调占空比和频率。
PWM只能调占空比(也是可以通过程序调频率,但不方便随时调)输出比较器可随时调占空比和频率。
输出比较器主要用于步进电机、伺服电机的控制。
下面举一个例子:
定时中断功能的使用:
和前面产出PWM波相类似,比之前简单,时钟频率默认72MHZ。
定时器时间计算公式Tout = ((重装载值+1)*(预分频系数+1))/时钟频率;
例如:1秒定时,重装载值=9999,预分频系数=7199
调用该函数即可:
TIM3_Init(9999,7199);//定时器初始化,定时1秒(9999,7199)
具体的初始化函数如下:
void TIM3_Init(u16 arr,u16 psc){ //TIM3 初始化 arr重装载值 psc预分频系数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3
TIM3_NVIC_Init (); //开启TIM3中断向量
TIM_TimeBaseInitStrue.TIM_Period=arr; //设置自动重装载值
TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数器向上溢出
TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); //TIM3初始化设置
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能TIM3中断
TIM_Cmd(TIM3,ENABLE); //使能TIM3
}
将定时器3的中断向量写入中断控制向量器的函数(因为中断向量控制器直接和单片机相连,控制着单片机的中断)如下:
void TIM3_NVIC_Init (void){ //开启TIM3中断向量
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3; //设置抢占和子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
中断处理函数如下(
注意函数名称不可以修改,是固定的
):
void TIM3_IRQHandler(void){ //TIM3中断处理函数
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){ //判断是否是TIM3中断
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//此处写入用户自己的处理程序
GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
}
}
刚进入中断时,需要判断中断标志位是否表示定时器的溢出,若确实为溢出,则清空标志位(为下次定时做准备),这时再if语句成立的条件下(即确定是定时器溢出产生中断),写入自己的处理程序。
所谓定时器中断在我看来,CPU和定时器独立工作,定时器计时,cpu做自己的事情,当定时器计满溢出之后,定时器被清零,产生中断信号给CPU,CPU立即放下手头的事情,然后处理中断函数中的内容,中断函数不能在主函数或者其他函数中调用,而是独立的,让CPU进入中断函数处理完成之后,再返回原来做原来的事情,当定时器再次溢出时,再产生中断,如此反复下去…
图中部分图片出自洋桃电子,仅用于学习目的。